Google's Project Zero heeft ontdekt hoe Samsung's Knox Hypervisor kan worden omzeild (opgelost in januari-patch)

In de nieuwste Project Zero-blogpost heeft het team een ​​manier ontdekt om de realtime kernelbescherming van Samsung te omzeilen, de Knox Hypervisor genaamd.

Het Project Zero-team van Google heeft een aantal exploits geverifieerd waardoor de telefoons van Samsung waarop het zogenaamd veilige Samsung Knox-beveiligingspakket draait, kunnen worden aangevallen. De blog merkt op dat alle kwetsbaarheden zijn doorgegeven aan Samsung, die er in een software-update van januari daadwerkelijk oplossingen voor heeft uitgebracht.


Achtergrond

Als onderdeel van de Samsung Knox-beveiligingssoftwaresuite geïntroduceerd door Samsung, is er een stukje software dat zich tussen Android-applicaties en de kernel bevindt, een zogenaamde Hypervisor. Dit kan worden gebruikt als een extra laag om Android-apparaten verder te beveiligen. De Samsung Knox Hypervisor heet "Realtime kernelbescherming"of kortweg RKP, zoals ik ernaar zal verwijzen in de rest van dit artikel.

De kernel bevindt zich onder RKP in de Android-softwarestack en de applicaties die op het apparaat worden uitgevoerd, staan ​​bovenaan. Het idee achter RKP is om een ​​extra beveiligingslaag voor het apparaat te bieden, aangezien alle verzoeken (geheugen en andere bronnen) van toepassingen op de kernel moeten eerst door Knox gaan, dat probeert te detecteren of een toepassing iets doet zou niet moeten. RKP biedt ook beveiliging door onduidelijkheid met een extra laag om gevoelige informatie te verbergen die een applicatie zou kunnen gebruiken om het apparaat in gevaar te brengen.

De blogpost gaat behoorlijk diep in op hoe Android-geheugen, de RKP en besturingssystemen in het algemeen werken, dus ik heb het samengevat en vereenvoudigd om een ​​snel overzicht te geven van wat er is ontdekt. Ik moedig u echter aan om het volledige artikel te lezen als u tijd heeft, omdat het zeer verhelderend is.


Exploitatie #1:

KASLR of kerneladresruimte-indeling Randomisatie is het proces waarbij de locatie van de kernelcode in het geheugen tijdens het opstarten met een willekeurige hoeveelheid wordt gewijzigd. Elke keer dat het apparaat wordt opgestart, wordt de kernel in een andere adresruimte (gebied in het geheugen) geladen. Het idee is om het moeilijker te maken om te vinden waar de kernelcode zich bevindt om deze aan te vallen, omdat na elke opstart de kernelcode met een willekeurige hoeveelheid in het geheugen "verschuift". Dit klinkt als een geweldige stap om potentiële aanvallers te voorkomen, maar recent onderzoek heeft aangetoond dat je dit daadwerkelijk kunt verslaan zonder dat er een softwarefout of kwetsbaarheid nodig is, omdat KASLR eigenlijk heel moeilijk op een robuuste manier te implementeren is tegen lokale aanvallers.

In het geval van de RKP-software is de mogelijkheid om KASLR te omzeilen feitelijk eenvoudiger dan het onderzoek waarnaar hierboven wordt verwezen. Er wordt verwezen naar het geheugen van alle Android-apparaten door verwijzingen en om de apparaten tegen aanvallen te beschermen, wordt telkens wanneer Android-apparaten afdrukken of uitvoeren (of het nu gaat om scherm- of om te archiveren voor logboeken of foutopsporing), worden de pointer-referenties geanonimiseerd, waardoor het onmogelijk wordt om erachter te komen waar de pointer daadwerkelijk naar verwijst bij het lezen van de uitgang.

Denk aan geheugenaanwijzers als een straatnaambord dat naar een locatie verwijst, en denk aan anonimiseren als het vervagen daarvan. Net als bij televisie wordt het anonimiseren na het filmen uitgevoerd. Android past deze anonimisering ook toe tijdens de uitvoer en alleen als het anonimiseren correct is geconfigureerd, aldus de auteur dat bij elk apparaat dat [hij] tegenkwam de pointer-anonimisering correct was geconfigureerd. Dit klinkt misschien alsof het heel moeilijk te doorbreken is, maar het enige wat je hoeft te doen is een enkele aanwijzer te vinden (denk aan een straatnaambord) die niet geanonimiseerd is (vervaagd). door de kernelontwikkelaar (let op: dit is niet de gemiddelde Android-app-ontwikkelaar) wanneer de pointer naar de logs of een andere locatie wordt geschreven, b.v. scherm of een bestand.

