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

Csak erős idegzetűeknek: extrém Flash exploit

2008.04.16. 22:50 | buherator | 1 komment

Miközben a feedjeimen rágtam át magam feltűnt, hogy többen hanyattdobták magukat Mark Dowd 25 oldalon kifejtett Flash-támadási módszerétől, de részletesebben utánajárni a dolognak nem volt időm. Aztán hazafelé döcögve már alig vártam hogy beleássam magam a leírásba, hazaérvén tehát az első dolgom volt elővenni a PDF-olvasómat és nekiállni az írásnak. Azt már az első néhány oldal után láttam, hogy nem fogom a fordítással megkönnyíteni a dolgotokat, főként terjedelmi okok miatt, de azt azért mindenképpen szerettem volna, hogy mindenki lássa milyen az, amikor a hackelést már művészi szinten űzik.
Úgy döntöttem tehát, hogy Thomas Ptacek (egyébként rendkívül szórakoztató) összefoglalóját fogom számotokra magyarítani, mivel ez tömören, ugyanakkor elegendő mélysében tárja elénk a módszer lényegét. A teljes leírás végéig még én sem jutottam el, a tervem az, hogy a fordítással párhuzamosan próbálom a rendes anyagot is emészteni. Most csütörtök éjjel van, már eléggé fáradt vagyok, kíváncsi vagyok mikorra végzek! Csapjunk tehát a lecsóba, innentől kössétek fel gatyát:

[...]

Nézzük a támadás részleteit! Ez egy "felfegyverzett" NULL pointer támadás, ami önmaga (pontosabban a Flash virtuális gép) ellen fordítja a bájtkód-ellenőrzőt, hogy veszélyes ActionScript kódot csempésszen a Flash futásába. Ha nem vagy egy exploit-gyáros, képzeld el így a dolgot: volt a Super Mario Brothersnek egy őrült változata, amit a Japánok nem akartak az Egyesült Államokba szállítani mondván, hogy az túlzottan felhergelné az amcsikat. Ez az exploit azzal a sráccal egyenértékű, akik hibátlanul végigviszi a játékot a YouTube-on.

De ezt tegyük félre egy kicsit.

Nézzük a sebezhetőséget:
Ez egy integer túlcsordulás, de nem az egyszerűbb fajtából.

Amikor a Flash futás közben színtér[?] adatokat olvas be egy SWF fájlból, van egy numerikus mező, amit méretellenőrzéskor előjeles számként értelmeznek, viszont utána előjel nélküliként használnak. Szóval a mező egyes értékekeknél az ellenőrzés pillanatában kicsinek és ártatlannak tűnik, valójában viszont hatalmas értéket tartalmaz.

Egy ehhez hasonló integer túlcsordítás általában egy strncpy vagy memcpy méretellenőrzését átejtve ráveszi a programot, hogy mondjuk 1k helyett 2 mega adatot szórjon szanaszét a folyamat memóriaterületén. De nem itt. Helyette a Flash ezt a rakoncátlan számot használja a lefoglalandó bájtok számontartására.

Ha arra kéred a Flash-t, hogy ugyan már, allokáljon néhány giga memóriát egyszerre, a foglalás meghiúsul, és NULL-t ad vissza. Ha ezt a NULL címet használod, a program összeomlik. Mindig ez történik. Sok fagyás vezethető vissza a NULL pointerekre. És mivel (általában) semmi nem lakik a NULL-on, a NULL pointeres összeomlások általában megfelelnek annak, hogy "Nem Kihasználható".

Csak nem most. A Flash elfelejti ellenőrizni a memóriafoglalás sikerességét, ez egy nevetségesen gyakori hiba. A visszakapott pointert viszont egy támadó által meghatározott eltolással használja. A NULL nem érvényes. A NULL+1024 nem érvényes. De a NULL+0x8f71ba90 az, mint ahogy minden NULL+N érték, amiben az N érvényes memóriát címez.

Erre a címre - amit a támadó szabályoz - a Flash egy olyan értéket tesz, amit szintén a támadó határoz meg. Ez a write32 minta: egy sebezhetőség, ami megadja a támadónak a lehetőséget, hogy a memória bármely értékét megváltoztassa egy neki tetszőre. Vége a játéknak.

Vagyis nem egészen.

Az exploit valójában nem a 0-tól meghatározott távolságú bytera lép. Feltételek egy bonyolultabb halmaza határozza meg a címet ahova ír, és azt is, hogy mit ír oda.

A tényleges írás egy struktúra-eltoláson keresztül valósul meg. A Flashbe bele van drótozva, hogy az eltolásodat egy másik számmá fordítsa. Mint kiderült, a működő eltolások nagyobbak 0x80000000-nál, és 4-et hozzájuk adva oszthatók 12-vel. Megjegyzés: és én még azt hittem kemény vagyok, amikor kisbetűk használata nélkül írtam IMAP exploitot shellkódban még a '90-es években...

Ez nem minden. Az érték, amit a Flash az adott címre ír sincs teljesen a támadó irányítása alatt. 16-bites egészről 32 bitesre kasztolódik, egy másik értéket pedig levonnak belőle. Ez volt az a ponja a jelentésnek, amikor menthetetlenül elkezdtem vihogni, totál hülyét csinálva magamból a kávézóban.

