I det seneste Project Zero blogindlæg har teamet opdaget en måde at omgå Samsungs kernebeskyttelse i realtid, kaldet Knox Hypervisor.
Googles Project Zero-team har verificeret en række udnyttelser, der gør det muligt at angribe Samsungs telefoner, der kører den formodet sikre Samsung Knox-sikkerhedspakke. Bloggen bemærker, at alle sårbarheder er blevet videregivet til Samsung, som faktisk har udgivet rettelser til dem i en softwareopdatering fra januar.
Baggrund
Som en del af Samsung Knox-sikkerhedssoftwarepakken introduceret af Samsung, er der et stykke software, der sidder mellem Android-applikationer og kernen kaldet en Hypervisor. Dette kan bruges som et ekstra lag for yderligere at sikre Android-enheder. Samsung Knox Hypervisor hedder "Kernelbeskyttelse i realtid" eller RKP for kort, som jeg vil referere til det i resten af denne artikel.
Kernen sidder under RKP i Android-softwarestakken, og de programmer, der kører på enheden, sidder øverst. Ideen bag RKP er at give enheden et ekstra lag af sikkerhed, da alle anmodninger (hukommelse og andre ressourcer) fremsat af applikationer til kernen skal først gennemgå Knox, som forsøger at opdage, om en applikation gør noget burde ikke. RKP giver også sikkerhed gennem uklarhed med et ekstra lag til at skjule følsomme oplysninger, som en applikation kan bruge til at kompromittere enheden.
Blogposten går ret dybt ind i, hvordan Android-hukommelse, RKP og operativsystemer generelt fungerer, så jeg har kondenseret og forenklet det for at give et hurtigt overblik over, hvad der blev opdaget. Jeg opfordrer dig dog til at læse hele artiklen, hvis du har tid, da den er meget oplysende.
Udnyttelse #1:
KASLR eller Kernel Address Space Layout Randomisering er processen med at ændre placeringen af kernekoden i hukommelsen med en tilfældig mængde ved opstart. Hver gang enheden startes, indlæses kernen i et andet adresseområde (område i hukommelsen). Ideen er at gøre det sværere at finde, hvor kernekoden er placeret, for at angribe den, fordi kernekoden efter hver opstart "skifter" med en tilfældig mængde i hukommelsen. Dette lyder som et godt skridt til at forhindre potentielle angribere, men nyligt forskning har vist, at du faktisk kan besejre dette uden at kræve en softwarefejl eller sårbarhed, da KASLR faktisk er meget svær at implementere på en robust måde mod lokale angribere.
I tilfælde af RKP-softwaren er muligheden for at omgå KASLR faktisk enklere end den forskning, der er refereret til ovenfor. Alle Android-enheders hukommelse refereres af pointere og for at beskytte enhederne mod angreb, når Android-enheder udskriver eller udskriver (uanset om de skal skærme eller at arkivere for logfiler eller fejlretning), er pointerreferencerne anonymiserede, - hvilket gør det umuligt at finde ud af, hvor markøren rent faktisk peger hen, når man læser produktion.
Tænk på hukommelsesmarkører som et gadeskilt, der peger på en placering, og tænk på anonymisering som sløring. Ligesom fjernsyn sker anonymisering efter optagelserne, Android anvender også denne anonymisering på outputtidspunktet, og kun hvis anonymisering er konfigureret korrekt, og forfatteren siger at hver enhed, [han] stødte på, har haft pointeranonymisering korrekt konfigureret. Det lyder måske som om, det er meget svært at bryde, men alt du skal gøre er at finde en enkelt pegepind (tænk gadeskilt), der ikke var anonymiseret (sløret) af kerneudvikleren (pas på, at dette ikke er din gennemsnitlige Android-appudvikler), når markøren skrives til logfilerne eller en anden placering, f.eks. skærm eller en fil.
Så hvis du kan finde en pointer, der ikke var anonymiseret, så kan du beregne kernens tilfældige adresseskift som forskellen mellem de to. Interessant nok kunne forfatteren ikke finde en udnyttelig pointer i kernen, men fandt den i RPK'en hvor udviklere glemte at anonymisere en pointer i fejlfindings- (logning)-outputtet, som opstod i form af en tastefejl. For at anonymisere pointerne i Android skal du bruge en speciel kode, og det viser sig, at RPK-udviklerne fejlagtigt brugte en lille "k" i stedet for en stort "K". Derfor var det relativt enkelt at finde ud af kernekodens tilfældige skiftmængde og angribe den.
Udnyttelse #2:
Den næste udnyttelse er lidt mere kompleks: Samsung Knox beskytter din enhed ved at anvende et sæt regler til enhedens hukommelse for at stoppe skadelig kode. Reglerne er som følger:
- Alle sider (kode i hukommelsen), med undtagelse af kernens kode, er markeret som "Privileged Execute Never" (hvilket betyder, at kode her aldrig kan køre)
- Kerneldatasider (data brugt af programmet i hukommelsen) er aldrig markeret som eksekverbare (så kode her kan aldrig køre)
- Kernelkodesider (kode i hukommelsen) er aldrig markeret som skrivbare (så ingen ondsindet kode kan ændre det)
- Alle kernesider er markeret som skrivebeskyttet i trin 2 oversættelsestabel (tabellen, der sidder mellem applikationen og kernen for yderligere at forhindre, at applikationer kender til rigtige hukommelsesplaceringer)
- Alle hukommelsesoversættelsesposter er markeret som skrivebeskyttet for programmer.
Vi vil fokusere på regel 3, da det er her, forfatteren fandt et problem med implementeringen af reglerne ovenfor. RPK markerer faktisk hukommelsen for kernen som skrivebeskyttet, men som en forglemmelse for KASL blev der opdaget et hul, som førte til skrive kode ind i den angiveligt "skrivebeskyttede" sektion. For at sløre placeringen af kernen ved opstartstidspunktet tildeles hukommelsen til kernen, men denne mængde hukommelse er meget større end kernens tekstsegment. Ved at allokere en større mængde hukommelse gør det det meget sværere at finde den faktiske kernekode, som kunne være hvor som helst, og som vi så ovenfor, flyttes den tilfældigt ved hver boot af enheden.
Forfatteren var i stand til at bekræfte, at den hukommelse, der blev brugt af kernen, faktisk var markeret som "skrivebeskyttet", men resten af den store mængde hukommelse, der blev brugt til at skjule kernen, var ikke markeret som "skrivebeskyttet". Dette skyldes, at RKP kun beskytter den region, der indeholder kernens tekst efter at have anvendt KASLR-sliden.
Udnyt #3
I den tredje udnyttelse var forfatteren i stand til at få adgang til et andet hukommelsesområde, som også skulle være begrænset til skrivebeskyttet. RKP beskytter hukommelsen og bruger en Hypervisor-konfigurationsregister (HCR) til at styre nøglekerneoperationer. Pointen med HCR er at tillade gyldige og rigtige kerneoperationer at få adgang til registrene og blokere ondsindede angreb. Det gør det ved at kontrollere opkaldene til de registre, der styrer virtualiseringsfunktionerne. HCR'en er konfigureret til at blokere specifikke operationer, som normalt ville blive håndteret, hvilket giver RKP mulighed for at vælge, om den vil tillade eller afvise en anmodning.
I denne udnyttelse var HCR-kontrollen ikke dækker to registre det viste sig at være meget vigtigt. Forfatteren gravede dybt ned i ARM-referencemanualen og opdagede, at det første register tillod ham grundlæggende at slå RKP fra for applikationer. Det "Systemkontrolregister for EL1 (SCTLR_EL1) giver kontrol på øverste niveau over systemet, inklusive hukommelsessystemet." I en perfekt verden ville applikationen bruge hukommelse, der blev kortlagt via RKP'en, så RKP'en kunne kontrollere, hvad applikationen kunne få adgang til. Men at slukke for dette register gjorde det muligt RKP skal deaktiveres ved effektivt at returnere enheden til, hvordan den kørte, før RKP blev installeret - hvilket betyder, at enheden er mappet til fysisk hukommelse uden den ekstra sikkerhed, som RKP giver. Det betød igen, at forfatteren kunne læse og skrive til en hukommelse, der oprindeligt og korrekt var blokeret af RKP-softwaren.
Det andet register, der blev savnet, havde en mere subtil effekt, men i sidste ende lige så ødelæggende for sikkerheden. Det Oversættelseskontrolregister for EL1 (TCR_EL1) register relaterer direkte til mængden af hukommelse, som en applikation arbejder med kaldet en side. RKP er hårdkodet til en sidestørrelse på 4kb, fordi AARCH64 Linux-kerner (såsom Android) bruger en oversættelsesstørrelse på 4KB. Det pågældende register (TCR_EL1) indstiller ARM-chipsættene til størrelsen af den hukommelse, der skal returneres. Det viser sig at dette register er ikke beskyttet af HCR og derfor kan en angriber ændre det, da forfatteren ændrede det til en sidestørrelse på 64 kb.
Hvad dette betyder er, at når anmodningen opfyldes af RKP, er den faktiske mængde tilgængelig hukommelse nu 64kb i stedet for 4kb. Årsagen er, at ARM-chipsættet stadig kontrollerer sidestørrelsen, og det blev sat til 64kb af udnyttelsen. Da RKP beskytter hukommelsen mod at blive skrevet til, som en del af reglerne anført i udnyttelse #2, er hukommelsen stadig faktisk beskyttet. Men her er fangsten - da RKP er hårdkodet til 4kb, ændres det ikke til en sidestørrelse på 64kb, da registret blev opdateret, så kun de første 4 kb hukommelse er beskyttet lader angriberen gøre hvad han vil med de resterende 60kb.
Udnyt #4
Den sidste udnyttelse, forfatteren viser, er at henvise til hukommelsen, hvor RKP-softwaren er, så angriberen kunne angribe selve RKP-softwaren. Et trick til at stoppe denne type angreb, som Linux-kerner også bruger, er at fjerne kortlægningen af dit program fra den virtuelle hukommelses adresseplads, så ingen applikationer kan angribe det, fordi de ikke kan referere til det.
Husk, at hukommelse handler om pointere og tabeller, som kortlægger fysisk hukommelse til virtuel hukommelse. I henhold til det normale forsvar i denne type angreb afkorter RKP sig selv, så det ikke kan angribes. Men hvor kernen ikke giver sådanne evner, tillader RKP et stykke hukommelse at blive kortlagt og markeret som Læs/Skriv. Den eneste kontrol er, at det ikke er selve den underliggende kerne, da RKP ikke foretager kontrol for at se, om de adresser, der anmodes om at blive kortlagt, er det område, hvor RKP selv ligger i hukommelsen. Dybest set RKP lader sig kortlægge igen tilbage i adresserummet, som applikationer kan få adgang til, og som en side påvirker hukommelse markeres automatisk som Læs/Skriv så en angriber kan nu bruge hukommelsen, som den vil.
Konklusion
Et af de største problemer med de fire ovenstående udnyttelser er, at forfatteren nævner, hvor vanskelige disse ville være at udføre på grund af manglen på funktioner i basis-Android-kernen. Ironisk nok leverede den sikre RKP Hypervisor alle de værktøjer, der var nødvendige for at udføre angrebene. Det viser sig nogle gange, at velmenende software forårsager flere problemer, end den løser, og vi er heldige, at vi har folk som Gal Beniamini, der er villige til at få deres hænder snavsede og teste, at dokumentationen matcher, hvad softwaren faktisk gør.
Selvom disse udnyttelser virker skræmmende og får Knox til at lyde meget sårbare, vil jeg gerne forsikre alle om, at disse problemer alle har været rettet i januar-opdateringen fra Samsung. Ydermere kræver disse udnyttelser en meget dyb forståelse af ARM-processorer og programmering, så adgangsbarrieren ved brug af disse udnyttelser er astronomisk høj.
Kilde: Project Zero