Tweets by @buherablog
profile for buherator at IT Security Stack Exchange, Q&A for IT security professionals

A BitBetyár Blog

Túljártál a nagyokosok eszén? Küldd be a mutatványodat! (e-mail a buherator gmailkomra jöhet)

Full-Disclosure / Névjegy / Coming out


Promó

H.A.C.K.

Címkék

0day (110) adobe (87) adobe reader (21) anonymous (26) apple (60) az olvasó ír (49) blackhat (20) botnet (22) bug (200) buherablog (44) buhera sörözés (39) bukta (49) deface (38) dns (22) dos (29) esemény (82) facebook (26) firefox (64) flash (33) gondolat (31) google (59) google chrome (36) hacktivity (37) hírek (117) incidens (224) internet explorer (88) iphone (35) java (50) jog (22) kína (21) kriptográfia (68) kultúra (21) linux (24) malware (43) microsoft (142) móka (48) mozilla (23) office (26) oracle (40) os x (43) patch (197) php (20) politika (31) privacy (58) programozás (22) safari (34) sql injection (62) windows (85) xss (77) Címkefelhő

Licensz

Creative Commons Licenc

Hétvégi matekóra: Gyorsabb Blind SQL Injection

2007.10.06. 12:37 | buherator | 2 komment

A blind (vak) SQL injectiont hagyományosan úgy szokás felfogni, mint egy bináris keresést az ASCII táblán, vagy annak egy részén.  Ennek lépésszáma O(log2 n)-nel arányos, ahol n a teljes ASCII táblát figyelembe véve 255 (a nullbyte nem érdekes), így a logaritmus értéke kb. 8 lesz, azaz átlagosan ennyi kérést kell intéznünk a sebezhető kiszolgálóhoz, hogy egy mező egy karakterét megkapjuk. Persze senki nem szereti felhívni magára a figyelmet, ezért érdemes elgondolkodni azon, hogy hogyan lehetne ezt a számot minál inkább csökkenteni. Stefano Di Paola egy pofonegyszerű ötletet mutat be a blogjában (bár valószínűleg nem ő volt az első, aki ezt a módszert használta, az ötlet tulajdonképpen triviális)


Tegyük fel, hogy van egy sebezhető alkalmazás a victim.com/page.php címen, amely különböző adatbázisban tárolt oldalakat jelenít meg a neki átadott id paramétertől függően. Ez a paraméter természetesen nincs megfelelően szűrve, SQL kéréseket injektálhatunk, a hibajelzések viszont ki vannak kapcsolva, ezért csak arra hagyatkozhatunk, hogy a kérésünk lefutása után melyik oldal (nem) jelenik meg a képernyőn.

A kulcs pedig itt van, ugyanis ha az alkalmazás több oldalt is megjelenít (végülis erre találták ki), akkor összeállíthatunk egy ügyes IF-ELSE szerkezetet melynek injektálásával a vizsgált függvényünk (tipikusan a substr()) visszatérési értékét  egyszerre több diszjunkt logikai  kifejezéssel is vizsgálhatjuk, melyek mindegyike más és más legitim oldalra irányít minket amennyiben a kifejezés értéke IGAZ:

res=substr(<field>,pos,1);

if(res>191 and res<255)
  then 1
else if(res>127 and res<192)
  then 2
else if(res>63 and res<128)
  then 3
else
    4


Hogy ez milyen hatással van a keresőalgoritmus komplexitására? Természetesen a logaritmus alapja növekszik meg annyira, ahány különböző oldalt tudunk a kimenetre varázsolni! log2(255) helyett tehát logP(255) lesz az algoritmus átlagos lépésszáma, ahol P a megjeleníthető oldalak száma, a függvénygörbénk tehát egyre laposabb lesz. Néhány számadat, összehasonlításképpen:

log2(255)=7,99 -> hagyományos bináris keresés
log5(255)=3,4
log10(255)=2,4
log255(255)=1 -> optimum :)

Öt megjeleníthető oldal esetén tehát a szükséges kérések száma kb. felére csökken. Ne szemeteljük tehát tele a logokat, ha nem muszáj, drágák a bitek ;)

Címkék: sql injection

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

_2501 2007.11.27. 11:58:57

Hi mann!

Nem rossz, tetszett a dolog, inspiráló.
Teljes blind injektből több értéket visszahozni az injekten belül már ninjutsu. :)
Olyan esetben mint a fenti példa, jó megoldás lehet az if szerkezet, de feltétele hogy több érték legyen kiválasztható.
Amennyiben erre nincs lehetőség arra lenne egy alternatív javaslatom.
Bár a cím az hogy gyorsabb injekt, ez most ne zavarjon, (ha már engem sem zavar :P) csak egy alternatív lehetőséget mondok.
A kulcsszó a válaszidő.
Az sql kérést úgy kraftolom fel hogy a válaszidőből lehessen következtetni az értékre.
konkrétan:

mysql> select CASE 1 when 1 then sleep(1) when 2 then sleep(2) else '...' END;

1 row in set (1.00 sec)

mysql> select CASE 2 when 1 then sleep(1) when 2 then sleep(2) else '...' END;

1 row in set (2.01 sec)

Nem pastoltam be a teljes outputot, nem az a lényeg.
Ha egy webes alkalmazásnak küldesz be egy ilyet, akkor a kiszolgálás válaszideje a query futásának idejétől is függ, és ha ezt az időt nézed akkor tudsz következtetni egy egy értékre.
Jobb eset ha az oldalon megjelenik valahol h mennyi ideig futott a query.
Nagy terhelésű szervereken a terheltség függvényében ingadozhat a válaszidő szal nem 100%-os módszer.
Csak egy lehetőség.

Vélemény?

buherator · http://buhera.blog.hu 2007.11.27. 12:12:20

Ez is nagyon jó ötlet, ráadásul, ha az ingadozás nem nagy (kis forgalmú időszakban kell játszani), akkor az overhead is épeszű marad, a logokat pedig mindenképp kíméled. Ha viszont proxykon keresztül okoskodsz, akkor már nem vagyok benne biztos hogy a válaszidőkkel sokra mész, főleg mondjuk egy Tor hálózat esetében, de ilyenkor is ott lehet még a "generated in ..." az oldal alján :)