V najnovejši objavi v blogu Project Zero je ekipa odkrila način, kako zaobiti Samsungovo zaščito jedra v realnem času, imenovano Knox Hypervisor.
Googlova ekipa Project Zero je preverila številne izkoriščanja, ki omogočajo napad na Samsungove telefone z domnevno varnim varnostnim paketom Samsung Knox. Blog ugotavlja, da so bile vse ranljivosti posredovane Samsungu, ki je v januarski posodobitvi programske opreme dejansko izdal popravke zanje.
Ozadje
Kot del paketa varnostne programske opreme Samsung Knox, ki ga je predstavil Samsung, obstaja del programske opreme, ki se nahaja med aplikacijami za Android in jedrom in se imenuje Hipervizor. To lahko uporabite kot dodatno plast za dodatno zaščito naprav Android. Hipervizor Samsung Knox se imenuje "Zaščita jedra v realnem času" ali na kratko RKP, kot ga bom omenil v nadaljevanju tega članka.
Jedro je v nizu programske opreme Android pod RKP, aplikacije, ki se izvajajo v napravi, pa na vrhu. Zamisel RKP je zagotoviti dodatno raven varnosti za napravo, saj vse zahteve (pomnilnik in drugi viri), ki jih aplikacije v jedro morajo najprej iti skozi Knox, ki poskuša zaznati, ali aplikacija nekaj počne ne bi smel. RKP zagotavlja tudi varnost prek nejasnosti z dodatno plastjo za skrivanje občutljivih informacij, ki bi jih aplikacija lahko uporabila za ogrožanje naprave.
Objava v blogu se precej poglobi v delovanje pomnilnika Android, RKP in operacijskih sistemov na splošno, zato sem jo strnil in poenostavil, da bi dal hiter pregled odkritega. Spodbujam vas, da preberete celoten članek, če imate čas, saj je zelo poučen.
Izkoriščanje #1:
KASLR ali Randomizacija postavitve naslovnega prostora jedra je postopek spreminjanja lokacije kode jedra v pomnilniku za naključno količino ob zagonu. Vsakič, ko se naprava zažene, se jedro naloži v drug naslovni prostor (območje v pomnilniku). Ideja je, da bi bilo težje najti, kje se nahaja koda jedra, da bi jo napadli, ker se po vsakem zagonu koda jedra "premakne" za naključno količino v pomnilniku. To se sliši kot odličen korak za preprečevanje morebitnih napadalcev, vendar nedavnih raziskovanje je pokazala, da lahko to dejansko premagate, ne da bi potrebovali programsko napako ali ranljivost, saj je KASLR dejansko zelo težko implementirati na robusten način proti lokalnim napadalcem.
V primeru programske opreme RKP je zmožnost obhoda KASLR dejansko enostavnejša od zgoraj navedene raziskave. Na pomnilnik vseh naprav Android se sklicujejo kazalci, da se naprave zaščitijo pred napadi, kadar koli naprave Android tiskajo ali izpisujejo (bodisi na zaslon ali v datoteko za dnevnike ali odpravljanje napak), so reference kazalcev anonimizirane, zaradi česar je nemogoče ugotoviti, kam kazalec dejansko kaže, ko berete izhod.
Pomislite na spominske kazalce kot na ulični znak, ki kaže na lokacijo, na anonimizacijo pa pomislite kot na zamegljevanje tega. Podobno kot pri televiziji se anonimiziranje izvede po snemanju, tudi Android to anonimiziranje uporabi ob izhodnem času in le, če je anonimiziranje pravilno konfigurirano, kot navaja avtor da je imela vsaka naprava, s katero se je srečal, pravilno konfigurirano anonimiziranje kazalca. To se morda sliši, kot da je zelo težko razbiti, vendar morate le najti en sam kazalec (pomislite na ulični znak), ki ni bil anonimiziran (zamegljen) s strani razvijalca jedra (pazite, da to ni vaš povprečni razvijalec aplikacij za Android), ko je kazalec zapisan v dnevnike ali drugo mesto, npr. zaslon ali a mapa.
Torej, če najdete kazalec, ki ni bil anonimiziran, potem lahko izračunate naključni premik naslova jedra kot razliko med obema. Zanimivo je, da avtor ni mogel najti kazalca, ki ga je mogoče izkoristiti, v jedru, vendar ga je našel znotraj RPK kjer so razvijalci pozabili anonimizirati kazalec v izhodu za odpravljanje napak (beleženje), kar je nastalo po tipkarska napaka. Za anonimiziranje kazalcev v Androidu morate uporabiti posebno kodo in izkazalo se je, da so razvijalci RPK pomotoma uporabili mala črka 'k' namesto an velika črka 'K'. Zato je bilo razmeroma enostavno ugotoviti količino naključnega premika kode jedra in jo napadeti.
Izkoriščanje #2:
Naslednji izkoristek je nekoliko bolj zapleten: Samsung Knox ščiti vašo napravo z uporabo nabora pravil za pomnilnik naprave za zaustavitev zlonamerne kode. Pravila so naslednja:
- Vse strani (koda v pomnilniku), razen kode jedra, so označene kot "Privilegirano Izvedi nikoli" (kar pomeni, da se koda tukaj nikoli ne more izvajati)
- Podatkovne strani jedra (podatki, ki jih program uporablja v pomnilniku) niso nikoli označene kot izvršljive (zato se koda tukaj nikoli ne more izvajati)
- Kodne strani jedra (koda v pomnilniku) niso nikoli označene za zapisljive (tako da jih nobena zlonamerna koda ne more spremeniti)
- Vse strani jedra so označene kot samo za branje v prevajalski tabeli 2. stopnje (tabela, ki se nahaja med aplikacijo in jedrom, da dodatno prepreči, da bi aplikacije vedele za dejanske pomnilniške lokacije)
- Vsi vnosi prevajanja pomnilnika so označeni kot samo za branje za aplikacije.
Osredotočili se bomo na 3. pravilo, saj je tukaj avtor našel težavo pri izvajanju zgornjih pravil. RPK dejansko označuje pomnilnik za jedro kot samo za branje, vendar je bila kot spregled v KASL odkrita luknja, ki je vodila do pisanje kode v razdelek, ki naj bi bil "samo za branje".. Da bi prikrili lokacijo jedra ob zagonu, je jedru dodeljen pomnilnik, vendar je ta količina pomnilnika veliko večja od besedilnega segmenta jedra. Z dodelitvijo večje količine pomnilnika je veliko težje najti dejansko kodo jedra, ki bi lahko bila kjer koli, in kot smo videli zgoraj, se premakne naključno ob vsakem zagonu naprave.
Avtor je lahko potrdil, da je bil pomnilnik, ki ga uporablja jedro, res označen kot "samo za branje", vendar je bila preostala velika količina pomnilnika, uporabljenega za skrivanje jedra, ne označen kot "samo za branje". To je zato, ker RKP ščiti samo območje, ki vsebuje besedilo jedra po uporabi diapozitiva KASLR.
Izkoriščanje #3
V tretjem podvigu je avtor lahko dostopal do drugega področja pomnilnika, ki bi moral biti prav tako omejen na samo za branje. RKP ščiti pomnilnik in uporablja a Register konfiguracije hipervizorja (HCR) za nadzor ključnih operacij jedra. Bistvo HCR je omogočiti veljavne in resnične operacije jedra za dostop do registrov in blokiranje zlonamernih napadov. To naredi tako, da preveri klice v registre, ki urejajo funkcije virtualizacije. HCR je konfiguriran tako, da blokira določene operacije, ki bi se običajno obravnavale, kar RKP omogoča, da izbere, ali dovoli ali zavrne zahtevo.
V tem izkoriščanju je bil nadzor HCR ne pokriva dveh registrov to se je izkazalo za zelo pomembno. Avtor se je poglobil v priročnik ARM Reference in odkril, da mu je prvi register omogočal, da v bistvu izklopi RKP za aplikacije. "Sistemski nadzorni register za EL1 (SCTLR_EL1) zagotavlja nadzor na najvišji ravni nad sistemom, vključno s pomnilniškim sistemom." V popolnem svetu bi aplikacija uporabljala pomnilnik, ki je bil preslikan prek RKP, tako da bi lahko RKP nadzoroval, do česa lahko aplikacija dostopa. Vendar je izklop tega registra omogočil RKP je treba onemogočiti z učinkovito vrnitvijo naprave v stanje, v katerem je delovala pred namestitvijo RKP – kar pomeni, da je naprava preslikana v fizični pomnilnik brez dodatne varnosti, ki jo zagotavlja RKP. To pa je pomenilo, da lahko avtor bere in piše v pomnilnik, ki ga je programska oprema RKP prvotno in pravilno blokirala.
Drugi register, ki je bil zgrešen, je imel bolj subtilen učinek, a na koncu prav tako uničujoč za varnost. The Register nadzora prevajanja za EL1 Register (TCR_EL1) je neposredno povezan s količino pomnilnika, s katerim deluje aplikacija, imenovana stran. RKP je trdo kodiran na velikost strani 4 kB, ker jedra Linuxa AARCH64 (kot je Android) uporabljajo velikost prevoda 4 KB. Zadevni register (TCR_EL1) nastavi nabore čipov ARM na velikost pomnilnika, ki ga je treba vrniti. Izkazalo se je, da ta register ni zaščiten s strani HCR zato jo lahko napadalec spremeni, saj jo je avtor spremenil na velikost strani 64 kb.
To pomeni, da ko RKP izpolni zahtevo, je dejanska količina dostopnega pomnilnika zdaj 64 kb namesto 4 kb. Razlog je v tem, da nabor čipov ARM še vedno nadzoruje velikost strani in je bila zaradi izkoriščanja nastavljena na 64 kb. Ker RKP ščiti pomnilnik pred zapisovanjem, kot del pravil, navedenih v izkoriščanju št. 2, je pomnilnik še vedno dejansko zaščiten. Toda tukaj je ulov - ker je RKP trdo kodiran na 4 kb, se ob posodobitvi registra ne spremeni v velikost strani 64 kb, tako da zaščiteni so le prvi 4kb pomnilnika ki napadalcu omogoča kar hoče s preostalimi 60kb.
Izkoriščanje #4
Zadnji podvig, ki ga prikazuje avtor, je sklicevanje na pomnilnik, kjer je programska oprema RKP, tako da lahko napadalec napade samo programsko opremo RKP. Eden od trikov za zaustavitev te vrste napada, ki ga uporabljajo tudi jedra Linuxa, je, da svoj program odstranimo iz naslovnega prostora navideznega pomnilnika, tako da ga nobena aplikacija ne more napasti, ker se ne more sklicevati nanj.
Ne pozabite, da gre pri pomnilniku za kazalce in tabele, ki fizični pomnilnik preslikajo v navidezni pomnilnik. V skladu z običajno obrambo pri tej vrsti napada se RKP razslika, tako da ga ni mogoče napasti. Vendar, kjer jedro ne zagotavlja takšnih zmožnosti, RKP dovoljuje, da se del pomnilnika preslika in označi kot Branje/Pisanje. Edino preverjanje je, da ne gre za samo osnovno jedro, saj RKP ne preverja, ali so naslovi, za katere se zahteva preslikava, področje, kjer se RKP nahaja v pomnilniku. V bistvu RKP dovoli, da se ponovno preslika nazaj v naslovni prostor, do katerega lahko dostopajo aplikacije in kot stran vpliva na pomnilnik je samodejno označen kot Branje/Pisanje tako da lahko napadalec zdaj uporablja pomnilnik, kakor hoče.
Zaključek
Ena največjih težav s štirimi zgoraj navedenimi izkoriščanji je, da avtor omenja, kako težko bi jih bilo izvesti zaradi pomanjkanja funkcij v osnovnem jedru Androida. Ironično je, da je varni hipervizor RKP zagotovil vsa orodja, potrebna za izvedbo napadov. Dokazuje, da včasih dobronamerna programska oprema povzroči več težav, kot jih reši, in srečni smo, da imamo ljudi kot Gal Beniamini, pripravljeni umazati roke in preizkusiti, ali se dokumentacija ujema s dejansko programsko opremo počne.
Medtem ko se ti podvigi zdijo strašljivi in povzročajo, da je Knox zelo ranljiv, bi rad vsem zagotovil, da so bile vse te težave popravljeno v januarski posodobitvi podjetja Samsung. Poleg tega ta izkoriščanja zahtevajo zelo globoko razumevanje procesorjev in programiranja ARM, zato je vstopna ovira pri uporabi teh izkoriščanj astronomsko visoka.
Vir: Project Zero