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

CVE-2012-0056 - Lerajzoltam

2012.01.25. 18:43 | buherator | 6 komment

A HUP-on már rendkívül szórakoztató eszmecsere alakult ki a legújabb Linux kernel jogosultság-kiterjesztés sebezhetőséggel kapcsolatban, én igyekeztem megállni a szócséplést, amíg legalább nagy vonalakban megértem, hogy miről is van szó :) A probléma részleteivel kapcsolatban remek összefoglaló olvasható Jason A Donenfeld blogján, én is ezt tanulmányoztam, és az alábbi összefoglaló is ez alapján születik.

Top-down megközelítéssel a probléma a 2.6.39-es Linux kernelben került bevezetésre, Linus múlt héten commitolta a javítást. Ez előtt a verzió előtt egy #ifndef kigyilkolta a sebezhető mem_write() függvényt még mielőtt lefordult volna. Ez a függvény a folyamatok memóriaterületének írását teszi lehetővé a /proc/<pid>/mem-en keresztül. A kernel 2.6.39-es változatának kiadásakor úgy gondolták, hogy a mem_write()-ba bevezetett ellenőrzések megakadályozzák a lehetőség rosszindulatú kihasználását - tévedtek (Linus szavaival: "the /proc/<pid>/mem handling really isn't very robust" :)

A csibészkedést két ellenőrzés hivatott megakadályozni, ezek közül az első azt garantálja, hogy egy folyamat csak a saját memóriaterületét írhatja. Ennek a megkerüléséhet első körben érdemes elolvasnunk az exec() manualját, ami úgy indít, hogy "[Ez a függvénycsalád] lecseréli az aktuális folyamat image-ét egy új folyamatéra". Vagyis egy SUID root binárist exec()-elve annak a memóriaterületére írhatnék, ami nekem nagyon jó lenne. Erre egy elegáns megoldás a su használata, ami megteszi azt a szívességet, hogy stderr-re egy az egyben kirakja a neki átadott érvénytelen paramétereket. A hibakimenetet egy megfelelő helyre pozicionált, /proc/self/mem-re mutató fájlleíróba irányítva öröm lesz és boldogság. 

Azaz csak lenne, ugyanis van még egy ellenőrzés, ami a folyamathoz rendelt self_exec_id változó értékét ellenőrzi. Ez az érték minden egyes exec()-re egyel nő, az ellenőrző rutin pedig azt vizsgálja, hogy a memória fájlleíróját megnyitó folyamat self_exec_id-ja megegyezik-e az azt írni kívánó folyamatéval. Az előző megoldásban a su folyamat id-ja tehát magasabb lesz a leírót létrehozónál, így bukta van.

Azonban ez a korlátozás megkerülhető a feladatok "párhuzamosításával":

Először is forkoljuk magunkat, az így kapott gyerek folyamat self_exec_id-ja meg fog egyezni a miénkkel. A gyerek folyamatban hívjuk az exec()-t, amivel létrehozzuk a fájlleírót a szülő folyamat memóriájára - ezt megtehetjük, az open() ugyanis mindig engedélyezett. Ha a szülő folyamat exec()-eli a shellkódot kiköpő su-t, a fájlleírót létrehozó folyamat és a su self_exec_id-ja meg fog egyezni! A gyerek folyamat szépen visszadja a létrehozott leírót a szülőnek, aki ennek birtokában megcsinálhatja az stderr megfelelő átirányítását, így a su végül önkéntelenül beletúr a saját memóriájába.

Magátólértetődő választás a shellkódot a su exit()-jének helyére írni, hiszen ez gyakorlatilag közvetlenül a hibaüzenet (shellkód) kiírása után meg is hívódik. Probléma akkor van, ha a su-t pozíciófüggetlennek (-PIE) fordították, így a kernel alkalmazza rá az ASLR-t, mi meg nem tudjuk, hova kell írni. A népszerű disztrók többségénél ez azonban úgy tűnik, nincs így, és a szerencsésebb esetekben (SUSE?) is elképzelhető, hogy lehet találni más megfelelő SUID állományt, vagy a nyers erőhöz lehet fordulni. 

Az érintett/javított disztrókról sajnos még nem találtam rendes listát. Remélem nem néztem be semmit, ha mégis, kommenteljetek, javítok! ;)

Friss: Az exploitokat meg majdnem elfelejtettem :)

Címkék: linux bug kernel mempodipper

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.

eax_ 2012.01.25. 19:52:22

Egy pici pontatlansag:
"Eközben a szülő folyamat exec()-eli a shellkódot kiköpő su-t, így a fájlleírót létrehozó folyamat és a su self_exec_id-ja meg fog egyezni! Végül a gyerek folyamat szépen visszadja létrehozott leírót a szülőnek, aki ennek birtokában megcsinálhatja az stderr megfelelő átirányítását, így a su végül önkéntelenül beletúr a saját memóriájába."

A szulo meg az elott kapja meg az fd-t, es csinalja meg az atiranyitast, hogy atexecelodne su-ba, utana ez mar relative nehez. :)

buherator · http://buhera.blog.hu 2012.01.25. 19:59:24

@eax_: Kösz, jogos, igyekszem javítani hamarost!

EQ · http://rycon.hu 2012.01.25. 21:49:58

off: miben rajzoltad az ábrát, kérlek írd le a progi nevét, hasonlót keresek. Köszi

Hunger 2012.01.26. 10:14:58

LWN: "The fix was made by Linus Torvalds and went into the mainline on January 17, though with a commit message that obfuscated the security implications—something that didn't sit well with some."

Ezt is megértük. :)