Viimases Project Zero ajaveebi postituses on meeskond avastanud viisi, kuidas Samsungi reaalajas tuumakaitsest, mida nimetatakse Knox Hypervisoriks, mööda hiilida.
Google'i Project Zero meeskond on kontrollinud mitmeid ärakasutusi, mis võimaldavad rünnata Samsungi telefone, mis käitavad väidetavalt turvalist Samsung Knoxi turvakomplekti. Blogis märgitakse, et kõik haavatavused on edastatud Samsungile, kes on jaanuarikuu tarkvarauuenduses nende jaoks parandused välja andnud.
Taust
Samsungi kasutusele võetud Samsungi Knoxi turbetarkvarakomplekti osana on Androidi rakenduste ja tuuma vahel üks tarkvara, mida nimetatakse Hüperviisor. Seda saab kasutada täiendava kihina Android-seadmete turvalisemaks muutmiseks. Samsung Knox Hypervisor kannab nime "Reaalajas tuumakaitse" või lühidalt RKP, nagu ma sellele artikli ülejäänud osas viitan.
Kernel asub Androidi tarkvaravirnas RKP all ja seadmes töötavad rakendused asuvad ülaosas. RKP idee on pakkuda seadmele täiendavat turvakihti, kuna kõik päringud (mälu ja muud ressursid) on tehtud Kerneli rakendused peavad esmalt läbima Knoxi, mis püüab tuvastada, kas rakendus seda teeb ei peaks. RKP pakub ka turvalisust läbi varguse lisakihiga, et varjata tundlikku teavet, mida rakendus võib seadme kahjustamiseks kasutada.
Ajaveebi postituses käsitletakse üsna sügavalt Androidi mälu, RKP ja operatsioonisüsteemide toimimist üldiselt, nii et olen selle lühendanud ja lihtsustanud, et anda avastatust kiire ülevaade. Soovitan teil siiski kogu artiklit lugeda, kui teil on aega, kuna see on väga hariv.
Kasutus nr 1:
KASLR või Kerneli aadressiruumi paigutuse juhusliku muutmine on protsess, mille käigus muudetakse alglaadimisel kerneli koodi asukohta mälus juhuslikult. Iga kord, kui seade käivitatakse, laaditakse kernel erinevasse aadressiruumi (mälu piirkonda). Idee on raskendada tuuma koodi asukoha leidmist, et seda rünnata, sest pärast iga alglaadimist "nihkub" kerneli kood mälus juhuslikult. See kõlab suurepärase sammuna potentsiaalsete ründajate ärahoidmiseks, kuid hiljuti uurimine on näidanud, et saate sellest tegelikult jagu ilma tarkvaravea või haavatavuseta, kuna KASLR-i on kohalike ründajate vastu tegelikult väga raske jõuliselt rakendada.
RKP tarkvara puhul on KASLR-ist möödasõit tegelikult lihtsam kui ülal viidatud uurimistöö. Kõigi Android-seadmete mälule viidatakse osutitega ja seadmete kaitsmiseks rünnakute eest alati, kui Android-seadmed prindivad või väljastavad (kas ekraanile või logide või silumise failide jaoks), on viited viited anonüümseks muudetud, mistõttu on võimatu teada saada, kuhu kursor tegelikult viitab väljund.
Mõelge mäluviidatele nagu tänavasilt, mis osutab asukohale, ja mõelge anonüümseks muutmisele kui selle hägustamisele. Sarnaselt televisiooniga tehakse anonüümseks muutmine pärast filmimist, Android rakendab seda anonüümseks muutmist ka väljundi ajal ja ainult siis, kui anonüümseks muutmine on õigesti konfigureeritud ning autor väidab et iga seadme [ta] kohtas kursori anonüümseks muutmine õigesti konfigureeritud. See võib tunduda nii, et seda on väga raske murda, kuid peate vaid leidma ühe osuti (mõelge tänavasildile), mida ei muudetud anonüümseks (häguseks) kerneli arendaja poolt (ettevaatust, et see pole teie keskmine Androidi rakenduse arendaja), kui kursor on kirjutatud logidesse või muusse asukohta, nt. ekraan või a faili.
Nii et kui leiate kursori, mida ei muudetud anonüümseks, saate nende kahe erinevusena arvutada tuuma juhusliku aadressi nihke. Huvitaval kombel ei leidnud autor kernelist kasutatavat osutit, kuid leidis selle RPK-st kus arendajad unustasid silumise (logimise) väljundis oleva kursori anonüümseks muuta, mis tekkis kirjaviga. Osutajate anonüümseks muutmiseks Androidis peate kasutama spetsiaalset koodi ja selgub, et RPK arendajad kasutasid ekslikult väiketäht "k" asemel an suurtäht "K". Seetõttu oli suhteliselt lihtne välja selgitada tuuma koodi juhusliku nihke suurus ja seda rünnata.
Kasutus nr 2:
Järgmine ärakasutamine on veidi keerulisem: Samsung Knox kaitseb teie seadet, rakendades pahatahtliku koodi peatamiseks seadme mälule reegleid. Reeglid on järgmised:
- Kõik leheküljed (mälus olev kood), välja arvatud kerneli kood, on tähistatud kui "Privileged Execute Never" (see tähendab, et koodi ei saa kunagi käivitada)
- Kerneli andmelehti (programmi poolt mälus kasutatavaid andmeid) ei märgita kunagi käivitatavaks (seega ei saa siinset koodi kunagi käivitada)
- Kerneli koodilehti (mälus olev kood) ei märgita kunagi kirjutatavaks (nii et ükski pahatahtlik kood ei saa seda muuta)
- Kõik kerneli lehed on märgitud kirjutuskaitstuks 2. etapi tõlketabelis (tabel, mis asub rakenduse ja kerneli vahel, et takistada rakendustel tegelikke mäluasukohti teadma)
- Kõik mälutõlkekirjed on rakenduste jaoks märgitud kirjutuskaitstuks.
Keskendume 3. reeglile, kuna siin leidis autor ülaltoodud reeglite rakendamisel probleemi. Tegelikult märgib RPK kerneli mälu kirjutuskaitstuks, kuid KASL-i kõrvalekaldumise tõttu avastati auk, mis viis koodi kirjutamine väidetavalt "kirjutuskaitstud" jaotisesse. Kerneli asukoha alglaadimise ajal hägustamiseks eraldatakse tuumale mälu, kuid see mälumaht on palju suurem kui kerneli tekstisegment. Suurema mälumahu eraldamine muudab tegeliku kerneli koodi leidmise palju raskemaks, mis võiks olla ükskõik kus, ja nagu eespool nägime, liigutatakse seda juhuslikult seadme igal alglaadimisel.
Autor suutis kinnitada, et kerneli kasutatav mälu oli tõepoolest märgitud kui "kirjutuskaitstud", kuid ülejäänud suur osa tuuma peitmiseks kasutatud mälust oli mitte märgitud kui "kirjutuskaitstud". Seda seetõttu, et RKP kaitseb kerneli teksti sisaldavat piirkonda alles pärast KASLR-i slaidi rakendamist.
Kasutamine nr 3
Kolmandas ärakasutamises pääses autor juurde veel ühele mälupiirkonnale, mis peaks olema piiratud ka kirjutuskaitstud režiimiga. RKP kaitseb mälu ja kasutab a Hüpervisori konfiguratsiooniregister (HCR) tuuma põhitoimingute juhtimiseks. HCR-i eesmärk on võimaldada kehtivatel ja reaalsetel tuumatoimingutel juurdepääsu registritele ja blokeerida pahatahtlikud rünnakud. See teeb seda, kontrollides virtualiseerimisfunktsioone reguleerivatele registritele tehtud kõnesid. HCR on konfigureeritud blokeerima konkreetseid toiminguid, mida tavaliselt käsitletakse, võimaldades RKP-l valida, kas taotlus lubada või keelata.
Selles ärakasutamises oli HCR kontroll ei hõlma kahte registrit mis osutus väga oluliseks. Autor süvenes ARM Reference käsiraamatusse ja avastas, et esimene register võimaldas tal RKP rakenduste jaoks põhimõtteliselt välja lülitada. "Süsteemi juhtimisregister EL1 jaoks (SCTLR_EL1) pakub süsteemi, sealhulgas mälusüsteemi, tipptasemel juhtimistTäiuslikus maailmas kasutaks rakendus mälu, mis on kaardistatud RKP kaudu, et RKP saaks kontrollida, millele rakendus juurde pääseb. Selle registri väljalülitamine võimaldas aga RKP keelatakse tagastades seadme tõhusalt sellele, kuidas see töötas enne RKP installimist – see tähendab, et seade kaardistatakse füüsilisele mällu ilma RKP pakutava täiendava turvalisuseta. See omakorda tähendas, et autor sai lugeda ja kirjutada mällu, mis oli algselt ja korrektselt RKP tarkvara poolt blokeeritud.
Teisel registril, mis vahele jäi, oli peenem mõju, kuid lõppkokkuvõttes turvalisusele sama laastav. The EL1 tõlkekontrolli register (TCR_EL1) register on otseselt seotud mälumahuga, millega rakendus töötab, mida nimetatakse lehele. RKP on kõvakodeeritud lehekülje suuruseks 4 kb, kuna AARCH64 Linuxi tuumad (nt Android) kasutavad tõlke suurust 4 kB. Kõnealune register (TCR_EL1) seab ARM-kiibistikud tagastatava mälu suurusele. Selgub, et see register ei ole HCR poolt kaitstud ja seetõttu saab ründaja seda muuta, kuna autor muutis selle 64 kb lehekülje suuruseks.
See tähendab, et kui RKP taotluse täidab, on tegelik juurdepääsetav mälumaht nüüd 4kb asemel 64 kb. Põhjus on selles, et ARM-kiibistik kontrollib endiselt lehe suurust ja selle määras ärakasutamine 64 kb. Kuna RKP kaitseb mälu kirjutamise eest, on 2. kasutuses loetletud reeglite osana mälu tegelikult kaitstud. Kuid siin on konks – kuna RKP on kõvakodeeritud 4 kbile, ei muutu see registri uuendamisel 64 kb suuruseks, nii et kaitstud on ainult esimesed 4 kb mälu lubades ründajal seda teha mida iganes ta ülejäänud 60kb-ga tahab.
Kasutamine nr 4
Viimane ärakasutamine, mida autor näitab, viitab mälule, kus asub RKP tarkvara, nii et ründaja võib rünnata RKP tarkvara ennast. Üks nipp seda tüüpi rünnakute peatamiseks, mida kasutavad ka Linuxi tuumad, on eemaldada teie programmi kaardistamine virtuaalmälu aadressiruumist, et ükski rakendus ei saaks seda rünnata, kuna nad ei saa sellele viidata.
Pidage meeles, et mälu on seotud osutite ja tabelitega, mis seostavad füüsilise mälu virtuaalmäluga. Seda tüüpi rünnakute tavapärase kaitse kohaselt võtab RKP end lahti, et seda ei saaks rünnata. Kui aga kernel selliseid võimeid ei paku, võimaldab RKP mälutükki kaardistada ja märkida lugemiseks/kirjutamiseks. Ainus kontroll on see, et see pole aluseks olev kernel ise, kuna RKP ei kontrolli, kas aadressid, mille vastendamist taotletakse, on ala, kus RKP ise asub mälus. Põhimõtteliselt RKP laseb end uuesti kaardistada tagasi aadressiruumi, millele rakendused pääsevad juurde, ja külgmiselt mõjutada mälu märgitakse automaatselt lugemiseks/kirjutamiseks nii et ründaja saab nüüd mälu kasutada nii, nagu soovib.
Järeldus
Üks suurimaid probleeme ülalloetletud nelja ärakasutamise juures on see, et autor mainib, kui raske oleks neid teostada Androidi baaskerneli funktsioonide puudumise tõttu. Irooniline, et turvaline RKP Hypervisor andis kõik rünnakute läbiviimiseks vajalikud tööriistad. See näitab, et mõnikord põhjustab heade kavatsustega tarkvara rohkem probleeme kui lahendab ja meil on vedanud, et meil on inimesi nagu Gal Benimini, kes on valmis oma käed määrima ja kontrollima, kas dokumentatsioon vastab tegelikule tarkvarale teeb.
Kuigi need ärakasutamised tunduvad hirmutavad ja muudavad Knoxi kõla väga haavatavaks, tahaksin kõigile kinnitada, et need probleemid on kõik olnud parandatud jaanuari värskenduses Samsungilt. Lisaks nõuavad need ärakasutamised ARM-protsessorite ja programmeerimise väga sügavat mõistmist, seega on nende ärakasutamiste kasutamise barjäär astronoomiliselt kõrge.
Allikas: Project Zero