Ennek a szokatlan viselkedésnek az az eredménye, hogy nehéz úgy eljárni, mint egy write32 sebezhetőség esetében szokás, nevezetesen, hogy kiütjük egy függvény címét egy pointerrel, ami visszamutat a pufferre, így a shellkód hívodik meg, amikor a kiütött függvényt hívják. Így Dowd exploitja más irányból közelíti meg a dolgokat, és inkább az ActionScript bájtkódot manipulálja.

Na igen, az ActionScript bájtkód, ejtsünk néhány szót róla: Az ActionScript egy JavaScript, ami a Flash animációkat vezérli.  De a Flash által használt JavaScript elég kifinomult, a teljesítménynövelés érdekében a JavaScriptet egy, a virtuális gép (Virtual Machine - VM) számára elfogadható bájtkóddá alakítja. Egy bájtkód VM számára az ActionScript elég szoros, a futásidejű stackjét a processzor futási stackjében tárolja. A memória, ahonnan a kód futtatásra kerül tehát ugyanaz, mint ahol a Flash C kódja nyilvántartja saját állapotát.

Az ActionScript egy regiszter-alapú VM, ami annyit jelent, hogy bájtkódjának legnagyobb része azzal foglalatoskodik, hogy ki- és bepakol értékeket a memóriarekeszekből/be, melyek a virtuális processzor regisztereit jelképezik. Ezek a regiszterek a futásidejű stackben laknak, és indexeléssel hozzáférhetők. Ez pedig azt jelenti, hogy egy rosszindulatú Flash bájtkód a rendszer stack tetszőleges helyére be tudja léptetni magát. Vége a játéknak.

Vagyis nem egészen.

Nem tudsz csak úgy rosszindulatú kódot injektálni.

A Flash lejátszóknak közvetlenül a weboldalakról származó bájtkódokat kell futtatniuk, ezeket pedig legtöbbször gengszterek [szervezett bűnözők ;)] irányítják. Így a Flash nem futtat le tetszőleges bájtkódot, először ellenőrzi azt. Az ellenőrzés garantálja, hogy a bájtkódból csak érvényes regisztermezőkhöz férünk hozzá.

De. Teljesítmény okokból, a Flash VM két lépcsős rendszerré van bontva, mely egy, a bájtkód érvényességét ellenőrző részre (Az-ellenőrzés-ideje) és egy végrehajtó részre (A-használat-ideje) van osztva. A bájtkód feldolgozása eltér a két részben. Így nézünk ki:

  • Az ellenőrző figyelmen kívül hagyja a nem használt bájtkódot
  • Az ellenőrző egy memóriában lévő táblázat segítségével nyilvántartja minden egyes bájtkód utasítás hosszát
  • Ez a táblázat a NULL pointer felülírással elérhető
  • A végrehajtó ettől teljesen különböző feldolgozást használ

Cseréld ki a megfelelő értéket a hossz-táblázatban, és írhatsz egy nem használt bájtkódot, ami sokkal hosszabbnak látszik, mint amilyen valójában. Az extra bájtok átcsúsznak az ellenőrzésen. A futtató résznek viszont fogalma sincs arról, hogy a használaton kívüli részt még követik bájtok. Ha pedig ezek érvényes bájtkódot alkotnak, a Flash lefuttatja őket. Ellenőrizetlenül. Hozzáférést engedve a teljes stackhez. Vége a játéknak.

Vagyis csak majdnem.

A Koopa kagyló a második platformon csapda, ha hozzáérsz, meghalsz.

Ok, valójában nincs tovább. Dowd exploitja NULL pointer write32-vel leveri a lakatot a Flash bájtkód interpreteréről, így az SWF-je olyan kódot tud futtatni, ami felülírja a rendszer-stacket.

De csak azért, hogy az arcunkba dörgölje, vagy mert ez természetesen jön, ha szerető szülők helyett a SkyNet zabolázatlan szuperszámítógép-clusterei neveltek fel, Dowd új akadályokat állított maga elé.

Csak a szellemi kihívás miatt: Dowd e exploitjának meg kell törnie a Flash futását, újra kell írnia azt, hogy lefusson Dowd kis trójai programja, majd futnia kell tovább, mintha mi sem történt volna. Azaz:

  • A módosítások az ellenőrzésben nem ronthatnak el meglévő utasításokat
  • A bájtkódjának az értékeket a stackre kell mentenie, ahelyett, hogy valami más helyére tenné őket
  • A kód egyes részeinek Flash bájtkódként és első szintű x86 shellkód bootként is futnia kell
Két vicces részlet:

Először is: bár az IE és a Firefox teljesen más Flash buildeket használ, a címzésük kompatibilis. az exploit mindkét helyen működik.

Másodszor: a Flash-t nem ASLR-el fordították. Tehát az exploit Vistan is [a papír szerint pedig kis módosításokkal akár Unix-like rendszereken is] működik.

Eddig tartott a móka mára - meg tegnapra, ugyanis mindjárt hajnal egy az óra, de azt hiszem, hogy ebbe megérte befektetni ezt az energiát.

Címkék: flash bug hardcore skynet super mario brothers

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.

noss 2008.04.17. 20:12:16

gratulálok, szép fordítás.
tanulságos, megérte a melót! :)