Error-based
🔍 Définition
L'injection SQL basée sur les erreurs exploite les messages d'erreur générés par une base de données pour extraire ou déduire des informations sensibles.
⚙️ Principes de Base
Messages d'Erreur SQL
But : Utiliser les erreurs pour obtenir des informations sur la base de données.
Détails : Les messages d'erreur peuvent révéler des données ou la structure des tables.
Exemple 👍
xyz' AND 1=CONVERT(INT, (SELECT TOP 1 nom FROM utilisateurs));Explication : tente de convertir le premier nom de la table utilisateurs en entier ; si le nom contient des caractères non numériques, cela provoquera une erreur de conversion, révélant ainsi des détails sur les données de la colonne nom.
Injection de Condition Booléenne
Principe : Injecter des conditions booléennes pour provoquer des erreurs spécifiques.
Exemple : Ajouter
OR 1=1pour observer si l'application génère une erreur ou non.
' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='aPuisque 1=2 est faux, la partie THEN 1/0 n'est pas exécutée. Au lieu de cela, le ELSE est utilisé, renvoyant 'a'.
Résultat : Aucune erreur n'est générée parce que l'expression retourne 'a'.
Explication : 1=1 est vrai, donc 1/0 provoque une erreur. La réponse HTTP montrera une différence si l'erreur est déclenchée.
Sénario
Test de la Présence d'Erreurs
Provoque une erreur de syntaxe car elle laisse une chaîne de caractères ouverte dans la requête SQL.
Corrigent cette erreur en fermant correctement la chaîne de caractères, confirmant que l'erreur précédente était bien une erreur de syntaxe SQL.
Vérifier si l'application traite correctement une sous-requête valide
Essayez une sous-requête valide :
Si cela semble invalide, essayez avec une table prévisible :
Si l'erreur disparaît, cela indique que la base de données est probablement Oracle.
Tester des Requêtes Invalides
Soumettez une requête avec une table inexistante :
Si une erreur est renvoyée, cela suggère que l'injection est interprétée comme une requête SQL.
Vérifier l'Existence d'une Table :
Testez l'existence de la table
users(limite la sélection à une seule ligne avecWHERE ROWNUM = 1)Si aucune erreur n'est renvoyée, la table
usersexiste.Tester des Conditions :
Soumettez la requête suivante pour déclencher une erreur conditionnelle :
Vérifiez que vous recevez un message d'erreur.
Changez ensuite en :
Vérifiez que l'erreur disparaît. Cela montre que vous pouvez déclencher une erreur conditionnelle.
Une erreur apparaît pour la condition vraie 1=1 et disparaît pour la condition fausse 1=2
Tester l'Existence d'un Utilisateur :
Utilisez cette requête pour vérifier si un utilisateur nommé
administratorexiste :
Si le username est administrator, et puisque 1=1 est toujours vrai, la requête provoquera une division par zéro, générant ainsi une erreur SQL.
Si le username n'est pas administrator, aucune ligne ne sera sélectionnée, et la sous-requête retournera simplement une chaîne vide, sans erreur.
Déterminer la Longueur d'un Mot de Passe :
Changez la valeur pour tester la longueur du mot de passe :
Si une erreur est reçue, cela confirme que le mot de passe a plus de 1 caractère.
Déterminer les Caractères du Mot de Passe :
Envoyez la requête suivante à Burp Intruder pour tester chaque caractère :
Définissez des payloads de a à z et de 0 à 9 dans Burp Intruder.
🧪 Test de la Présence d'Erreurs
Provoquer une Erreur de Syntaxe :
Injectez une apostrophe non fermée pour provoquer une erreur de syntaxe :
Explication : Une apostrophe non fermée dans MySQL génère une erreur de syntaxe SQL.
Corriger l'Erreur :
Testez avec une apostrophe supplémentaire pour fermer la chaîne correctement :
Explication : Deux apostrophes consécutives (
'') dans MySQL sont interprétées comme un seul caractère apostrophe, ce qui corrige l'erreur de syntaxe.
🔍 Vérifier les Sous-Requêtes Valides
Tester une Sous-Requête :
Essayez une sous-requête simple :
Explication : En MySQL,
dualn'est pas nécessaire, mais ajouter--pour commenter le reste de la requête permet d'éviter les erreurs de syntaxe additionnelles.
Utiliser une Table Prévisible :
Testez avec une table connue ou visible :
Explication :
information_schema.tablesest une table système utilisée pour vérifier l'existence des tables dans MySQL.
❌ Tester des Requêtes Invalides
Requête avec une Table Inexistante :
Injectez une requête qui fait référence à une table qui n'existe pas :
Explication : Une erreur apparaît si la table n'existe pas, confirmant que l'injection est traitée comme une requête SQL.
🗃️ Vérifier l'Existence d'une Table
Tester la Table users :
Testez l'existence de la table
users:Explication : Aucune erreur indique que la table
usersexiste.
🔄 Tester des Conditions
Déclencher une Erreur Conditionnelle :
Soumettez une requête avec une condition qui provoque une erreur :
Explication : Provoque une division par zéro si la condition est vraie.
Modifier la Condition :
Testez une condition fausse :
Explication : Pas d'erreur si la condition est fausse, prouvant que l'injection peut déclencher des erreurs conditionnelles.
🔐 Tester l'Existence d'un Utilisateur
Vérifier un Utilisateur administrator :
Testez si un utilisateur spécifique existe :
Explication : Provoque une erreur si l'utilisateur existe (division par zéro) ; sinon, retourne une chaîne vide.
🧩 Déterminer la Longueur du Mot de Passe
Tester la Longueur :
Vérifiez la longueur du mot de passe :
Explication : Une erreur confirme que le mot de passe a plus de 1 caractère.
🔠 Déterminer les Caractères du Mot de Passe
Tester chaque caractère :
Envoyez des requêtes pour tester les caractères :
Explication : Utilisez Burp Intruder pour tester chaque caractère à chaque position du mot de passe.
Note : En MySQL, les commentaires -- sont utilisés pour ignorer le reste de la requête après l'injection, contrairement à Oracle où || est utilisé pour la concaténation de chaînes. Utilisez ces modifications pour adapter les injections SQL à MySQL.
🧪 Test de la Présence d'Erreurs
Provoquer une Erreur de Syntaxe :
Injectez une apostrophe non fermée pour provoquer une erreur de syntaxe :
Explication : Une apostrophe non fermée dans PostgreSQL génère une erreur de syntaxe SQL.
Corriger l'Erreur :
Testez avec une apostrophe supplémentaire pour fermer correctement la chaîne :
Explication : Deux apostrophes consécutives (
'') dans PostgreSQL sont interprétées comme un seul caractère apostrophe, ce qui corrige l'erreur de syntaxe.
🔍 Vérifier les Sous-Requêtes Valides
Tester une Sous-Requête :
Essayez une sous-requête simple :
Explication :
pg_tablesest une table système de PostgreSQL. La requête valide indique que l'injection est interprétée comme SQL.
Utiliser une Table Prévisible :
Testez avec une table connue ou visible :
Explication :
information_schema.tablesest une table système utilisée pour vérifier l'existence des tables dans PostgreSQL.
❌ Tester des Requêtes Invalides
Requête avec une Table Inexistante :
Injectez une requête qui fait référence à une table qui n'existe pas :
Explication : Une erreur apparaît si la table n'existe pas, confirmant que l'injection est traitée comme une requête SQL.
🗃️ Vérifier l'Existence d'une Table
Tester la Table users :
Testez l'existence de la table
users:Explication : Aucune erreur indique que la table
usersexiste.
🔄 Tester des Conditions
Déclencher une Erreur Conditionnelle :
Soumettez une requête avec une condition qui provoque une erreur :
Explication : Provoque une division par zéro si la condition est vraie.
Modifier la Condition :
Testez une condition fausse :
Explication : Pas d'erreur si la condition est fausse, prouvant que l'injection peut déclencher des erreurs conditionnelles.
🔐 Tester l'Existence d'un Utilisateur
Vérifier un Utilisateur administrator :
Testez si un utilisateur spécifique existe :
Explication : Provoque une erreur si l'utilisateur existe (division par zéro) ; sinon, retourne une chaîne vide.
🧩 Déterminer la Longueur du Mot de Passe
Tester la Longueur :
Vérifiez la longueur du mot de passe :
Explication : Une erreur confirme que le mot de passe a plus de 1 caractère.
🔠 Déterminer les Caractères du Mot de Passe
Tester chaque caractère :
Envoyez des requêtes pour tester les caractères :
Explication : Utilisez Burp Intruder pour tester chaque caractère à chaque position du mot de passe.
🛠️ CAST et Erreur Verbose
🔍 Principe :
Les messages d'erreur détaillés générés par une mauvaise configuration de la base de données peuvent révéler des informations précieuses, comme des données sensibles ou des détails sur la structure des tables. Ces informations peuvent être exploitées pour obtenir des données que l’on ne pourrait pas normalement voir.
Identifier la Construction de la Requête SQL
Exemple de Message d'Erreur :
Explication : Ce message montre la requête SQL complète construite par l'application, incluant l'injection. Ici, l'erreur provient d'une chaîne de caractères non terminée (unquoted string) causée par l'injection d'une seule apostrophe. Cela indique où et comment les données sont intégrées dans la requête, ce qui aide à formuler des charges utiles (payloads) malveillantes valides.
Conseil : Commenter ou corriger la syntaxe SQL peut prévenir des erreurs, mais la manière dont la requête est construite peut fournir des indices utiles pour les attaques.
Utilisation de la Fonction CAST() :
Exemple de Requête :
Explication : La fonction CAST() tente de convertir des données d'un type à un autre (ici, d'une chaîne de caractères à un entier). Si les données ne sont pas du bon type, une erreur se produit.
Message d'Erreur :
Conseil : L'erreur générée peut révéler des données brutes ou des détails sur les colonnes et les tables. Cela est particulièrement utile si la limite de caractères empêche de déclencher des réponses conditionnelles.
🔄 Sénario
🛠️ Provoquer une Erreur SQL
Révéler des informations sur la requête SQL
Vérifier si la requête est maintenant correctement formatée et exécutée.
🔍 Tester une Sous-Requête Générique
Vérifier si la base de données accepte les sous-requêtes et la conversion de types.

