Qu’est-ce que la faille LFI

La faille LFI tient son nom de Local File Inclusion (Inclusion de fichier local). Elle permet à un utilisateur d’inclure des fichiers locaux dans un site (appartenant au serveur sur lequel est hébergé le même site), et cela à partir d’une URL.

Keskidi?

En somme, un site web faillible peut permettre l’inclusion de fichiers arbitraires dans son propre contenu.

Ces fichiers peuvent très bien être en dehors du répertoire racine du site web. Des fichiers sensibles comme ceux contenant des données personnelles et notamment des mots de passe peuvent donc être inclus et récupérés.

Prenons un exemple, voulez-vous ?

On a souvent besoin d’inclure un fichier dans une page de façon tout à fait légitime comme sur l’exemple qui suit :

 http://exemple.com/vulnerable.php?page=menu.php

Seulement le fait de vérifier si ce fichier existe ne suffit pas, il faut s’assurer qu’il soit celui que l’on veut. (Et pas celui que n’importe qui choisit)

Que peut-on faire avec une faille LFI ?

Habituellement cette faille peut permettre de récupérer des informations comme les noms des utilisateurs de votre serveur et leurs mot de passe :

http://www.exemple.com/pagevulnerable.php?page=../../../../../../../../../../../etc/passwd

Faille LFI fichier passwd

Exemple de fichier passwd qui peut s’afficher directement sur un site faillible.

 

On peut également récupérer le code source d’une page php ou exécuter des commandes PHP à distance en les postant vers une url spécifique.

Dans le pire des cas, un shell php peut être installé sur votre serveur afin d’autoriser un pirate à exécuter des commandes à distance.

Et shell dans le monde du hacking est en effet une interface « injectée » à travers une faille web permettant de servir de tableau de bord pour exploiter le système.

Comment savoir si mon site est faillible ?

Si votre site utilise une URL comme nous l’avons vu plus haut, il est possible qu’il soit faillible.

Voici un exemple typique de script php faillible :

<?php
   $fichier = $_GET['fichier'];
   if(isset($fichier))
   {
       include("pages/$fichier"); //inclut le fichier si il existe
   }
   else
   {
       include("index.php"); 
   }
   ?>

Par exemple, regardez si un utilisateur peut accéder aux fichiers de votre site :

http://www.exemple.com/vulnerable.php?page=../../../../../../../../fichier

 

Il faudra évidemment adapter le nombre de répertoire parents requis (../).

Si les ../ vous paraissent curieux depuis le début de cet article, il faut savoir que sous les systèmes Linux, cela signifie « dossier parent ».

Admettons pour cela un dossier appelé « dossier », présent à la racine du site. La racine étant « / ».

On a donc (architecture Linux) : /dossier.

Dans ce joli dossier, nous avons un sous-dossier :

/dossier/sous-dossier/

Et enfin un fichier dans ce même sous-dossier :

/dossier/sous-dossier/fichier

Attention, on complique les choses et l’on place un fichier motdepasse dans le dossier initial :

/dossier/sous-dossier/fichier
/dossier/motdepasse

Dans « dossier » on a donc « sous-dossier » (contenant lui-même « fichier ») et « motdepasse ».

Eh bien, même en nous trouvant dans le sous-dossier (là où est fichier), on peut chercher le fichier motdepasse en utilisant :

../../motdepasse

../ dit « dossier parent au dossier actuel », il s’agit donc de sous-dossier, c’est comme dire /dossier/sous-dossier.

Puis ../../ cherche encore le dossier parent de « sous-dossier », soit « dossier ».

Une fois dans le dossier cible, en passe à « motdepasse ».

Vous allez me dire: mais que fait-on à la base dans le « sous-dossier » en question ? Eh bien c’est tout simplement un dossier quelque part dans le système où se trouvent physiquement tous les codes sources du site web concerné ! Le système « travaille » donc à partir de ce dossier. Et les ../ sont relatifs à celui-ci.

Tout cela pour dire, qu’on peut naviguer entièrement dans le système de fichier et pointer les fichiers que l’on souhaite, à condition de connaître l’architecture… ou d’essayer à tâtons…

Et parfois il faut « revenir » dans beaucoup de dossiers parents, d’où l’enchaînement des « ../ ».

Comment se prémunir de la faille LFI ?

On va donc changer notre script précédent pour éliminer la possibilité d’utiliser « ../ » et forcer l’extension « .php »:

