Google Project Zero zjistil, jak obejít hypervisor Knox společnosti Samsung (opraveno v lednové opravě)

V nejnovějším příspěvku na blogu Project Zero tým objevil způsob, jak obejít ochranu jádra společnosti Samsung v reálném čase, která se nazývá Knox Hypervisor.

Tým společnosti Google Project Zero ověřil řadu exploitů, které umožňují napadení telefonů Samsung s údajně bezpečnou bezpečnostní sadou Samsung Knox. Blog uvádí, že všechny zranitelnosti byly předány společnosti Samsung, která pro ně skutečně vydala opravy v lednové aktualizaci softwaru.


Pozadí

Jako součást bezpečnostního softwaru Samsung Knox představeného společností Samsung existuje software, který je umístěn mezi aplikacemi pro Android a jádrem, tzv. Hypervizor. To lze použít jako další vrstvu pro další zabezpečení zařízení Android. Hypervisor Samsung Knox se nazývá „Ochrana jádra v reálném čase“ nebo zkráceně RKP, jak na to budu odkazovat ve zbytku tohoto článku.

Jádro se nachází pod RKP v zásobníku softwaru Android a aplikace, které běží na zařízení, jsou nahoře. Myšlenkou RKP je poskytnout zařízení další vrstvu zabezpečení, protože všechny požadavky (paměť a další zdroje) aplikace do jádra musí nejprve projít Knoxem, který se snaží zjistit, zda aplikace něco dělá neměl by. RKP také poskytuje zabezpečení prostřednictvím utajení s další vrstvou pro skrytí citlivých informací, které by aplikace mohla použít ke kompromitaci zařízení.

Příspěvek na blogu jde docela hluboko do toho, jak funguje paměť Android, RKP a operační systémy obecně, takže jsem jej zkrátil a zjednodušil, abych poskytl rychlý přehled toho, co bylo objeveno. Doporučuji vám, abyste si přečetli celý článek, pokud máte čas, protože je velmi poučný.


Využití #1:

KASLR nebo Kernel Address Space Layout Randomizace je proces změny umístění kódu jádra v paměti o náhodné množství při bootování. Pokaždé, když je zařízení spuštěno, jádro se načte do jiného adresového prostoru (oblasti paměti). Cílem je ztížit nalezení, kde se nachází kód jádra, aby bylo možné na něj zaútočit, protože po každém spuštění se kód jádra "posune" o náhodnou hodnotu v paměti. Zní to jako skvělý krok k zabránění případným útočníkům, ale nedávno výzkum ukázal, že to můžete skutečně porazit, aniž byste potřebovali softwarovou chybu nebo zranitelnost, protože KASLR je ve skutečnosti velmi obtížné implementovat robustním způsobem proti místním útočníkům.

V případě softwaru RKP je možnost obejít KASLR ve skutečnosti jednodušší než výzkum zmíněný výše. Paměť všech zařízení Android je odkazována ukazateli, aby byla zařízení chráněna před útokem, kdykoli zařízení se systémem Android tiskne nebo vydává výstup (ať už na obrazovku nebo do souborů pro protokoly nebo ladění), odkazy na ukazatele jsou anonymizovány, - takže při čtení není možné zjistit, kam ukazatel skutečně ukazuje výstup.

Představte si ukazatele paměti jako značku ulice, která ukazuje na místo, a anonymizaci si představte jako rozmazání. Podobně jako u televize se anonymizace provádí po natáčení, Android také tuto anonymizaci aplikuje při výstupu a pouze v případě, že je anonymizace správně nakonfigurována a autor uvádí že každé zařízení, se kterým se setkal, má správně nakonfigurovanou anonymizaci ukazatele. Může to znít, jako by to bylo velmi těžké prolomit, ale vše, co musíte udělat, je najít jediný ukazatel (přemýšlejte o značce ulice), který nebyl anonymizován (rozmazaný) vývojářem jádra (pozor, toto není váš průměrný vývojář aplikací pro Android), když je ukazatel zapsán do protokolů nebo do jiného umístění, např. obrazovka nebo a soubor.

