Solution de iv3l pour Push it to the limit

intro web PHP

22 février 2025

Dans ce cas, vous faites face à une vulnérabilité d’injection SQL basique. Décomposons ce qui se passe à chaque étape et pourquoi cela fonctionne.

Inspecter le Code

Tout d’abord, vous inspectez le code source de la page. C’est une étape courante lorsqu’on essaie d’identifier comment les entrées des utilisateurs (comme le nom d’utilisateur et le mot de passe) sont traitées. Dans ce cas, vous remarquez un formulaire qui envoie des données, et vous découvrez également la requête SQL qui est exécutée pour authentifier l’utilisateur. Le code source révèle quelque chose comme :

SELECT * FROM users WHERE username="admin" AND password="poloska"

Cette requête cherche une ligne dans la table users où à la fois le username et le password correspondent aux valeurs entrées dans le formulaire. Cela est typique pour des formulaires de connexion simples.

Identifier la Vulnérabilité

La vulnérabilité ici réside dans le fait que l’application web insère directement les entrées des utilisateurs (username et password) dans la requête SQL sans les sanitiser correctement. Cela rend l’application vulnérable à une injection SQL. Dans un système sécurisé, les paramètres comme le username et le password devraient être paramétrés ou échappés pour empêcher les utilisateurs malveillants de modifier la structure de la requête. Cependant, dans ce cas, les valeurs sont directement injectées dans la chaîne de la requête.

Exploiter la Vulnérabilité

Maintenant, vous connaissez la structure de la requête, donc vous pouvez la manipuler. L’astuce consiste à utiliser la syntaxe de commentaire SQL (--) pour ignorer le reste de la requête après votre entrée, ce qui vous permet de contourner la vérification du mot de passe.

Votre payload :

admin"--

Voici comment cela fonctionne :

  • admin est le nom d’utilisateur avec lequel vous essayez de vous connecter.
  • -- est un commentaire en SQL, ce qui signifie que tout ce qui suit sur cette ligne est ignoré.

La requête envoyée à la base de données ressemble alors à ceci :

SELECT * FROM users WHERE username="admin" --" AND password="test"

Explications :

  • Après le --, la base de données traitera tout comme un commentaire.
  • Donc, la partie AND password="test" est ignorée par le moteur SQL.
  • La requête vérifie maintenant seulement si une ligne existe avec username="admin".
  • Puisque vous n’avez pas besoin de fournir un mot de passe valide (car la vérification du mot de passe est “commentée”), vous êtes connecté en tant qu’utilisateur admin.

Contourner la vérification du mot de passe

En injectant admin"--, vous avez effectivement ignoré la validation du mot de passe, car la requête SQL vérifie maintenant uniquement le username, et la partie du mot de passe est mise en commentaire. Tant que le nom d’utilisateur admin existe dans la base de données, vous serez authentifié sans avoir besoin de connaître le mot de passe correct.

Résultat final

Lorsque vous soumettez le formulaire avec ce payload, l’application envoie la requête SQL modifiée à la base de données, et la base de données retourne les données correspondantes à l’utilisateur admin sans vérifier le mot de passe. Comme vous avez contourné la vérification du mot de passe, vous accédez au compte admin (ou à tout autre compte que représente admin). Et voilà, le flag ou l’accès vous est accordé !

Points clés

  • L’injection SQL se produit lorsque les entrées des utilisateurs sont directement utilisées dans une requête SQL sans être correctement sécurisées, ce qui permet aux attaquants de manipuler la structure de la requête.
  • Les commentaires en SQL (--) sont utilisés pour ignorer une partie de la requête, ce qui, dans ce cas, vous permet de contourner la validation du mot de passe.
  • Il s’agit d’une injection SQL basique où l’attaquant n’a pas besoin de voir les erreurs ou les messages de la base de données, mais peut toujours manipuler la structure de la requête.

Mitigations

Pour éviter ce genre d’attaque, il faut sanitiser correctement les entrées des utilisateurs. La méthode la plus efficace consiste à utiliser des requêtes préparées ou paramétrées où les entrées des utilisateurs sont traitées comme des données, pas du code exécutable. De cette manière, même si un attaquant tente d’injecter du SQL, cela ne modifiera pas la logique de la requête.

Si vous écriviez ce code de manière sécurisée, cela pourrait ressembler à ceci :

cursor.execute("SELECT * FROM users WHERE username=? AND password=?", (username, password))

Cela garantit que les entrées des utilisateurs ne peuvent pas modifier la structure de la requête.