SQLInjection cheat sheet
Cél:
Van egy users tábla, amiben van egy admin nevű felhasználó, és annak a jelszavát kell megszerezni.
Alap query SQL sziintaxisa:
SELECT author, title, rating, cover_url FROM BOOK WHERE title = '{search_obj}';
SELECT author, title, rating, cover_url FROM BOOK
WHERE title = '{search_obj}';
Itt a search_obj lesz az amit a felhasználó ad meg. Ez azt jelenti, hogy a felhasználó mondja meg, hogy mi legyen a címe a lekért könyvnek. Ez itt a problémás, mert a felhasználó tényleg bármit meg tud adni a lekérdezésben, és ezzel úgy meg tudja változtatni a lekérdezésünket, hogy olyan lekérdezést valósítson meg, amit mi nem szerettünk volna, hogy megtegyen.
Ha mondjuk a felhasználó ezt az inputot adja a programunknak:
search_obj = alma' valami
Akkor a lekérdezés, így fog kinézni:
SELECT author, title, rating, cover_url FROM BOOK WHERE title = 'alma'valami';
Itt látható, hogy az "alma" szó után, lezártam a szöveget, és így a kikerültem abból a részből, ami a könyv címét adja meg. Ekkor már SQL kódot írok. Itt részre lehet venni, hogy a lekérdezés dob egy elnöki méretű hibát. Ez azért van, mert azzal, hogy kitörtünk a string-ből elrontottuk a szintaxisát a lekérdezésnek, ezt egyszerűen meg tudjuk javítani. +
Komment használata:
Patch: + A lekérdezés többi részét ami nekünk nem kell kikommenteljeük.
SELECT author, title, rating, cover_url FROM BOOK WHERE title = 'alma'valami --';
Itt az lehet problémás, ha az sql kódba való kontárkodás után van még fontos része a lekérezésnek, akkor azt is eldobtuk.
Most egyszerűen ki tudjuk listázni, az egész tábla tartalmát. Viszont nem találtunk semmi olyan adatot amit felhasználhatnánk. Valószínűleg ezt az adatot egy másik tábla tárolja.
Hogyan tudunk másik táblából lekérdezni (UNION):
SQLite-ban azt a táblát ami a táblákat tartalmazza sqlite_master-nak nevezzük. Listázzuk ki ennek a táblának a tartalmát. Ezt a UNION kulcsszó használatával tudjuk megoldani.
SELECT attributum1 FROM tabla WHERE attributum = 1 UNION SELECT 2 FROM tabla2 WHERE attributum2 = 3;
Ez a szintaxisa a lekérdezésnek, ez szimplán az eredeti lekérdezés után rakja azokat a rekordokat, amiket a UNION megtalál. + Itt az a fontos, hogy ugyanannyi értéket szabad visszaadnia a UNION-os lekérdezésrésznek, mint a fő lekérdezésnek. Ahogy látszódik a példán is, hogy mindkettő lekérdezés 1 elemet ad vissza.
Hol találjuk meg a többi táblát?
Arra kell még figyelnünk, hogy az sqlite_master táblából nekünk a tbl_name oszlop kell nekünk.
Így a lekérdezés, az alábbi módon fog kinézni:
SELECT author, title, rating, cover_url FROM BOOK WHERE title = 'alma' UNION SELECT tbl_name, 1, 2,3 FROM sqlite_master--';
Avagy az input amit meg kell adnunk:
alma' UNION SELECT tbl_name, 1, 2,3 FROM sqlite_master--
Itt azt fogjuk megkapni, hogy létezik egy users nevű tábla.
Próbáljuk meg megnézni, mi van ebben a táblában. Ezt ugyanúgy a UNION kulcsszóval tudjuk megtenni.
Végső lekérdezés:
SELECT author, title FROM BOOK WHERE author = 'alma' UNION SELECT username, password FROM users --';
Azaz a következő inputot kell nekünk beadni.
alma' UNION SELECT username, password FROM users --
És ekkor megkapjuk az összes felhasználó felhasználónevét és jelszavát, aucs.
Gyakori hibák:
- "-et használnak ' helyett. SQL általában mindig '-et használ
- Nincsen komment a lekérdezés végén
- Beragad valami az inputba és ha újratöltik az oldalt, akkor alapból elküldi a rossz lekérdezést a szervernek, ezért látszik úgy mintha teljesen eltört volna a szerver.
- A UNION kulcsszó más mennyiségú adatot ad vissza (4-et kell visszaadnia)
- A UNION olyan sorrendbe adja vissza az elemeket ahogy az eredeti, is de az utolsó elemet kép-ként parse-olja a szerver. Próbálják meg megváltoztatni a SELECT utáni attribútumok sorrendjét.
Kis plusz help
A böngészőbe épített Console kiírja az aktuális lekérdezést, hasznos debuggolásnál.