Egy igen érdekes "lehetőség" látott napvilágot még a múlt héten, ami több platformon is jogosultságkiterjesztést tesz lehetővé a 64-bites Intel processzorok egy tulajdonságát kihasználva. A probléma érinti a Windows egyes változatait, a FreeBSD-t, a NetBSD-t, a Xen hypervisort, és a lista még bővülhet. A Linux kernelben 6 éve szépen csendben javították a problémát...
De miről is van szó? A Xen blogposztjában jó összefoglalót kapunk a sérülékenység részleteiről, ínyenceknek a HUP-os flame-et ajánlom :)
Mindenek előtt azzal kell tisztába kerülnünk, hogy az AMD mérnökei a laptábla szintek csökkentése érdekében nem használtk ki a teljes 64 biten megcímezhető memóriatartományt, hanem definiáltak egy 48-bites, ún. kanonikus címteret. A kanonikus címek 48-63. bitjeinek értéke meg kell hogy egyezzen a 47-el, így két érvényes virtuális címtartományt kapunk a 0x0000000000000000-0x00007fffffffffff és 0xffff800000000000-0xffffffffffffffff címek között.
A problémát az okozza, hogy a privilegizált rendszerhívásokból történő visszatérést megvalósító SYSRET utasítás AMD-étől eltérő implementációját nem vették figyelembe az érintett szoftverekben. Az utasítás hatására a processzor visszatölti a user-módból elmentett utasításszámláló (RIP) értékét, visszaállítja a felhasználó memória szegmensét, emellett az operációs rendszer kernele (illetve a hypervisor) visszaállítja a környezet maradékát, például a stack pointert is.
Gond akkor van, ha a visszaállítandó RIP nem-kanonikus címet tartalmaz (pl. mivel a rendszerhívás a kanonikus tartomány végén történt meg user-módban). Ekkor a CPU General Protection Fault-ot generál, méghozzá Intel CPU esetén még privilegizált módban. Mivel ekkorra már a kernel visszaállította a user-módból lementett stack pointert, a GPF kezelő a felhasználó által meghatározott címet fogja veremnek használni a továbbiakban. Ilyen módon, kihasználva, hogy a felhasználói mód regiszterei is a stackre kerülnek, gyakorlatilag tetszőleges privilegizált írás hajtható végre tetszőleges memóriaterületre, de más kihasználási lehetőségek is elképzelhetőek lehetnek.
Köszönet Hungernek a videóért, és poszt lektorálásáért!
|Z| 2012.06.25. 22:34:25
Hunger 2012.06.26. 08:36:52
brutueforce 2012.06.26. 11:10:48
Hunger 2012.06.26. 19:53:45
0x0000000000000000-0x00007fffffffffff: tipikusan a userland számára fenntartott terület
0xffff800000000000-0xffffffffffffffff: pedig a kernelé.
A közötte lévő címek nem kanonikusak, azaz:
0x0000800000000000-0xffff7fffffffffff között.
bármelyik címre visszatérve ezek közül a SYSRET másképp viselkedik az Intel processzorokon és még ring0-ban váltja ki a GPF megszakítást, amelyre az oprendszerek kernelei nem voltak felkészítve és emiatt a már visszatöltött ring3 userland alkalmazás regiszterkészletét használják fel a kernel GPF kezelőben, amelyik kiválóan kontrollálható támadást tesz lehetővé (igaz, rendkívül alacsony szinten és különösen kényes helyen, de a proaktív biztonsági megoldásokat nem alkalmazó rendszereken bőven van lehetőség a hiba kihasználására).