Post-SP2 Windows XP heap'as ir jo pažeidžiamumai
Povilas Tumėnas, 2006-11-13 14:09:09

Manau verta pradėti nuo to kas šiame straipsnyje rašoma ir kam jis skirtas. Čia aprašoma post-SP2 Windows XP heap‘ų „viduriai“, apsaugos, bei pažeidžiamumai. Post-SP2 XP versija pasirinkta dėl to, jog su SP2 Microsoft realizavo naujus apsaugos mechanizmus ir žymiai apsunkino su heap‘u susijusių pažeidžiamumų išnaudojimą. Windows 2003 SP1 ir Windows XP SP2 heap‘ų apsaugos yra beveik identiškos, todėl viskas kas čia bus aprašyta gali būti taikoma ir 2k3 operacinei sistemai.

Na šis straipsnis skirtas daugmaž labiau pažengusiesiems, tiems kurie turi patirties atbulinėje inžinerijoje, pažeidžiamumų išnaudojime ir bent kiek išmano NT šeimos operacinių sistemų vidurius. Be to, šis straipsnis nėra pamoka kaip rašyti heap‘o pažeidžiamumus išnaudojančius exploitus, čia aprašoma tik teorija ir tik tai kas susiję su pačiais heap‘o realizacijos pažeidžiamumais, todėl nerasit čia kaip ką nors perpildžius perimti valdymą ar paleisti jūsų shellkodą. Skanaus.

Heap‘o apibrėžimas

