2. diel - Kontrola používateľských účtov vo Windows - pokračovanie
Po prvním dílu miniseriálu nastal čas zodpovědět otázku, jak se oprávnění aplikací, které prošly UAC dialogem (nebo byly spuštěny některou z aplikací, jenž jím prošla) odlišuje od těch, které takové štěstí neměly. Přitom předpokládáme, že obě třídy aplikací byly spuštěny pod uživatelem s administrátorským oprávněním. Rozdíly ukazuje tabulka 1. Interpretace jejího obsahu je následující:
- SID skupiny Administrators nelze použít při povolování přístupu k objektu. Při procházení DACL dochází k ignorování trojic, které povolují přístup skupině Administrators. To například znamená, že aplikace, která neprošla UAC dialogem, nemůže se soubory, jejichž zabezpečení povoluje přístup pouze členům této skupiny, pracovat. ACE zakazující administrátorům oprávnění ale stále platí.
- Normální úroveň integrity. Aplikace, které neprošly UAC dialogem, při žádostech o přístup k objetkům více trpí restrikcemi integritních politik, což vede například k nemožnosti číst paměť procesů běžících na vyšší úrovni integrity.
- Superprivilegia nejsou k mání. Superprivilegia dovolují v jistých případech přeskočit celý proces kontroly přístupu a automaticky požadovaný přístup k cílovému objektu povolit, případně získat neomezenou kontrolu nad systémem jiným způsobem. Se superprivilegii se může aplikace tvářit například jako zálohovací (čtecí oprávnění k souborům a registru), obnovovací (zápisová oprávnění k souborům a registru) či debugger (neomezený přístup ke všem procesům vyjma chráněných). Z tabulky je patrné, že ten, kdo přes UAC dialog neprojde (a není spuštěn někým, kdo tak učinil), na superprivilegia nemá nárok. Jedná se o důsledek příliš nízké úrovně integrity.
Aplikace, které prošly UAC (nebo byly spuštěny aplikací, jenž měla to štěstí), disponují vysokou úrovní integirty a neplatí pro ně žádné z omezení popsaných výše. Pokud je mechanismus Kontroly uživatelských účtů vypnut, chovají se všechny aplikace spuštěné pod účtem správce, jako by prošly přes UAC dialog.
Tabulka 1: Rozdíly mezi oprávněními aplikací, jenž prošly a neprošly UAC dialogem
Vlastnost | Neprošly | Prošly |
---|---|---|
SID skupiny Administrators | Pouze zakazování přístupu | Plná funkčnost |
Úroveň integrity (IL) | Normální (8192) | Vysoká (12288) |
Superprivilegia | NE | ANO |
Myšlenka obejití mechanismu
Implementaci Kontroly uživatelských účtů ve Windows Vista by mnohý uživatel jistě eufemisticky označil za „neskutečně otravnou“. UAC dialog totiž vyskakoval prakticky při každé změně nastavení systému, takže například výlet do Ovládacích panelů se stával časově náročnějším než v předchozích verzích Windows. Mnoho uživatelů se na základě této zkušenosti určitě rozhodlo UAC úplně vypnout (což prakticky znamená návrat do stavu z předchozích verzí operačního systému).
Windows 7 v tomto ohledu přinesla pozitivní zkušenost, protože při změně systémových nastavení zobrazovala UAC dialog v minimálním množství případů. Důvod tohoto chování pravděpodobně představuje zavedení speciálního seznamu procesů, které jsou spouštěny s administrátorskými právy, aniž by prošly přes UAC dialog (platí pouze pro případ, že příslušný uživatel je správcem). Většina takových procesů se nachází v systémovém adresáři nebo v jeho podstromě. Bohužel, některé z nich nemají dostatečně ošetřeno načítání DLL knihoven, které ke svému běhu potřebují. Tudíž se nabízí otázka, zda-li by jim nešlo podstrčit DLL knihovnu upravenou útočníkem. A odpověď na tuto otázku už přes pět let zní ANO.
Než ale bude možné přistoupit ke zdůvodnění této odpovědi, je nutné absolvovat další obecnou vsuvku, tentokráte o spustitelných souborech ve Windows.
Spustitelné soubory
Většina druhů spustitelných souborů ve Windows (EXE, DLL knihovny, ovladače) dodržuje jednotný binární formát s názvem Portable Executable (PE). Zjednodušeně řečeno, každý spustitelný soubor obsahuje následující:
- kód v podobě souboru funkcí a procedur,
- data (globální proměnné a konstanty),
- seznam exportovaných symbolů (funkcí, procedur, proměnných), které poskytuje vnějšímu světu k volnému užití (využívají jej zejména DLL knihovny a některé druhy ovladačů),
- seznam importovaných symbolů (zejména procedur a funkcí) udává, jaké knihovny daný spustitelný soubor ke své činnosti potřebuje a jaké jimi exportované symboly využívá.
Každý symbol exportovaný spustitelným souborem může být identifikován jménem a/nebo číslem (ordinálem). Seznam importovaných symbolů se dělí do „adresářů“, každý z nich obsahuje informace o symbolech importovaných z určité DLL knihovny. Jméno knihovny je uvedeno bez cesty k jejímu souboru, což nechává útočníkům teoretický prostor k podstrčení vlastní knihovny do právě startující (či již běžící) aplikace).
Poznámka: Symboly nemusí exportovat pouze DLL knihovny. Pro jednoduchost se však tento text zaměřuje hlavně na ně.
Aplikace též mohou DLL knihovny načítat a využívat jejich funkcionality dynamicky – například pouze v určitých okamžicích své existence. Před započetím práce DLL knihovnu načtou do paměti, po dokončení úkolu ji zase uvolní. I v případě takového explicitního načítání je zvykem specifikovat pouze jméno souboru knihovny, nikoliv celou cestu.
Systém tedy musí být schopný nalézt požadovanou knihovnu na základě jména jejího souboru, aniž by znal jeho přesné umístění. Postupně prohledává určité složky, dokud nenarazí na soubor požadovaného jména. Ten pak považuje za správnou knihovnu a načte jej do paměti. Proces vyhledávání správného souboru probíhá nezávisle na tom, zda je knihovna požadována, protože jiný spustitelný soubor z ní importuje symboly, nebo zda je její načtení vyžádáno explicitně aplikací.
Tabulka 2 ve svých řádcích popisuje jednotlivá místa, kde systém hledá při načítání DLL knihoven do paměti. Číselné údaje v jednotlivých řádcích udávají pořadí prohledávání pro nastavení uvedená v příslušném sloupci.
Pokud zadané jméno souboru knihovny patří mezi tzv. známé knihovny (KnownDlls), k prohledávání nedochází a je namapovaná kopie příslušné známé knihovny, která obvykle sídlí v systémovém adresuáří.
Poznámka: Seznam známých knihoven se nachází v klíči registru HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls. Pro 32bitové aplikace na 64bitových verzích Windows je ze stejného důvodu důležitý klíč KnownDlls32 ve stejném podstromě.
Tabulka 2: Pořadí prohledávaných umístění při načítání DLL knihoven
Standardní prohledávání | Alternativní prohledávání | |||
---|---|---|---|---|
DllSearchMode | ||||
Zapnuto | Vypnuto | Zapnuto | Vypnuto | |
Složka aplikace | 1 | 1 | - | - |
Systémový adresář | 2 | 3 | 2 | 3 |
Sys. adresář (16bit) | 3 | 4 | 3 | 4 |
Adresář Windows | 4 | 5 | 4 | 5 |
Aktuální adresář | 5 | 2 | 5 | 2 |
%PATH% | 6 | 6 | 6 | 6 |
Adresář knihovny | - | - | 1 | 1 |
Poznámka: Alternativní prohledávání se použije v případě, že při volání funkce LoadLibraryEx specifikujete absolutní cestu ke knihovně, kteoru chcete načíst, a dále nastavíte příznak LOAD_WITH_ALTERED_SEARCH_PATH. Alternativní prohledávání se aplikuje na všechny další moduly, ze kterých daná knihovna importuje, a to i nepřímo (moduly, ze kterých importují moduly exportující pro danou knihovnu atd.). V případě načítání těchto modulů nejprve dochází k prohleádávní adresáře s danou knihovnou.
Teď už známe potřebnou teorii a v příštím díle se podíváme na samotný útok.