Googles Project Zero upptäckte hur man kan kringgå Samsungs Knox Hypervisor (fixad i januari-patch)

click fraud protection

I det senaste Project Zero-blogginlägget har teamet upptäckt ett sätt att kringgå Samsungs kärnskydd i realtid, kallat Knox Hypervisor.

Googles Project Zero-team har verifierat ett antal exploateringar som gör att Samsungs telefoner som kör den förment säkra säkerhetssviten Samsung Knox kan attackeras. Bloggen noterar att alla sårbarheter har skickats till Samsung som faktiskt har släppt korrigeringar för dem i en mjukvaruuppdatering i januari.


Bakgrund

Som en del av Samsung Knox säkerhetsprogramsvit som introducerats av Samsung, finns det en mjukvara som sitter mellan Android-applikationer och kärnan som kallas en Hypervisor. Detta kan användas som ett extra lager för att ytterligare säkra Android-enheter. Samsung Knox Hypervisor heter "Kärnskydd i realtid" eller RKP för kort, som jag kommer att referera till i resten av denna artikel.

Kärnan ligger under RKP i Android-programstapeln, och applikationerna som körs på enheten sitter överst. Tanken bakom RKP är att tillhandahålla ett extra lager av säkerhet för enheten eftersom alla förfrågningar (minne och andra resurser) som görs av applikationer till kärnan måste gå igenom Knox först, som försöker upptäcka om en applikation gör något borde inte. RKP ger också säkerhet genom mörker med ett extra lager för att dölja känslig information som en applikation kan använda för att äventyra enheten.

Blogginlägget går ganska djupt in i hur Android-minne, RKP och operativsystem i allmänhet fungerar, så jag har sammanfattat och förenklat det för att ge en snabb överblick över vad som upptäcktes. Jag uppmuntrar dig dock att läsa hela artikeln om du har tid, eftersom den är väldigt upplysande.


Utnyttja #1:

KASLR eller Kernel Address Space Layout Randomisering är processen att ändra platsen för kärnkoden i minnet med en slumpmässig mängd vid uppstart. Varje gång enheten startas laddas kärnan i ett annat adressutrymme (område i minnet). Tanken är att göra det svårare att hitta var kärnkoden finns för att attackera den eftersom kärnkoden "skiftar" efter varje uppstart med en slumpmässig mängd i minnet. Detta låter som ett bra steg för att förhindra potentiella angripare men nyligen forskning har visat att du faktiskt kan besegra detta utan att kräva en mjukvarubugg eller sårbarhet, eftersom KASLR faktiskt är väldigt svårt att implementera på ett robust sätt mot lokala angripare.

När det gäller RKP-mjukvaran är möjligheten att kringgå KASLR faktiskt enklare än forskningen som refereras till ovan. Alla Android-enheters minne refereras av pekare och för att skydda enheterna från attack, närhelst Android-enheter skriver ut eller matar ut (oavsett om de ska skärma eller att arkivera för loggar eller felsökning), är referenserna för pekare anonymiserade, - vilket gör det omöjligt att ta reda på var pekaren faktiskt pekar på när man läser produktion.

Tänk på minnespekare som en gatuskylt som pekar på en plats och tänk på att anonymisera som att det suddar ut det. Ungefär som TV, görs anonymisering efter inspelningen, Android tillämpar också denna anonymisering vid utgång och endast om anonymisering är korrekt konfigurerad, och författaren anger att varje enhet [han] stött på har haft pekarens anonymisering korrekt konfigurerad. Det här kan låta som om det är väldigt svårt att bryta, men allt du behöver göra är att hitta en enda pekare (tänk på gatuskylt) som inte var anonymiserad (suddig) av kärnutvecklaren (se upp att detta inte är din genomsnittliga Android-apputvecklare) när pekaren skrivs till loggarna eller annan plats, t.ex. skärm eller en fil.

Så om du kan hitta en pekare som inte var anonymiserad, så kan du beräkna kärnans slumpmässiga adressförskjutning som skillnaden mellan de två. Intressant nog kunde författaren inte hitta en exploateringsbar pekare i kärnan men hittade den i RPK: n där utvecklare glömde att anonymisera en pekare i felsöknings- (loggnings)-utgången, vilket kom till i form av en stavfel. För att anonymisera pekarna i Android måste du använda en speciell kod och det visar sig att RPK-utvecklarna av misstag använde en gemen "k" istället för en versaler "K". Därför var det relativt enkelt att ta reda på den slumpmässiga skiftmängden för kärnkoden och attackera den.


Utnyttja #2:

Nästa utnyttjande är lite mer komplex: Samsung Knox skyddar din enhet genom att tillämpa en uppsättning regler på enhetens minne för att stoppa skadlig kod. Reglerna är som följer:

  1. Alla sidor (kod i minnet), med undantag för kärnans kod, är markerade som "Privileged Execute Never" (vilket betyder att kod här aldrig kan köras)
  2. Kärndatasidor (data som används av programmet i minnet) är aldrig markerade som körbara (så koden här kan aldrig köras)
  3. Kernel-kodsidor (kod i minnet) är aldrig märkta som skrivbara (så ingen skadlig kod kan ändra det)
  4. Alla kärnsidor är markerade som skrivskyddade i översättningstabellen för steg 2 (tabellen som sitter mellan applikationen och kärnan för att ytterligare förhindra att applikationer känner till riktiga minnesplatser)
  5. Alla minnesöversättningsposter är markerade som skrivskyddade för applikationer.

