Trouver la sonde SQLi : lire les payloads d'injection dans les logs web
Le défi
Votre point de terminaison de recherche est bombardé de requêtes étranges. Caché parmi les recherches normales, une IP envoie des charges classiques d'injection SQL - des choses comme ' OR '1'='1 et UNION SELECT - pour sonder si la barre de recherche parle directement à la base de données. Filtrez les requêtes suspectes, trouvez l'attaquant unique, et soumettez son IP.
Ce que tu vas apprendre
- Lire la query string d'une requête, pas seulement l'IP et le statut
- Reconnaître les payloads classiques d'injection SQL dans les logs d'accès
- Distinguer les sondes d'injection des recherches normales
- Utiliser les codes de statut d'erreur comme signal secondaire d'une attaque par requête malformée
- Attribuer une attaque web à une IP source unique
Compétences testées
Prérequis
- Compréhension de base des requêtes SQL et de la clause WHERE
- Familiarité avec les paramètres de requête d'URL
- Connaissance des codes de statut HTTP (200, 500, 504)
Comment ça marche
Une injection SQL se produit lorsqu'une application insère l'entrée utilisateur directement dans une requête de base de données sans séparer le code des données. Un attaquant la sonde en envoyant une entrée qui, une fois reflétée dans le SQL, change le sens de la requête. Dans un log d'accès, cela est directement visible : l'intention malveillante est écrite dans la query string de l'URL, pour quiconque lit la colonne path.
Ici, l'attaquant, 203.0.113.200, suit le scénario classique contre /search. Une simple apostrophe (q=laptop') teste une rupture de syntaxe et déclenche un 500. Puis un contournement booléen (' OR '1'='1), une sonde de comptage de colonnes (UNION SELECT null,null), une tentative de vol de données (UNION SELECT username,password FROM users), un dump de schéma (information_schema.tables), un test basé sur le temps (AND SLEEP(5) produisant un 504), et un payload destructeur (;DROP TABLE users). Chaque utilisateur légitime ne fait que taper des noms de produits, donc les chaînes d'injection ressortent dès que l'on lit la valeur de la requête au lieu de survoler les IP.
Les erreurs sont un indice utile mais secondaire. Filtrer sur status:500 fait apparaître les lignes où le SQL malformé a cassé la requête, et elles appartiennent toutes à la même IP, mais les lignes d'injection réussies en 200 comptent tout autant, car un résultat retourné signifie que le contournement a peut-être fonctionné. La preuve décisive est le contenu du payload combiné à sa source unique.
Erreurs fréquentes
- Filtrer uniquement sur le statut. Beaucoup des pires payloads renvoient un
200; filtrer seulement surstatus:500fait manquer les injections qui ont réussi. - Survoler les IP en ignorant la query string. L'attaque est dans la valeur
q=, il faut la lire. - Prendre des recherches bizarres pour des fautes de frappe. Une apostrophe isolée peut être une faute de frappe ;
UNION SELECT password FROM usersn'en est pas une. - Soumettre le path ou le payload au lieu de l'IP. La question demande qui, la source unique qui envoie les injections.
Comment s'en protéger
L'injection SQL se prévient dans le code, pas en espérant que personne ne l'essaie. Les mêmes payloads que vous avez repérés dans le log sont exactement ce qu'un WAF et des règles de détection doivent attraper.
- Utilisez des requêtes paramétrées ou des prepared statements pour que l'entrée utilisateur soit toujours de la donnée, jamais du code SQL.
- Validez et contraignez l'entrée (un terme de recherche n'a pas besoin d'apostrophes, de points-virgules, ou du mot UNION).
- Alertez sur les requêtes dont la query string contient des marqueurs d'injection comme
UNION SELECT,OR 1=1, ouinformation_schema, surtout répétés depuis une même source. - Faites tourner la base de données avec le moindre privilège afin qu'une injection réussie ne puisse pas supprimer des tables ni lire des données non liées.