Portál AbcLinuxu, 27. dubna 2024 10:38

Jaderné noviny – 10. 10. 2013: Větší bezpečí s ASLR v jádře

29. 10. 2013 | Luboš Doležel
Články - Jaderné noviny – 10. 10. 2013: Větší bezpečí s ASLR v jádře  

Aktuální verze jádra: 3.12-rc4. Citáty týdne: Greg Kroah-Hartman, Rafał Miłecki. Náhodné rozvržení paměťového prostoru jádra: Útoky; Náhodné umístění jádra; Implementace.

Obsah

Aktuální verze jádra: 3.12-rc4

link

Aktuální vývojová verze jádra je 3.12-rc4 vydaná 6. října. Linus ji okomentoval slovy: Hmm. rc4 má více nových commitů než rc3, z čehož nemám pocit pohodlí, ale nic nevyčnívá z řady. Objevilo se více aktualizací v systémech souborů, než je obvyklé, ale mám za to, že je to jen náhoda. Máme tam opravy v cifs, xfs, btrfs, fuse a nilfs2.

Stabilní aktualizace: verze 3.11.4, 3.10.15, 3.4.65 a 3.0.99 vyšly 5. října. Greg připojil upozornění, že dlouhověká řada 3.0 se během pár týdnů dostane ke konci, takže uživatelé by měli přemýšlet o přechodu.

Citáty týdne: Greg Kroah-Hartman, Rafał Miłecki

link

Jak se říká tomu pocitu, když se podíváte na kód a přemýšlíte „kdo tenhle hnůj sakra napsal, je to úplně zmatené, musí se to opravit, jak to vůbec může fungovat!“, tak se podíváte na 'git blame' a uvědomíte si, že jste to byli vy před deseti lety?

Pak přemýšlíte, že byste mohli vinit někoho jiného, že to od té doby neopravil, tak spustíte 'scripts/get_maintainer.pl' a uvědomíte si, že jste i správcem tohoto kódu.

Je čas pomalu odstoupit od klávesnice a zapomenout na to, že jsem tyto soubory kdy otevřel...

-- Greg Kroah-Hartman

Tak to vypadá, že proprietární adaptéry ATI obsahují jakýsi drobný protokol I2C, pomocí kterého je lze identifikovat! Podle všeho Catalyst / fglrx používá jakousi komunikaci přes I2C, aby ověřilo, že adaptér je vyroben v ATI, a podle toho povolí, nebo odmítne režim HDMI. To také vysvětluje, proč ovladač radeon neměl nikdy problémy se zvukem přes DVI. ať už se použil jakýkoliv adaptér.

-- Rafał Miłecki

Náhodné rozvržení paměťového prostoru jádra

link

Náhodné rozvržení paměťového prostoru (ASLR) je známá technika komplikující tvorbu exploitů, která používá náhodné rozmístění různých objektů místo používání pevných adres. Linux má už dlouhou dobu ASLR pro programy v uživatelském prostoru, ale Kees Cook by toto rád viděl i v jádře. V přednášce na Linux Security Sumitu vysvětlil důvody a popsal také, jak jeho patche fungují. Na jeho patche jsme se dívali už v dubnu, od té doby se ale věci změnily; šlo o kód postavený na původním návrhu od Dana Rosenberga z roku 2011.

Útoky

link

Mnoho útoků na jádro má podobnou strukturu, říká Cook. Útočník musí najít chybu prohledáváním kódu jádra, nalezením něčeho v patchích nebo sledováním CVE. Útočník pak může různými způsoby použít chybu ke vložení škodlivého kódu do paměťového prostoru jádra a přesměrovat běh jádra na tento kód. Jediním z nejsnazších způsobů, jak získat rootovská práva, je spustit tyto dvě jednoduché funkce:

commit_creds(prepare_creds());

Existence těchto funkcí podle něj „útočníkům neuvěřitelně zjednodušila práci“. Jakmile byl zákeřný kód spuštěn, tak po sobě exploit uklidí. Například poukázal na Rosenbergův expolit protokolu RDS.

Tyto útoky závisí na znalosti toho, kde v paměti jádra se nacházejí jaké symboly. Tato umístění se mezi verzemi jádra a distribučními sestaveními mohou měnit, ale pro konkrétní jádro jsou známá (nebo je možné je zjistit). ASLR tento proces narušuje a přidává další vrstvu komplikací pro útočníka.

ASLR v uživatelském prostoru činí náhodnými různé části aplikace: zásobník, oblasti pro mmap, haldu [heap] a text programu jako takový. Útočníci tak závisí na únicích informací, aby ASLR obešli. Využitím jiné chyby (úniku) může útočník zjistit, kam je kýžený kód nahraný.

Náhodné umístění jádra

link

Cookův jaderný ASLR (KASLR) aktuálně mění jen místo, kam je jaderný kód (neboli text) umístěn při bootu. KASLR „někde musí začít,“ říká. V budoucnosti bude možné náhodně umisťovat i další oblasti.

KASLR má řadu výhod. Jedním z důsledků byl přesun tabulky popisovačů přerušení (interrupt descriptor table; IDT) pryč od zbytku jádra do oblasti v paměti jen ke čtení. Ke zjištění umístění IDT se dá použít neprivilegovaná instrukce SIDT, což se dříve dalo využít ke zjištění umístění jádra. Teď už to nejde, jelikož IDT je někde jinde a navíc je chráněno proti přepsání, protože je jen ke čtení.

ASLR je „statistickou obranou“, protože techniky brute force [hrubé síly] je obecně možné použít pro jeho překonání. Pokud je 1000 možných míst, kde se kýžená položka může nacházet, tak ji brute force najde jednou a 999× selže. V uživatelském prostoru tato chyba povede k pádu programu, ale to na sebe neupozorní tolik jako pád 999 strojů. To by mohl být důsledek špatného tipu při brute force vedenému proti KASLR.