Vi kommer att fokusera på regel 3 eftersom det är här författaren hittade ett problem med implementeringen av reglerna ovan. RPK markerar faktiskt minnet för kärnan som skrivskyddat, men som ett förbiseende till KASL upptäcktes ett hål, vilket ledde till skriva kod till den förment "skrivskyddade" sektionen. För att fördunkla platsen för kärnan vid uppstart tilldelas minne till kärnan, men denna mängd minne är mycket större än kärnans textsegment. Genom att allokera en större mängd minne gör det det mycket svårare att hitta den faktiska kärnkoden som kan finnas var som helst, och som vi såg ovan flyttas den slumpmässigt vid varje start av enheten.

_text och _etext markerar det skyddade området

Författaren kunde bekräfta att minnet som användes av kärnan verkligen var markerat som "skrivskyddat", men resten av den stora mängden minne som användes för att dölja kärnan var inte markerad som "skrivskyddad". Detta beror på att RKP endast skyddar regionen som innehåller kärnans text efter att ha applicerat KASLR-bilden.


Utnyttja #3

I den tredje exploateringen kunde författaren komma åt ett annat minnesområde som också borde begränsas till skrivskyddat. RKP skyddar minnet och använder en Hypervisor konfigurationsregister (HCR) för att styra nyckelkärnoperationer. Poängen med HCR är att tillåta giltiga och verkliga kärnoperationer att komma åt registren och blockera skadliga attacker. Den gör detta genom att kontrollera anropen till registren som styr virtualiseringsfunktionerna. HCR: n är konfigurerad att blockera specifika operationer som normalt skulle hanteras, vilket tillåter RKP att välja om en begäran ska tillåtas eller inte tillåtas.

I denna exploatering var HCR-kontrollen inte täcker två register det visade sig vara väldigt viktigt. Författaren grävde djupt i ARM-referensmanualen och upptäckte att det första registret tillät honom att i princip stänga av RKP för applikationer. Den "Systemkontrollregister för EL1 (SCTLR_EL1) ger toppnivåkontroll över systemet, inklusive minnessystemet." I en perfekt värld skulle applikationen använda minne som kartlades via RKP så att RKP kunde kontrollera vad applikationen kunde komma åt. Men att stänga av detta register tillät RKP ska inaktiveras genom att effektivt återställa enheten till hur den kördes innan RKP installerades - vilket innebär att enheten mappas till fysiskt minne utan den extra säkerheten som tillhandahålls av RKP. Det innebar i sin tur att författaren kunde läsa och skriva till ett minne som ursprungligen och korrekt blockerades av RKP-mjukvaran.

Det andra registret som missades hade en mer subtil effekt, men i slutändan lika förödande för säkerheten. De Översättningskontrollregister för EL1 (TCR_EL1)-registret relaterar direkt till mängden minne som en applikation arbetar med som kallas en sida. RKP är hårdkodad till en sidstorlek på 4kb eftersom AARCH64 Linux-kärnor (som Android) använder en översättningsstorlek på 4KB. Registret i fråga (TCR_EL1) ställer in ARM-chipset till storleken på minnet som ska returneras. Det visar sig att detta register är inte skyddat av HCR och därför kan en angripare ändra det eftersom författaren ändrade det till en sidstorlek på 64 kb.

Vad detta betyder är att när begäran uppfylls av RKP är den faktiska mängden tillgängligt minne nu 64kb istället för 4kb. Anledningen är att ARM-kretsuppsättningen fortfarande kontrollerar sidstorleken och den sattes till 64kb av exploateringen. Eftersom RKP skyddar minnet från att skrivas till, som en del av reglerna som listas i exploit #2, är minnet fortfarande faktiskt skyddat. Men här är haken - eftersom RKP är hårdkodad till 4kb ändras den inte till en sidstorlek på 64kb när registret uppdaterades, så endast de första 4kb minnet är skyddade låter angriparen göra vad han vill med de återstående 60kb.


Utnyttja #4

Det sista utnyttjandet som författaren visar är att hänvisa till minnet där RKP-mjukvaran finns, så att angriparen kan attackera själva RKP-mjukvaran. Ett knep för att stoppa den här typen av attacker som även Linux-kärnor använder är att ta bort ditt program från det virtuella minnesadressutrymmet så att inga applikationer kan attackera det eftersom de inte kan referera till det.

Kom ihåg att minne handlar om pekare och tabeller som mappar fysiskt minne till virtuellt minne. Enligt det normala försvaret i denna typ av attack, avkartar RKP sig så att det inte kan attackeras. Däremot, där kärnan inte tillhandahåller sådana förmågor, tillåter RKP att en bit minne mappas och markeras som Läs/Skriv. Den enda kontrollen är att det inte är den underliggande kärnan själv eftersom RKP inte gör några kontroller för att se om adresserna som begärs att mappas är det område där RKP själv finns i minnet. I grund och botten, RKP låter sig kartläggas om tillbaka till adressutrymmet som applikationer kan komma åt och som en sida påverkar minnet markeras automatiskt som Läs/Skriv så en angripare kan nu använda minnet hur den vill.


Slutsats

Ett av de största problemen med de fyra utnyttjandena som anges ovan är att författaren nämner hur svåra dessa skulle vara att utföra på grund av bristen på funktioner i Android-baskärnan. Ironiskt nog tillhandahöll den säkra RKP Hypervisor alla verktyg som krävdes för att utföra attackerna. Det visar sig ibland att välmenande programvara orsakar fler problem än den löser och vi har turen att vi har människor som Gal Beniamini villig att smutsa ner händerna och testa att dokumentationen stämmer överens med vad programvaran faktiskt gör.

Även om dessa bedrifter verkar skrämmande och får Knox att låta väldigt sårbart, skulle jag vilja försäkra alla om att alla dessa problem har varit fixade i januariuppdateringen från Samsung. Dessutom kräver dessa exploateringar en mycket djup förståelse av ARM-processorer och programmering, så inträdesbarriären för att använda dessa exploateringar är astronomiskt hög.


Källa: Project Zero