Pokud tedy najdete ukazatel, který nebyl anonymizován, můžete vypočítat náhodný posun adresy jádra jako rozdíl mezi těmito dvěma. Zajímavé je, že autor nemohl najít zneužitelný ukazatel v jádře, ale našel ho uvnitř RPK kde vývojáři zapomněli anonymizovat ukazatel ve výstupu ladění (protokolování), který vznikl způsobem překlep. Chcete-li anonymizovat ukazatele v systému Android, musíte použít speciální kód a ukázalo se, že vývojáři RPK omylem použili malé písmeno 'k' místo an velké 'K'. Proto bylo relativně jednoduché zjistit velikost náhodného posunu kódu jádra a zaútočit na něj.


Využití #2:

Další exploit je trochu složitější: Samsung Knox chrání vaše zařízení tím, že aplikuje sadu pravidel na paměť zařízení, aby zastavil škodlivý kód. Pravidla jsou následující:

  1. Všechny stránky (kód v paměti), s výjimkou kódu jádra, jsou označeny jako „Privileged Execute Never“ (což znamená, že kód zde nelze nikdy spustit)
  2. Datové stránky jádra (data používaná programem v paměti) nejsou nikdy označeny jako spustitelné (takže zde kód nelze nikdy spustit)
  3. Kódové stránky jádra (kód v paměti) nejsou nikdy označeny jako zapisovatelné (takže je nemůže změnit žádný škodlivý kód)
  4. Všechny stránky jádra jsou v překladové tabulce stupně 2 označeny jako pouze pro čtení (tabulka, která je umístěna mezi aplikací a jádrem, aby se aplikace dále nedozvěděly o skutečných umístěních paměti)
  5. Všechny položky překladu paměti jsou pro aplikace označeny jako pouze pro čtení.

Zaměříme se na pravidlo 3, protože zde autor našel problém s implementací výše uvedených pravidel. RPK ve skutečnosti označí paměť pro jádro jako pouze pro čtení, nicméně jako přehlédnutí KASL byla objevena díra, která vedla k zapsání kódu do sekce údajně „pouze pro čtení“.. Aby se zamlžilo umístění jádra při bootu, je jádru přidělena paměť, ale toto množství paměti je mnohem větší než textový segment jádra. Alokací většího množství paměti je mnohem obtížnější najít skutečný kód jádra, který by mohl být kdekoli, a jak jsme viděli výše, přesunuje se náhodně při každém spuštění zařízení.

_text a _etext označují chráněný rozsah

Autor byl schopen potvrdit, že paměť používaná jádrem byla skutečně označena jako „pouze pro čtení“, avšak zbytek velkého množství paměti použité ke skrytí jádra byl ne označeno jako „pouze pro čtení“. Je to proto, že RKP chrání pouze oblast obsahující text jádra po použití snímku KASLR.


Využití #3

Ve třetím exploitu byl autor schopen přistupovat k další oblasti paměti, která by měla být také omezena pouze na čtení. RKP chrání paměť a používá a Registr konfigurace hypervisoru (HCR) k ovládání klíčových operací jádra. Smyslem HCR je umožnit platným a skutečným operacím jádra přístup k registrům a blokovat škodlivé útoky. Provádí to kontrolou volání provedených do registrů, které řídí virtualizační funkce. HCR je nakonfigurováno tak, aby blokovalo specifické operace, které by byly normálně zpracovány, což umožňuje RKP vybrat si, zda povolit nebo zakázat požadavek.

V tomto exploitu bylo ovládání HCR nepokrývá dva registry což se ukázalo jako velmi důležité. Autor se ponořil hluboko do manuálu ARM Reference a zjistil, že první registr mu umožnil v podstatě vypnout RKP pro aplikace. "System Control Register pro EL1 (SCTLR_EL1) poskytuje nejvyšší úroveň kontroly nad systémem, včetně paměťového systému." V dokonalém světě by aplikace používala paměť, která byla mapována prostřednictvím RKP, aby RKP mohla řídit, k čemu má aplikace přístup. Vypnutí tohoto registru však umožnilo RKP deaktivovat efektivním navrácením zařízení do stavu, v jakém běželo před instalací RKP – což znamená, že zařízení je namapováno do fyzické paměti bez dodatečného zabezpečení poskytovaného RKP. To zase znamenalo, že autor mohl číst a zapisovat do paměti, která byla původně a správně blokována softwarem RKP.