<?php
   $fichier= str_replace('../', '', $_GET['fichier']); //élimine ../
   if(isset($fichier))
   { //le fichier devra être inclus par son nom sans .php
       include("$fichier". ".php"); //ajoute ici le .php
   }
   else
   {
       include("index.php");
   }
   ?>

Pas mal ?

Vous pensez ?

Sachez cependant qu’il est possible d’utiliser l’encodage hexadécimal à la place des slashs car le navigateur les convertit correctement :

http://www.exemple.com/vulnerable.php?page=..%2F..%2F..%2F..%2F..%2Ffichier

Et il est aussi possible d’utiliser le NULL Byte %00 pour passer outre cette restriction.

Sur les nouvelles versions de Apache (un serveur web populaire) ce genre d’exploitation n’est maintenant plus possible car %2F et %00 ne sont pas gérés par sécurité. Cela dit vous pouvez tout de même ajouter cette ligne pour éviter la faille :

$fichier= str_replace(chr(0), '', $fichier); //chr(0) étant le null byte

Une autre technique plus simple et radicale consiste à inclure le nom directement dans le code sans passer par l’URL mais en testant un nom à la place:

<?php if ($_GET['page'] == “news”) {
    include(“news.php”);
} else {
    include (“accueil.php”);
}?>

Envie d’en apprendre plus sur les failles web ?

Cette faille et bien d’autres est vue en détail dans mon cours vidéo sur les tests d’intrusion web.

Nous allons parler des fondamentaux : fonctionnement d’HTTP, d’HTTPs, de DNS et de l’architecture web de manière générale.

Nous allons également mettre en place un laboratoire de test avec des machines virtuelles pour héberger et scanner nos sites vulnérables afin d’apprendre sans rien casser.

Nous allons bien sûr parler de toutes les failles web (XSS, CSRF, SQL, LFI, RFI, …etc) en suivant le Top 10 OWASP mais aussi de tout ce qui gravite autour de la sécurité web : dénis de service, mauvaises configurations, données personnelles, reconnaissance, etc…
Impatient de commencer avec vous, je vous propose de rejoindre le cours dès maintenant : https://cyberini.com/cours/hacking-ethique-tests-intrusion-web/

Articles similaires

Commentaires
Cliquez ici pour ajouter un commentaire

  • […] Faille LFI / RFI […]

    Répondre
  • Bonjour ,

    Je pense qu’il faut revoir cette partie : $fichier= str_replace(‘../’,  », $_GET[‘fichier’]); //élimine ../
    car cela n’élimine pas vraiment le ../ au cas où le payload donné est le suivant : ….//….//….//….//etc/passwd. Donc ici on arrive quand même à exploiter la faille. Il faut donc evaluer le chemin avec realpath() ou autre ;). Merci

    Répondre
  • Bonjour
    Merci pour l’astuce
    Sinon pour contrer les éléments répétitifs j’ai ajouté une boucle

    $nbrocc=substr_count($page,’../’);

    if ($nbrocc>0) {

    for ($i = 1; $i <= $nbrocc; $i++) {

    $page= str_replace('../', '', $page);
    }
    }

    à priori ca devrait résoudre le cas
    le if juste pour le pas faire mouliner pour rien les pages normales…

    Répondre
  • Bonjour Michel,
    Si je fais mon site en Joomla, le code est-il protégé décemment ?
    Bien à toi.
    Marc

    Répondre
    • Bonjour Marc, c’est une excellente question et je m’en veux de ne pas avoir répondu plus tôt. En fait, Joomla DEVRAIT surtout être protégé décemment à la base, et donc effectivement éviter toutes présences de telles failles. Je n’ai aucun moyen de la garantir (et je crois qu’eux-même non plus). C’est bien ça la difficulté au final ! Soit on fait tout nous-même en sachant qu’on fait aussi des erreurs, et que cela prendra beaucoup plus de temps, soit on fait confiance, parfois aveuglément, à d’autres développeurs. C’est le cas de WordPress aussi, et que j’utilise d’ailleurs !

      Répondre
  • Je remarque au fil du temps que des explications en vidéo seraient plus pertinentes… Car il est difficile de comprendre tout cela du premier coup, et je n’ai pas forcément très bien expliqué.

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous devez remplir ce champ
Vous devez remplir ce champ
Veuillez saisir une adresse e-mail valide.

Menu