La **Local File Inclusion (LFI)** est une vulnérabilité critique qui survient lorsqu'une application web permet à un utilisateur de manipuler le chemin d'un fichier qui sera inclus et exécuté par le serveur.
En PHP, des fonctions comme include(), require(), include_once() ou file_get_contents() sont souvent utilisées pour construire des pages dynamiques.
Si l'attaquant envoie ?page=admin, le serveur inclut admin.php. C'est le comportement attendu.
Mais si l'attaquant envoie ?page=/etc/passwd, le serveur tente d'inclure le fichier système des mots de passe. C'est une LFI.
/dev/random ou fichiers infinis.Souvent, le développeur préfixe le chemin pour forcer un dossier (ex: include('pages/' . $file);).
Pour sortir de cette prison (Jailbreak), on utilise la séquence ../.
Le système de fichier résout cela ainsi :
pages/ : On entre dans pages.../ : On remonte (retour à la racine web).../ : On remonte (dans /var/www).../ : On remonte (dans /var).../ : On remonte (dans /).etc/passwd : On descend dans le dossier cible..php), on peut l'annuler avec un Null Byte.?page=../../etc/passwd%00include('../../etc/passwd\0.php');/etc/passwd.
PHP possède des flux d'E/S avancés (Wrappers) qui transforment une simple lecture de fichier en arme de guerre.
Par défaut, si vous incluez config.php, le code PHP est exécuté et vous ne voyez rien (page blanche). Pour voir le CODE SOURCE (et les mots de passe), on utilise un filtre d'encodage.
Le serveur renvoie une chaîne Base64 qu'il suffit de décoder pour lire le code source brut.
Si allow_url_include est activé, on peut injecter du code PHP directement dans l'URL.
Ici, on injecte un webshell encodé en base64. Le serveur l'exécute immédiatement.
Si on ne peut rien uploader, on infecte les logs du serveur.
<?php system($_GET['c']); ?>/var/log/apache2/access.log.?page=../../var/log/apache2/access.log&c=lsLa RFI est la cousine de la LFI, mais en pire. Au lieu d'inclure un fichier local, le serveur inclut un fichier distant hébergé par l'attaquant.
Pour que cela fonctionne, la configuration php.ini doit être permissive :
allow_url_fopen = On (Par défaut : On)allow_url_include = On (Par défaut : Off depuis PHP 5.2)<?php system(...) ?>) et force le serveur victime à le télécharger et l'exécuter instantanément.
Tester manuellement ../../ est fastidieux. Les professionnels utilisent des outils pour "fuzzer" les paramètres.
Le projet SecLists contient des milliers de variantes de payloads LFI.
Wfuzz ou FFuF permettent de tester des milliers de combinaisons par seconde.
Intercept la requête, envoie-la dans Intruder, définit la position du payload sur le nom du fichier, et lance l'attaque avec une wordlist "Path Traversal".
Ne jamais, jamais laisser l'utilisateur définir directement un chemin. Utilisez une map (switch/case ou array).
Si vous devez être dynamique, forcez le nom de fichier et empêchez la navigation dans les dossiers.
Durcissez la configuration du serveur :
allow_url_fopen = Off (Empêche RFI)allow_url_include = Off (Empêche data:// et input://)open_basedir = /var/www/html/ (Empêche d'accéder à /etc/passwd)Ne regardez cette section que si vous êtes bloqué. Copiez-collez les payloads dans l'URL du labo.
Récupérer le fichier /etc/passwd.
Récupérer la clé privée de l'admin pour se connecter au serveur.
Récupérer les mots de passe de la base de données.
Note: Dans ce labo simulé, on lit le fichier. En vrai PHP, il faudrait utiliser php://filter.