Visų pirma reikėtų apibrėžti heap‘o sąvoką, taigi heap`as yra duomenų struktūra naudojama dinamiškam atminties valdymui. Tradiciškai operacinės sistemos turi heap‘o realizaciją, ne išimtis ir Windows NT šeimos sistemos. XP SP2 sistemoje egzistuoja daug įvairių API‘ių įvairių heap‘ų valdymui, tačiau visi jie tėra apvalkalai pagrindinėms Rtl...Heap() šeimos funkcijoms realizuotoms ntdll.dll bibliotekoje. Šios funkcijos bendrauja su branduolyje esančiu virtualiosios atminties tvarkytojo komponentu (angl. „virtual memory manager“ ).

Supaprastinta Win32 heap‘o realizacijos struktūra.

Žiūrint iš žemo lygio požiūrio taško pats heap‘as tėra atminties gabalai valdomi virtualios atminties tvarkytojo.

Toliau kalbėsime tik apie vadinamąjį Win32 heap‘ą, o tai verta paminėti dėl to, jog Windows operacinės sistemos programos kartais naudoja trečiosios šalies heap‘us kurie, pavyzdžiui, išskiria virtualiąją atmintį patys ir naudoja vidinius mechanizmus atskirai heap‘o realizacijai. Kai kurių kalbų vykdomosios bibliotekos irgi turi savas heap‘ų realizacijas, nors, pavyzdžiui, C vykdomoji biblioteka (CRT) naudoja Win32 heap’ą, tačiau valdydama atmintį ji prideda prie jos papildomą informaciją, tarkim jei yra kviečiama funkcija malloc(), ji iškviečia funkciją HeapAlloc() ir išskiria truputį daugiau atminties nei yra prašoma į kurią yra įrašomos papildomos struktūros vidiniam valdymui.

Heap‘o dizainas

Kiekvienas procesas Windows operacinėje sistemoje gali turėti kelis heap‘us, tačiau vienas heap‘as kiekvienam procesui yra sukuriamas bet kokiu atveju. Proceso heap‘ai yra surašyti to proceso PEB („Process Environment Block“). PEB tai vartotojo režimo (angl. „user mode“) atmintyje esanti struktūra kurioje saugomi globaliniai tam procesui, sistemos nustatyti kintamieji. Pažiūrėkim kaip atrodo PEB iš arčiau. Tam mes naudosime WinDbg, puikų, nemokamą Microsoft derintuvą (angl. „debugger“) (parsisiųsti jį galite iš microsoft.com, arba į mėgstamą paieškos variklį įrašykit WinDbg ir pirmas rezultatas turėtų būti WinDbg tinklalapis iš kur jį ir galėsit parsisiųsti). Iškart paminėsiu, jog WinDbg čia tėra naudojamas tik keliose vietose ir jo siųstis visiškai nebūtina, nes viskas ko reikia yra aprašyta, tačiau jei norit patys pasižiūrėt ar nemeluoju, tada galit siųstis. Parsisiuntus ir įdiegus jį, reikės susikonfigūruoti simbolius. Tam padaryti užtenka WinDbg programoje įvesti į File -> Symbol File Path , Symbol Path, šią eilutę:

srv*c:\symbols*http://msdl.microsoft.com/download/symbols

Kuri reiškia, jog simboliai esant reikalui bus automatiškai parsiunčiami iš Microsoft simbolių serverio ir saugomi paryškintoje direktorijoje, todėl jei norite, kad simboliai būtų saugomi kitur, paprasčiausiai pakeiskit paryškintą vietą. Nenustebkit jei iš pradžių įvedus kokią nors komandą atrodys, jog WinDbg pakibo, tuo metu bus siunčiami reikalingi simboliai. Be to, ši eilutė greičiausiai būna įrašyta pagal nutylėjimą (nesu tikras, nes gana seniai įdiegiau WinDbg, todėl jei rasite ją įrašytą paprasčiausiai palikit ją ramybėje arba paredaguokit direktoriją pagal savo pageidavimus). Simbolius galima siųstis ir rankiniu būdu, tačiau rekomenduočiau nustatyti automatinį siuntimą. Jei vis dėl to nenorit, kad WinDbg bendrautų su Microsoft serveriais kiekvieną kartą paleidus jį, teks konsultuotis su WinDbg dokumentacija, kuri tiesą sakant yra tikrai geros dokumentacijos pavyzdys, todėl jei iškils kokių klausimų susijusių su šiuo derintuvu patarčiau pirmiausia pavartyti dokumentaciją, nes ten aprašyta viskas nuo A iki Z ir dar daugiau. Na jei viską atlikot tai įsijungiam vietinį branduolio derinimą (File -> Kernel Debug -> Local , OK) ir sugrįžtam prie PEB.

Norėdami pažiūrėti kokį nors tipą ar struktūrą galime tai padaryti naudodami komandą dt („display type“).

Komanda dt ntdll!_PEB (paveikslėlyje pažymėta melsvai) parodo struktūrą _PEB esančią ntdll modulyje. Mums šioje struktūroje tėra įdomūs paryškinti laukeliai:
ProcessHeap – pagal nutylėjimą sukurto heap‘o adresas.
NumberOfHeaps – heap‘ų skaičius procese.
ProcessHeaps – nuoroda į nuorodų, į procese esančius heap‘us, masyvą.
Kaip atrodo pati heap‘ą apibrėžianti struktūra. Sekančiame paveikslėlyje ji ir pavaizduota, taip pat pavaizduotas ir svarbesnių heap‘o struktūrų išdėstymas. Taigi, heap‘o viduriai:

* Visų pirma paminėsiu kas tai per struktūros _LIST_ENTRY ir _SINGLE_LIST_ENTRY, kurios yra minimos ir bus minimos dar daugelį kartų, o tai tėra dvigubai ir viengubai sujungti sąrašai atitinkamai. Na pirma struktūra sudaryta iš dviejų nuorodų, o antroji iš vienos ir iš jų sudaromi sąrašai. Tikiuos turit programavimo pagrindų ir bent jau numanot kas per daiktas yra sąrašai.

Ši struktūra ir jos substruktūros, taip pat kaip ir PEB, niekur nėra oficialiai aprašytos, remiuosi tik atvirkštinės inžinerijos specialistų straipsniais, aprašymais ir t.t., kurių sąrašas yra pabaigoje, bei savo tyrinėjimais. Todėl kai kuri informacija gali būti ne visai tiksli arba gali būti pasikeitusi, nes niekas negarantuoja, jog Microsoft nepakeis vidinių struktūrų su kokiu nors eiliniu atnaujinimu.
Į pačią heap‘o struktūrą per daug nesigilinsime, aprašysiu tik kai kuriuos jos elementus (parodytus vizualiai paveikslėlyje), kurie reikalingi heap‘o veikimo supratimui. Pradėsim nuo virtualių išskyrimų sąrašo.

Virtualių išskyrimų sąrašas

Šiame dvigubai sujungtame sąraše saugomi virtualiai išskirtų atminties gabalų adresai. Jei išskiriant atmintį, na, pavyzdžiui su HeapAlloc, išskiriamos atminties dydis yra didesnis arba lygus 512 kb (turėkit omeny, jog čia kilobitai, o ne baitai) yra apeinamos heap‘o funkcijos ir išskiriama paprasta virtualioji atmintis ir tas atminties gabalo adresas įdedamas į šį sąrašą.

Segmentai

Tai _HEAP_SEGMENT tipo struktūros, apibūdinančios išskirtus virtualios atminties gabalus, kurie yra paskui naudojami heap‘o atminčiai, t.y. ta išskirta atmintis yra naudojama įvairiems kintamiesiems, heap‘o struktūroms, bei išskirtiems heap‘o gabalams laikyti (angl. „chunks“, apie gabalus kalbėsime vėliau, tačiau verta paminėti, jog tai jau nebe virtualiosios atminties, o heap‘o gabalai, aišku tai tik virtualiosios atminties abstrakcija, bet tai jau heap‘o gabalai kuriuose yra saugomi duomenys patalpinami heap‘o naudotojo). Pagal nutylėjimą kiekvienam procesui pasileidžiant jo heap‘e sukuriamame pagal nutylėjimą yra išskiriama 1 MB atminties. Šis skaičius nustatomas iš PE failo galvutės, jį dažniausiai galima pakeisti linkerio pagalba, arba rankomis modifikuojant PE failą. Segmentai skirti tam, jog kiekvieną kartą kam nors bandant išskirti atmintį iš heap‘o, jam nereikėtų kviesti virtualios atminties funkcijų, nes atmintis jau būna išskirta. Jei jos pritrūksta tada jau tenka kreiptis į virtualios atminties funkcijas ir išskirti dar atminties segmentams.

FreeList masyvas

Šis masyvas prasidedantis 0x178 baitai nuo _HEAP struktūros pradžios yra sudarytas iš 128 _LIST_ENTRY struktūrų, t.y. tai 128 dvigubai sujungti sąrašai. Juose saugomi laisvų heap‘o gabalų adresai. Saugomų gabalų dydis atitinka dvigubai sujungto sąrašo kuriame jis saugomas indekso FreeList‘e numerį padaugintą iš aštuonių. Tarkim FreeList[20] sąraše yra saugomi 20 * 8 = 160 baitų dydžio gabalai. Šiai taisyklei yra tik viena išimtis, FreeList masyvo nuliniame elemente (FreeList[0]) saugomame dvigubai sujungtame sąraše yra gabalai kurių dydis yra nuo 1024 baitų iki 64 kilobaitų.

FreeList masyvas.

Mažomis raidėmis parašyti Flink ir Blink tai _LIST_ENTRY struktūros nariai. Flink („Forward link“) - nuoroda į toliau einantį dvigubai sujungto sąrašo narį ir Blink – („Backward link“) nuoroda į prieš tai esantį sąrašo narį.

LookAside masyvas

128 viengubų sąrašų masyvas. Sukuriamas tik tada jei sukuriant heap‘ą būna nenustatyta HEAP_NO_SERIALIZE (ši vėliavėlė būna nenustatyta pagal nutylėjimą) ir nustatyta HEAP_GROWABLE vėliavėlės (ši vėliavėlė būna nustatyta pagal nutylėjimą heap‘ui, kuris yra sukuriamas pagal nutylėjimą, o kuriant atskirą heap‘ą ją galima nustatyti tik padavus nulį HeapCreate funkcijos dwMaximumSize parametrui). Iš pradžių LookAside būna tuščias. Jame saugomi užimti (angl. „busy“), ne didesni nei 1016 baitų, heap‘o gabalai, kurie buvo atlaisvinti, tačiau liko pažymėti užimtais, t.y. auga tada kai atlaisvinama atmintis. Naudojamas greitiems išskyrimams ir atlaisvinimams. LookAside sąrašų „gylis“ t.y. kiek elementų būna sąraše yra limituotas ir nuolat kinta priklausomai nuo atliekamų išskyrimo/atlaisvinimo operacijų gausos. Visas tai daroma norint pagreitinti smulkių gabalų išskyrimą/atlaisvinimą.

LookAside masyvas.

Gabalai (angl. „chunks“)

Atmintis iš heap‘o išskiriama gabalais. Heap‘o gabalas susideda iš galvutės ir duomenų.

Heap‘o gabalai.

Manau paveikslėlyje atvaizduojama viskas ką reikia žinoti apie heap‘o gabalus, be to visus svarbesnius elementus paaiškinsiu tada kai prireiks, todėl einam toliau.

Algoritmai

Šiame skyriuje aprašomi atminties išskyrimo/atlaisvinimo ir sujungimo algoritmai. Aprašymai nėra labai tikslūs ir smulkmeniški, nes tie algoritmai tikrai nėra paprasti, be to juk jie nėra dokumentuoti, todėl pilna analizė užtruktų labai daug laiko.

Išskyrimas

1. Jei išskiriamos atminties dydis didesnis arba lygus 64 kB, atmintis išskiriama panaudojant virtualios atminties funkcijas.
2. Jei išskiriamos atminties dydis mažesnis nei 1024 baitai atliekami šie veiksmai:
2.1 Jei egzistuoja LookAside sąrašas pirmiausiai yra tikrinamas jis. Jei atmintis randama ji išskiriama ir gabalas išimamas iš LookAside sąrašo.
2.2 Jei nerandama atminties LookAside sąraše arba jo nėra tada tikrinamas FreeList sąrašas kuriame laikomi tiksliai tokio dydžio gabalai kaip to kurio yra prašoma išskirti. Jei tas sąrašas nėra tuščias atmintis išskiriama ir gabalas išimamas iš sąrašo.
2.3 Jei tiksliai tokio dydžio kurio yra prašoma išskirti sąrašas yra tuščias, tikrinami didesnius gabalus laikantys sąrašai, jei ten randamo gabalo dydis yra 16 baitų didesnis nei išskiriamos atminties dydis, jis skeliamas į dvi dalis, atmintis gražinama vartotojui, o likutis yra gražinamas gabalo pavidalu į FreeList‘ą.
2.4 Jei nerandama nei LookAside nei FreeList sąrašuose (išskyrus FreeList[0]) yra ieškoma heap‘o keše (kešas nebuvo paminėtas prie heap‘o struktūrų, nes ši struktūra nėra dažnai naudojama, ji sukuriama tik tada jei trumpam dažnai naudojami heap‘o gabalai didesni už 4kB ir yra panaši į FreeList‘ą tik skirta didesniems gabalams).
3. Jei gabalas didesnis nei 1024 baitai, bet mažesnis nei 64 kB ar jei atmintis nebuvo rasta atlikus veiksmus antrame punkte, tikrinamas FreeList[0], jei ten yra randamas gabalas, jis yra skaldomas taip pat kaip 2.3. punkte, o jei tinkamas gabalas nerandamas ir heap‘as yra „augantis“ t.y. yra nustatyta vėliavėlė HEAP_GROWABLE, tada yra išskiriama papildoma atmintis ir sukuriamas naujas/i segmentai.

Atlaisvinimas

1. Jei atmintis yra išskirta virtualiai ji gražinama operacinei sistemai.
2. Jei atmintis neišskirta virtualiai, yra mažesnė nei 1024 baitai, egzistuoja LookAside masyvas ir jis nėra pilnas tai paliekama vėliavėlė HEAP_ENTRY_BUSY ir to gabalo adresas įrašomas į atitinkamą LookAside sąrašą.
3. Jei nėra LookAside masyvo/jis pilnas ar jei gabalo dydis didesnis nei 1024 baitai tai tikrinama ar nėra šalia kitų laisvų gabalų, jei yra, tie gabalai sujungiami (kaip vyksta sujungimas bus aprašoma toliau) ir gautasis gabalas yra įdedamas į atitinkamą FreeList‘o sąrašą, jei šalia nerandama laisvų gabalų atlaisvinamas gabalas įdedamas į FreeList‘ą.

Sujungimas

1. Atlaisvinant atmintį, kaip ir minėta ties trečiu punktu atlaisvinimo algoritmo aprašyme, yra tikrinama ar prie atlaisvinamo gabalo nėra laisvų gabalų.
2. Radus šalia esantį gabalą tikrinama:
2.1 Ar gabalas nėra užimtas (angl. „busy“)?
2.2 Ar bendras dydis sujungus gabalus nebus didesnis nei 64 kB?
3. Jei susijungimas gali vykti, tai šalia esantis laisvas gabalas išimamas iš FreeList‘o, gabalai sujungiami ir gautasis gabalas įdedamas į FreeList‘ą.

Heap‘ų pažeidžiamumai ir apsaugos

Dėl, manau, savaime suprantamų priežasčių aš neminėsiu visų heap‘o pažeidžiamumų ir jų tipų, o tik tuos kurie padės suprasti heap‘ų pažeidžiamumų esmę ir tuos kuriais galima apeiti SP2 egzistuojančias apsaugas.

4-baitų perrašymas

4-baitų perrašymas tai ataka kurios metu yra perrašoma reikšmė esanti jūsų pasirinktame 32 bitų adrese su jūsų pasirinkta 32 bitų reikšme. Įvykus heap‘o perpildymui, t.y. perpildžius kokį nors atminties gabalą yra perrašomos toliau atmintyje esančios struktūros, tarkim laisvas gabalas. Taigi įvykus perpildymui galima perrašyti šalia esančio laisvo gabalo galvutę. Išskyrus ar sujungiant tą perrašytą gabalą su kitu jis bus išimamas iš dvigubai sujungto FreeList sąrašo, tam įvykus bus atnaujinamos šalia esančių sąrašo narių rodyklės. Sufalsifikavę perrašyto gabalo galvutėje esančias rodykles, jį išimant iš sąrašo mes sukelsime 4 baitų perrašymą. Na nemanau, jog šiuo metu viskas aišku, todėl iliustruosiu šį veiksmą paveikslėliu.

4-baitų perrašymas.

Deja, viskas nebėra taip paprasta, ši technika puikiai veikdavo su ankstesnės nei SP2 versijos operacinėmis sistemomis, su SP2 Microsoft įdiegė kelias paprastas, tačiau gana efektyvias apsaugas apie kurias toliau ir kalbėsiu.

Apsaugos

Su SP2 atsirado dvi naujos apsaugos padedančios apsaugoti nuo pažeidžiamumų tiesiogiai išnaudojančių heap‘o dizainą, tos apsaugos tai saugus išėmimas iš sąrašo (angl. „safe unlinking“) ir heap‘o slapukai (angl. „heap cookies“).

Heap‘o slapukai

Apie šio tipo apsaugą pirmą kartą viešai buvo užsiminta 2003 metais, nepriklausomuose vienas nuo kito saugumo tyrinėtojų Y. Huang ir W. Robertson, C. Kruegel išleistuose straipsniuose. Microsoft pirmieji, iš OS gaminančių kompanijų, realizavo šio tipo apsaugą. Heap‘o slapukų esmė yra ta, jog heap‘o galvutėje būna patalpinama apsauginė 1 baito dydžio reikšmė (paveikslėlyje atvaizduojančiame heap‘o gabalus ji pažymėta kaip „slapukas“) kuri būna tikrinama prieš įvykdant tam tikras „nesaugias“ operacijas, tokias kaip gabalo išskyrimas. Bėda ta, jog apsauginė reikšmė tėra 1 baito dydžio, todėl tėra galimi 256 skirtingi tos reikšmės variantai, o tokį kiekį reikšmių gana nesunku „parinkti“ (angl. „brute-force“).

Saugus išėmimas iš sąrašo

Ši apsauga prieš išimant laisvą gabalą iš sąrašo tikrina ar išimamo sąrašo elemento nuorodos nėra perrašytos. Žiūrint į paveikslėlį „4-baitų perrašymas“ esant šiai apsaugai prieš išimant B gabalą iš sąrašo būtų atliekami šie patikrinimai:

B->Flink->Blink == B->Blink->Flink == B

Paprastai tariant, yra tikrinama ar C->Blink ir A->Flink nuorodos nurodo į gabalą B.

Be to, Microsoft siekdama sumažinti nuorodų skaičių per kurias būtų galima nukreipti vykdomo kodo eigą PEB adresą padarė pusiau atsitiktiniu (adresas išlieka tam tikrose ribose ir jį galima nuspėti), bei užkodavo UEF ir VEH nuorodas, tačiau tai nėra „grynos“ heap‘o apsaugos jos tik apsunkina kodo eigos nukreipimą, todėl į jas daugiau ir nesigilinsime.

Pažeidžiamumai

Realizavus apsaugas buvo atrasti keli nauji pažeidžiamumai vis dar atakuojantys pačią heap‘o realizaciją, o ne konkrečios programos struktūrą ir vidinę logiką. Tačiau tie pažeidžiamumai dažniausiai galimi tik keliose labai specifinėse situacijose, todėl, deja, dažniausiai belieka atakuoti programos struktūrą ir logiką. Taigi, šiuo metu egzistuoja dvi pagrindinės atakos kurios toliau ir aprašomos. Jums jau turint gana tvirtus heap‘o veikimo principų pagrindus pasistengsiu nesikartoti ir pažeidžiamumus aprašyti kuo trumpiau.

FreeList perrašymas nesaugiai išimant iš sąrašo (angl. „Un-Safe Unlinking FreeList Overwrite“)

Tai gana teorinė ir nepatikima ataka surasta Matt‘o Conover‘io ir pirmą kart paskelbta jo prezentacijoje „Windows Heap Exploitation“ kuri buvo pristatyta SyScan 2004 konferencijoje. Šios atakos pagalba galima perrašyti kai kuriuos FreeList‘o narius. Dėl jos menkavertiškumo per daug į ją ir nesigilinsime, nes ji kaip ir minėjau yra beveik teorinė, praktikoje ją panaudoti būtų tikrai nelengva. Norint atlikti šią ataką turi įvykti šios heap‘o operacijos:
(Jei LookAside neegzistuoja, 2 ir 4 žingsnius galit praleisti)
1. Išskiriamas n dydžio atminties gabalas A.
2. Užpildomas LookAside sąrašas.
3. Atlaisvinamas A.
4. Ištuštinamas LookAside sąrašas.
5. Pasinaudojant kokiu perpildymu ar dar kuom nors perrašomas A gabalas. Jis perrašomas taip:
5.1 Nustatoma vėliavėlė „Busy“ (tam, kad gabalas atsitiktinai nebūtų sujungtas).
5.2 A->Flink perrašomas su &FreeList[(n/8) + 1] – 4 (t.y. A->Flink perrašomas su FreeList‘o, kurio indeksas yra vienu mažesnis nei atlaisvinto gabalo dydžio FreeList‘o indeksas, Blink‘u).
5.3 A->Blink perrašomas su &FreeList[(n/8) + 1] + 4 (t.y. A->Blink perrašomas su FreeList‘o, kuriame saugomi A dydžio gabalai, Blink‘u).
6. Išskiriamas n dydžio atminties gabalas. Gražinama nuorodą į anksčiau atlaisvintą A gabalą, ji ignoruojama. Šiame punkte apeinamas saugus išėmimas, nes įrašytos nuorodos juk nurodo į mūsų laisvą gabalą, todėl išėmimas įvyksta ir išskiriamas tas gabalas.
7. Vėl išskiriamas n dydžio atminties gabalas A. Dėl anksčiau perrašytų laisvo gabalo A nuorodų ir įvykių išimant jį iš sąrašo, A dabar nurodo į &FreeList[(n/8) – 2].Blink. Jei jūs valdot sekančią atminties operaciją su gabalu A, tai galit perrašyti dalį FreeList‘o, o ką toliau darysit jau priklauso nuo jūsų.

Taigi, kaip matot ši ataka nėra labai praktiška, nes per daug jau veiksnių nuo kurių priklauso atakos sėkmė.

4-iki-n-baitų perrašymas perrašant LookAside gabalą (angl. „4-to-n-byte overwrite“ arba „Chunk-On-LookAside overwrite“)

Deja, tai irgi ne visai praktiška ataka. Ji buvo atrasta Alexander‘io Anisimov‘o 2004 metais ir paskelbta jo parašytame straipsnyje „Defeating Microsoft Windows XP SP2 Heap protection and DEP bypass“. Pasinaudojant šiuo heap‘o realizacijos pažeidžiamumu galima perrašyti iki 1016 baitų pasirinktos atminties. Ši ataka remiasi tuo, jog LookAside sąrašuose nėra saugaus išėmimo iš sąrašo, nes tai viengubas sąrašas, bei tuo, jog vykdant įvairias operacijas su LookAside gabalais nėra tikrinami heap‘o slapukai. 4-iki-n-baitų perrašymui įvykdyti reikia, jog įvyktų šios heap‘o operacijos:
(Manau tai, jog LookAside sąrašas turi egzistuoti turėtų būti savaime aišku, nes juk tai LookAside gabalų perrašymas..)
1. Išskiriamas n dydžio gabalas (n < 1016 baitų).
2. Šis gabalas atlaisvinamas, jis įrašomas į LookAside.
3. Perrašomas atlaisvinto gabalo Flink su norimu adresu.
4. Išskiriamas n dydžio gabalas, atnaujinant LookAside sąrašo nuorodas mūsų perrašytas Flink atsiranda sąraše.
5. Vėl išskiriamas n dydžio gabalas, gražinamas mūsų norimas adresas. Jei valdote sekančią atminties operaciją su išskirtu gabalu, galite perrašyti iki 1016 baitų atminties. Ką su ja darysit ir ką ten talpinsit jūsų reikalas.
Na kaip matote ši ataka taipogi nėra labai praktiška, tačiau ji praktiškesnė nei „nesaugus išėmimas“, be to Anisimov‘as teigia sėkmingai panaudojęs šį heap‘o pažeidžiamumą bent vienam heap‘o perpildymui išnaudoti.

Tai būtų visi pagrindiniai viešai žinomi SP2 heap‘o realizacijos pažeidžiamumai. Egzistuoja dar keletas technikų kurios atakuoja heap‘e dažnai esančias struktūras, tačiau tai jau ne heap‘o dizaino pažeidžiamumai ir tai jau yra virš mano straipsnio ribos.

Epilogas

Lengvų, jei taip juos būtų galima pavadinti, nes heap‘o pažeidžiamumai ir seniau nebuvo labai lengvai išnaudojami, heap‘o pažeidžiamumų išnaudojimo laikas, deja, jau baigėsi. Be to, Microsoft sukūrė naują, taip vadinamą „Žemo Susiskaidymo Heap‘ą“ („Low Fragmentation Heap“), kuris naudojamas gabalams mažesniems nei 16 kB, jis turi ir padidintas apsaugas – naudojami 32 bitų heap‘o slapukai, apsaugojamos sąrašų nuorodos. Tačiau jis beveik niekur nenaudojamas, todėl jo anksčiau ir neminėjau. Dabar belieka atakuoti nebe patį heap‘ą, o heap‘e esančias struktūras ir tikiuosi, jog susipažinus su heap‘o struktūrom ir veikimo principais, apie ką šis straipsnis ir stengėsi būti, bus lengviau tai padaryti.


Komentarai

Vardas:
Komentaras:

Copyright © 2005 - 2010, UAB „Critical Security“