Na druhou stranu není KASLR kompatibilní s hibernací (tedy uspáním na disk). Tento problém má řešení, ale jak Cook řekl, nemá o zájem to řešit. Množství místa dostupného pro přesun textu jádra je dalším problémem. Kód musí být zarovnán na 2 MB kvůli omezením tabulky stránek a k dispozici je prostor o velikosti 2 GB. V „dokonalém světě“ by to znamenalo 1024 možných míst. Ve skutečném světě to je ale mnohem méně.

Je také nutné učinit jisté kroky proti únikům informací, které by bylo možné použít ke zjištění, kde se jádro nachází. Sysctl kptr_restrict by mělo být použito k zajištění toho, že jaderné ukazatele nepronikají do uživatelského prostoru. Stejně tak by se mělo používat dmesg_restrict, protože dmesg má často adresy nebo další informace, které jde použít. Stejně tak logy (jako /var/log/messages) by měly mít práva tak, aby je mohl číst jen root.

Poslední zmiňovaný zdroj úniků je sice snadné opravit, ale narazil na odpor správců síťového subsystému. Soketové API INET_DIAG používá jako popisovač adresu jaderného objektu. Tato adresa je pro uživatelský prostor neprůhledá [opaque], ale jde o skutečný jaderný ukazatel, takže se dá použít pro zjištění umístění jádra. Změna na nějakou zatemněnou [obfuscated] hodnotu by problém napravila, ale správci síťové vrstvy tomu nejsou nakloněni.

Ve zcela neohraničeném [unconfined] systému, hlavně tam, kde místním uživatelům není možno věřit, nebude podle Cooka KASLR moc užitečné. Ale na systémech, které používají kontejnery nebo silně ohraničené procesy, může KASLR pomoci. Například vykreslovací proces v prohlížeči Chrome je ohraničen pomocí sandboxu seccomp-BPF, který omezuje exploity natolik, že nemohou získat potřebné informace. Je také užitečný jako ochrana proti útokům proti vzdáleným službám, jelikož je vzdáleně dostupných „mnohem méně úniků informací“.

Implementace

link

Cook řekl, že KASLR bylo přidáno do Chrome OS. Je v gitovém stromu pro jádro této distribuce a brzy se dostane do stabilního vydání. Cook je pověstný tím, že „přináší rušivé změny v zabezpečení těm, kdo o ně nezbytně nestojí,“ což řekl s úsměvem na tváři, ale KASLR je nakonec „nejméně problematickou“ věcí, co navrhuje. To je částečně kvůli tomu, že „několik dalších moc chytrých lidí“ mu s tím pomáhalo, a to včetně Rosenberga, dalších vývojářů z Google a lidí na mailing listu.

Cookovy patche mění bootovací proces tak, že zjišťuje nejnižší možnou bezpečnou adresu, kam by se jádro mohlo umístit. Pak prochází oblasti e820 a počítá sloty o velikosti jádra. Z těchto náhodně vybere slot pomocí nejlepšího dostupného zdroje náhodných čísel. V závislosti na systému může jít o instrukci RDRAND, nejnižší bity z RDTSC (čítač časového razítka) nebo bity z I/O portů časovače. Pak se jádro dekomprimuje, ošetří se přemístění [relocation] a jádro se spustí.

Patche jsou teď jen pro 64bitové x86, Cook pak má v plánu pracovat na ARM. O ARMu toho ale ví „daleko méně“, takže doufá, že „někoho přesvědčí, aby mu pomohl“.

Současné rozvržení virtuálního adresního prostoru jádra pro jaderný kód ponechává pouze 512 MB – a 1,5 GB pro moduly. Protože tolik adresního prostoru není potřeba, tak jeho patche tento prostor snižují na 1 GB, tudíž jádru zbývá 1 GB a tedy 512 možných slotů (protože musí být zarovnané na 2 MB). Počet slotů se může zvýšit, pokud je umístění modulů přidáno do KASLR.

Následovala ukázka tří virtuálních strojů s jedním obyčejným jádrem a dvěma s kódem pro KASLR. Při pohledu na /proc/kallsyms a /sys/kernel/debug/kernel_page_tables bylo vidět různé adresy. Cook řekl, že se mu nepodařilo odhalit žádné měřitelné výkonnostní důsledky KASLR.

Odlišnosti v adresách komplikují dekódování panik jádra, proto je offset slotu používáný ke zjištění umístění jádra k výstupu přidáván. Zdůraznil, že úniky informací budou u systémů s KASLR větším problémem, je to vcelku podobné tomu, jak Secure Boot nyní rozlišuje mezi rootem a kernel ring 0. Vývojáři většinou únik informací z jádra neřešili, což se teď bude muset změnit.

Pomocí několika jednoduchých kroků mohou vývojáři zamezit úniku jaderných adres. Při použití formátu „%pK“ pro tisk adres se obyčejným uživatelům zobrazí 0, zatímco root nadále uvidí skutečnou adresu (pokud je kptr_restrict povolené, jinak skutečnou adresu uvidí všichni). Obsah dmesg se musí chránit pomocí dmesg_restrict a jádro by nemělo používat adresy jako popisovače. Toto všechno umožní, aby KASLR bylo účinnou technikou, jak zmařit exploity – alespoň v restriktivních prostředích.

Odkazy a zdroje

Kernel coverage at LWN.net: October 10, 2013

Další články z této rubriky

Jaderné noviny – přehled za březen 2024
Jaderné noviny – přehled za únor 2024
Jaderné noviny – přehled za leden 2024
Jaderné noviny – přehled za prosinec 2023
Jaderné noviny – přehled za listopad 2023

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.