Dus als je een pointer kunt vinden die niet geanonimiseerd is, dan kun je de willekeurige adresverschuiving van de kernel berekenen als het verschil tussen de twee. Interessant genoeg kon de auteur geen exploiteerbare pointer in de kernel vinden, maar vond deze wel in de RPK waarbij ontwikkelaars vergaten een pointer in de debug-uitvoer (logboekregistratie) te anonimiseren, wat tot stand kwam via een typfout. Om de pointers in Android te anonimiseren, moet je een speciale code gebruiken en het blijkt dat de RPK-ontwikkelaars per ongeluk een code hebben gebruikt kleine letter 'k' in plaats van een hoofdletter 'K'. Daarom was het relatief eenvoudig om de willekeurige verschuivingshoeveelheid van de kernelcode te achterhalen en deze aan te vallen.


Exploitatie #2:

De volgende exploit is iets complexer: Samsung Knox beschermt uw apparaat door een reeks regels op het geheugen van het apparaat toe te passen om kwaadaardige code te stoppen. De regels zijn als volgt:

  1. Alle pagina's (code in het geheugen), met uitzondering van de kernelcode, zijn gemarkeerd als "Privileged Execute Never" (wat betekent dat de code hier nooit kan worden uitgevoerd)
  2. Kernelgegevenspagina's (gegevens die door het programma in het geheugen worden gebruikt) worden nooit als uitvoerbaar gemarkeerd (dus code hier kan nooit worden uitgevoerd)
  3. Kernelcodepagina's (code in het geheugen) zijn nooit als beschrijfbaar gemarkeerd (dus geen kwaadaardige code kan deze wijzigen)
  4. Alle kernelpagina's zijn gemarkeerd als alleen-lezen in de vertaaltabel van fase 2 (de tabel die zich tussen de applicatie en de kernel bevindt om verder te voorkomen dat applicaties op de hoogte zijn van echte geheugenlocaties)
  5. Alle geheugenvertalingsvermeldingen zijn gemarkeerd als alleen-lezen voor toepassingen.

We zullen ons concentreren op regel 3, omdat de auteur hier een probleem ontdekte met de implementatie van de bovenstaande regels. RPK markeert het geheugen voor de kernel inderdaad als alleen-lezen, maar als een vergissing voor de KASL werd er een gat ontdekt, wat leidde tot code schrijven in de zogenaamd "alleen-lezen" sectie. Om de locatie van de kernel tijdens het opstarten te verdoezelen, wordt geheugen aan de kernel toegewezen, maar deze hoeveelheid geheugen is veel groter dan het tekstsegment van de kernel. Door een grotere hoeveelheid geheugen toe te wijzen, wordt het veel moeilijker om de daadwerkelijke kernelcode te vinden, die zich overal kan bevinden, en zoals we hierboven zagen, wordt deze willekeurig verplaatst bij elke opstart van het apparaat.

_text en _etext markeren het beschermde bereik

De auteur kon bevestigen dat het geheugen dat door de kernel werd gebruikt inderdaad als "alleen-lezen" was gemarkeerd, maar de rest van de grote hoeveelheid geheugen die werd gebruikt om de kernel te verbergen was niet gemarkeerd als "alleen-lezen". Dit komt omdat RKP alleen het gebied beschermt dat de kerneltekst bevat na het toepassen van de KASLR-dia.


Exploitatie nr. 3

Bij de derde exploit kreeg de auteur toegang tot een ander geheugengebied dat ook beperkt zou moeten worden tot alleen-lezen. De RKP beschermt het geheugen en gebruikt een Hypervisorconfiguratieregister (HCR) om belangrijke kernelbewerkingen te controleren. Het doel van de HCR is om geldige en echte kernelbewerkingen toegang te geven tot de registers en kwaadaardige aanvallen te blokkeren. Dit gebeurt door de oproepen te controleren die zijn gedaan naar de registers die de virtualisatiefuncties regelen. De HCR is geconfigureerd om specifieke bewerkingen te blokkeren die normaal zouden worden afgehandeld, waardoor RKP kan kiezen of een verzoek wel of niet wordt toegestaan.

Bij deze exploit was de HCR-controle niet twee registers bestrijken dat bleek heel belangrijk. De auteur verdiepte zich diep in de ARM-referentiehandleiding en ontdekte dat het eerste register hem in staat stelde RKP voor toepassingen feitelijk uit te schakelen. De "Systeemcontroleregister voor EL1 (SCTLR_EL1) biedt controle op het hoogste niveau over het systeem, inclusief het geheugensysteem." In een perfecte wereld zou de applicatie geheugen gebruiken dat in kaart was gebracht via de RKP, zodat de RKP kon bepalen waartoe de applicatie toegang had. Door dit register echter uit te schakelen, kon de RKP moet worden uitgeschakeld door het apparaat effectief terug te brengen naar hoe het werkte voordat RKP werd geïnstalleerd - wat betekent dat het apparaat wordt toegewezen aan fysiek geheugen zonder de extra beveiliging die door RKP wordt geboden. Dat betekende op zijn beurt dat de auteur kon lezen en schrijven naar het geheugen dat oorspronkelijk en correct werd geblokkeerd door de RKP-software.