Druhý rejstřík, který se minul, měl jemnější účinek, ale nakonec stejně zničující pro bezpečnost. The Registr řízení překladu pro EL1 Registr (TCR_EL1) přímo souvisí s množstvím paměti, se kterou aplikace pracuje, nazývanou stránka. RKP je pevně zakódován na velikost stránky 4 kB, protože linuxová jádra AARCH64 (jako je Android) používají velikost překladu 4 kB. Dotyčný registr (TCR_EL1) nastavuje čipové sady ARM na velikost paměti, která má být vrácena. Ukázalo se, že tento registr není chráněn HCR a proto jej může útočník změnit tak, jak jej autor změnil na velikost stránky 64 kb.

To znamená, že když je požadavek splněn RKP, skutečné množství dostupné paměti je nyní 64 kb místo 4 kb. Důvodem je, že čipset ARM stále kontroluje velikost stránky a exploitem byl nastaven na 64 kb. Vzhledem k tomu, že RKP chrání paměť před zápisem, jako součást pravidel uvedených v exploitu #2, je paměť stále skutečně chráněna. Ale tady je háček - protože RKP je pevně zakódován na 4 kb, nezmění se při aktualizaci registru na velikost stránky 64 kb, takže chráněny jsou pouze první 4 kb paměti umožňující útočníkovi udělat co chce se zbývajícími 60kb.


Využití #4

Poslední exploit, který autor ukazuje, je odkazování na paměť, kde je software RKP, takže útočník by mohl napadnout samotný software RKP. Jeden trik, jak zastavit tento typ útoku, který používají i linuxová jádra, je odmapovat váš program z adresního prostoru virtuální paměti, aby na něj žádná aplikace nemohla zaútočit, protože na něj nemohou odkazovat.

Pamatujte, že paměť je celá o ukazatelích a tabulkách, které mapují fyzickou paměť na virtuální paměť. Podle normální obrany při tomto typu útoku se RKP odmapuje, takže na něj nelze zaútočit. Pokud však jádro takové schopnosti neposkytuje, RKP umožňuje namapovat část paměti a označit ji jako čtení/zápis. Jedinou kontrolou je, že to není samotné jádro, protože RKP nekontroluje, zda adresy, které mají být mapovány, jsou oblastí, kde je samotný RKP uložen v paměti. V podstatě RKP se nechá přemapovat zpět do adresního prostoru, ke kterému mají aplikace přístup, a jako vedlejší vliv na paměť je automaticky označena jako čtení/zápis takže útočník může nyní používat paměť, jak chce.


Závěr

Jedním z největších problémů čtyř výše uvedených exploitů je, že autor zmiňuje, jak obtížné by bylo jejich provedení kvůli nedostatku funkcí v základním jádře Androidu. Je ironií, že bezpečný RKP Hypervisor poskytoval všechny nástroje, které byly nutné k provedení útoků. Ukazuje se, že někdy dobře míněný software způsobuje více problémů, než řeší, a máme štěstí, že máme lidi jako Gal Beniamini ochotni si ušpinit ruce a otestovat, že dokumentace odpovídá tomu, co skutečně software dělá.

I když se tyto exploity zdají děsivé a způsobují, že Knox zní velmi zranitelně, rád bych všechny ubezpečil, že všechny tyto problémy byly opraveno v lednové aktualizaci od společnosti Samsung. Kromě toho tyto exploity vyžadují velmi hluboké porozumění procesorům a programování ARM, takže bariéra vstupu do používání těchto exploitů je astronomicky vysoká.


Zdroj: Project Zero