Corriger la Condition :
📄 Extraire des Données
Adaptez la requête pour récupérer les noms d'utilisateur :
But : Tenter de récupérer les noms d'utilisateur en adaptant la requête. Vous recevrez une erreur si la requête est trop longue ou tronquée.

🌍 Libérer des Caractères
Supprimez la valeur originale du cookie pour libérer des caractères :
Limiter les Résultats
Modifiez la requête pour limiter les résultats à une seule ligne :
🔒 Extraire le Mot de Passe
Modifiez la requête pour obtenir le mot de passe de l'utilisateur :
Time Sleep
Si la condition est vraie, la base de données attend un certain temps avant de répondre. En mesurant le délai de réponse, on peut déterminer si la condition est vraie, révélant ainsi des informations sensibles.
Test condition vraie
But : L'application met 10 secondes à répondre, confirmant que la requête est exécutée correctement.
Test condition Fausse
But : l'application répond immediatement
Vérifier la Présence d'un Utilisateur
But : Confirmez que l'utilisateur
administratorexiste si l'application met 10 secondes à répondre.%3 = ;en URL+ = espaceen URL
Déterminer la Longueur du Mot de Passe
But : Vérifiez si le mot de passe est plus long qu'un caractère en observant un délai de 10 secondes.
Extraire les données
Intruder :
Définir les 2 payloads
Définir le "Maximum concurrent requests" dans "ressource pool" à 1 pour limitez le nombre de requêtes envoyées en même temps à une seule.
Regarder "Résponse received" pour voir le temps de réponse.
Voici la requête de base pour le Time sleep :
Last updated