La faille include : RFI/LFI (Bases)

To the non-french speaker, note that you can translate the articles using the Google Trad widget situated at the bottom of all pages.


Dans une page web il y a souvent du code redondant. Par exemple le menu de la page, le pied de page ou encore la bannière sont des éléments que l’on retrouve sur chaque pages. Pour éviter d’avoir à recopier du code (ou le copier/coller), on peut décider de créer un fichier banniere.html, footer.html, ou encore menu.html et les inclure dynamiquement dans nos pages.

Pour cela on se servira de 4 fonctions PHP : require(), require_once(), include() et include_once().

Quelles sont les différences entre ces fonctions ? Pour le « once », cela veut juste dire que le fichier sera inclus une seule fois. Quant aux fonctions require et include, la différence est que si la fonction include() ne trouve pas le fichier à inclure alors une erreur sera affichée mais le reste du code de la page sera quand même exécuté. Avec require(), si le fichier à inclure n’est pas trouvé alors le code n’est pas exécuté.

Dans tous les cas, si l’inclusion n’est pas sécurisée, un attaquant sera en mesure de lire n’importe quel fichier sur le serveur ou pire, inclure des scripts malicieux qui lui permettront de prendre le contrôle du serveur.

I/ Détecter et exploiter une faille include

Voyons ce que ça donne avec un exemple. Ici j’ai trois fichiers :

1.png

Dans le fichier index.php nous avons notre fonction include :

1.png

Et dans les deux autres fichiers nous avons juste une ligne de texte :

3.png

Du coup, si dans mon URL je spécifie que je veux inclure la page « page1.html » :

http://localhost/index.php?page=page1.html

Je reçois bien son contenu :

4.png

A l’inverse si je ne spécifie pas de page à inclure, alors la page par défaut sera affichée :

http://localhost/index.php

5.png

Jusque là tout va bien. Mais qu’est ce qui se passerait si je voulais inclure un fichier qui n’existe pas ? Par exemple « motdepasse.txt » :

http://localhost/index.php?page=motdepasse.txt

6.png

On reçoit une erreur ! Retenez la bien car elle est typique d’une erreur d’inclusion et donc nous indique clairement que la faille include est présente. A partir du moment où nous avons détecté une faille include deux possibilités s’offrent à nous :

-La faille est de type locale (on parle alors de LFI pour Local File Include) et permet d’inclure des fichiers localement présents sur le serveur web.
-La faille est de type remote (on parle alors de RFI pour Remote File Include) et  permet d’inclure des fichiers présents sur d’autres serveurs.

  • Local File Include :

Si notre faille include est de type LFI alors cela veut dire qu’on va pouvoir inclure n’importe quel fichier présent sur le serveur vulnérable à commencer par le fichier /etc/passwd :

7.png

Suivant les fichiers disponibles on pourra trouver des identifiants de connexion à une base de données, des mots de passe, des fichiers confidentielles ou encore des fichiers de code source qui nous permettront de trouver d’autres vulnérabilités.

  • Remote File Inclusion :

Si la faille include est de type RFI alors là on va pouvoir inclure n’importe quel contenu venant de sites extérieurs. Autrement dit, un attaquant pourra inclure sur le serveur vulnérable un script malicieux qu’il aura hébergé sur son serveur à lui.

Par exemple si j’inclus http://google.com :

http://localhost/index.php?page=http://google.com/

Je vais avoir ce rendu :

8.png

Bien évidemment un attaquant n’inclura jamais une telle URL. A la place il préféra inclure une backdoor ou encore un webshell afin de prendre le contrôle du serveur.

II/ Comment se protéger des LFI/RFI ?

Plusieurs points permettent d’empêcher l’exploitation des LFI/RFI.

  • Pour les RFI :

La première et unique chose à faire, c’est de désactiver l’option « allow_url_include » et « allow_url_open » dans le fichier php.ini. Ce fichier se trouve dans le répertoire /etc/php/x.0/apache2/ (avec x le numéro de version de PHP) :

9.png

Si ces options sont désactivées alors il ne sera plus possible d’inclure d’URL et donc la partie RFI de la faille include sera patchée comme on peut le voir ci-dessous :

10.png

  • Pour les LFI :

Là c’est un peu plus compliqué. En effet on ne peut pas désactiver l’inclusion de fichiers internes puisque cela casserait pas mal de sites qui reposent sur ces fonctions. En revanche on peut limiter l’accès à certains fichier en se servant de l’option « open_basedir ».

Open_basedir est une option PHP qui permet d’indiquer à PHP quels sont les fichiers auxquels il  a accès. Avec cette option on va pouvoir dire à PHP que si quelqu’un essaye d’inclure un fichier en dehors du répertoire spécifié, eh bien PHP doit refuser l’inclusion.

Du coup si je donne ce répertoire à open_basedir :

11.png

Et que j’essaye d’accéder au fichier /etc/passwd, j’aurais une erreur :

12.png

En général ce genre de restriction d’accès est plus à faire au niveau du fichier de configuration du serveur web (que ce soit pour Apache ou Nginx) mais au cas ou, il est toujours bien de la spécifier dans le fichier de configuration de PHP.

Au niveau du code PHP, des modifications sont aussi à faire. Premièrement on va forcer l’utilisation d’une extension bien définie. En l’occurrence nous voulons que seuls les fichiers .html soient inclus. Voici comment on pourrait implémenter cette règle en PHP :

13.png

Seulement ce n’est pas suffisant. En plus d’imposer une extension, on pourra aussi imposer le répertoire dans lequel les fichiers à inclure sont stockés :

14.png

Mais encore une fois ce n’est pas suffisant car rien n’empêchera un attaquant d’utiliser les caractères « ../ » afin de se balader dans les répertoires pour inclure d’autres fichiers. Du coup il va aussi falloir filtrer les inputs en supprimant tous les caractères qui ne sont pas soit des chiffres soit des lettres. Et pour cela, on utilisera des regex :

15.png

A partir de maintenant je considère que notre application est plutôt bien sécurisée. Mais si vous voulez vraiment forcer la sécurité, rien ne vous empêche de déclarer un tableau contenant les pages incluables et de vérifier que les pages demandées font parties de ce tableau :

16.png

Seules les pages page1 et default pourront être incluses. Là maintenant vous pouvez être absolument sur que votre application est sécurisée contre la faille include 🙂 !

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s