Het tweede register dat werd gemist, had een subtieler effect, maar was uiteindelijk net zo verwoestend voor de veiligheid. De Vertaalcontroleregister voor EL1 (TCR_EL1) register heeft rechtstreeks betrekking op de hoeveelheid geheugen waarmee een applicatie werkt, een zogenaamde pagina. RKP is hardgecodeerd tot een paginagrootte van 4 kb omdat AARCH64 Linux-kernels (zoals Android) een vertaalgrootte van 4 KB gebruiken. Het register in kwestie (TCR_EL1) stelt de ARM-chipsets in op de grootte van het geheugen dat moet worden geretourneerd. Het blijkt dat dit register is niet beschermd door de HCR en daarom kan een aanvaller het wijzigen, net zoals de auteur het heeft gewijzigd in een paginagrootte van 64 kb.

Wat dit betekent is dat wanneer aan het verzoek wordt voldaan door RKP, de werkelijke hoeveelheid toegankelijk geheugen nu 64 kb bedraagt ​​in plaats van 4 kb. De reden is dat de ARM-chipset nog steeds de paginagrootte regelt en deze door de exploit op 64 kb was ingesteld. Omdat de RKP het geheugen beschermt tegen schrijven, als onderdeel van de regels vermeld in exploit #2, is het geheugen nog steeds feitelijk beschermd. Maar hier is het addertje onder het gras: aangezien RKP hardgecodeerd is tot 4 kb, verandert het niet naar een paginagrootte van 64 kb wanneer het register werd bijgewerkt, dus alleen de eerste 4 kb geheugen is beveiligd waardoor de aanvaller dit kan doen wat hij maar wil met de resterende 60 kb.


Exploitatie #4

De laatste exploit die de auteur laat zien, is het verwijzen naar het geheugen waar de RKP-software zich bevindt, zodat de aanvaller de RKP-software zelf kan aanvallen. Een truc om dit type aanval, dat ook door Linux-kernels wordt gebruikt, te stoppen, is door je programma los te koppelen van de adresruimte van het virtuele geheugen, zodat geen enkele applicatie het kan aanvallen omdat ze er niet naar kunnen verwijzen.

Onthoud dat bij geheugen alles draait om verwijzingen en tabellen die fysiek geheugen aan virtueel geheugen toewijzen. Volgens de normale verdediging bij dit type aanval ontkoppelt RKP zichzelf zodat deze niet kan worden aangevallen. Wanneer de kernel dergelijke mogelijkheden echter niet biedt, staat RKP wel toe dat een stukje geheugen in kaart wordt gebracht en wordt gemarkeerd als Lezen/Schrijven. De enige controle is dat het niet de onderliggende kernel zelf is, aangezien RKP geen controles uitvoert om te zien of de adressen waarvan wordt gevraagd om in kaart te worden gebracht, het gebied zijn waar RKP zelf zich in het geheugen bevindt. Kortom, RKP laat zich opnieuw in kaart brengen terug in de adresruimte waartoe applicaties toegang hebben en als een kant invloed hebben op de geheugen wordt automatisch gemarkeerd als Lezen/Schrijven zodat een aanvaller het geheugen nu kan gebruiken zoals hij wil.


Conclusie

Een van de grootste problemen met de vier hierboven genoemde exploits is dat de auteur vermeldt hoe moeilijk deze uit te voeren zouden zijn vanwege het gebrek aan functies in de basis-Android-kernel. Ironisch genoeg voorzag de beveiligde RKP Hypervisor in alle tools die nodig waren om de aanvallen uit te voeren. Het laat zien dat goedbedoelde software soms meer problemen veroorzaakt dan oplost, en dat we geluk hebben dat we mensen hebben zoals Gal Beniamini die bereid is de handen uit de mouwen te steken en te testen of de documentatie overeenkomt met wat de software daadwerkelijk is doet.

Hoewel deze exploits angstaanjagend lijken en Knox erg kwetsbaar laten klinken, wil ik iedereen geruststellen dat deze problemen allemaal hebben plaatsgevonden opgelost in de update van januari van Samsung. Bovendien vereisen deze exploits een zeer diepgaand begrip van ARM-processors en -programmering, dus de drempel om deze exploits te gebruiken is astronomisch hoog.


Bron: Project Zero