Sociálne siete

SecIT.sk na Facebooku SecIT.sk na Google+ SecIT.sk na Twitteri

Podporte nás


V prípade, že Vám obsah nášho portálu niekedy nejakým spôsobom pomohol, či bol pre Vás prínosom prosím podporte jeho chod ľubovoľnou čiastkou. Ďakujeme!

Štítky

Vyhľadávanie

You are here

Domov
Upozornenie: Obsah je licenčne chránený a bez písomných súhlasov autora článku a vlastníka webovej stránky nesmie byť v žiadnej forme ďalej kopírovaný a šírený v pôvodnom, či v akokoľvek upravenom stave.

Kontrola uživatelských účtů: obcházení

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šllo 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 dcohází k prohleádávní adresáře s danou knihovnou.

Další možnost obrany představuje uvedení explicitních cest k DLL knihovnám do manifestu daného EXE souboru. Systém tedy ví, kde knihovny daných jmen hledat, a tak k prohledávání nedochází. Jako příklad poslouží úryvek manifestu procesu sysprep.exe na Windows 8.1.

<!--
Specifically load these DLLs from the specified path. This
is done as a defence-in-depth approach to closing a known UAC
exploit related to Sysprep.exe being auto-elevated. The list
need not contain KnownDlls since those are always loaded
by the loader from the system directory.
-->
<file 
  loadFrom="%systemroot%\system32\actionqueue.dll" 
  name="actionqueue.dll" />
<file
  loadFrom="%systemroot%\system32\bcryptprimitives.dll"
  name="bcryptprimitives.dll" />
<file
  loadFrom="%systemroot%\system32\cryptbase.dll"
  name="cryptbase.dll" />
<file
  loadFrom="%systemroot%\system32\unattend.dll"
  name="unattend.dll" />
<file
  loadFrom="%systemroot%\system32\wdscore.dll"
  name="wdscore.dll" />

Jak ale demonstruje praktická ukázka v závěru tohoto textu, na některé knihovny se v manifestu této utility zapomnělo.

Pořadí prohledávaných oblastí také ovlivňuje nstavení registrové hodnoty DllSearchMode. Hodnota má typ REG_DWORD a obsahuje-li nenulová data, pro prohledávání platí první a třetí sloupeček tabulky (sloupeček hlavičky se nepočítá).

Z tabulky 2 je patrné, že při načítání DLL knihovny systém začíná hledat v adresáři s EXE souborem aplikace, v jejímž kontextu k načítání dochází. Tato složka je preferována dokonce i před systémovým adresářem či adresářem Windows. Pokud se útočníkovi podaří nakopírovat vlastní knihovnu s příhodným jménem do adresáře aplikace, která prochází přes UAC dialog automaticky, stačí mu tuto aplikaci následně spustit a má vyhráno.

Plán útoku

Postup útočníka může tedy vypadat následovně:

  1. Vyhlédnutí obětního beránka. Nejprve je třeba najít aplikaci, která automaticky prochází přes UAC dialog a při načítání knihoven dochází k prohledávání umístění popsaných v tabulce 2. Seznamy aplikací splňující první kritérium lze pravděpodobně nalézt na internetu, případně je možné uchýlit se ke kvalifikovanému odhadu. Většina takových aplikací totiž sídlí v systémovém adresáři či v jeho podstromu.
  2. Určit název útočící knihovny. Po spuštění vyhlédnuté aplikace se útočník podívá, jaké knihovny používá (např. pomocí nástroje Process Explorer) a vybere si některé ze jemn nepatřící žádné ze známých knihoven.
  3. Nakopírovat útočící knihovnu k vybrané aplikaci. Je pravda, že snad všechni potenciální obětní beránci sídlí v systémovém adresáři či jeho podstromu, tedy na místech, kam běžný uživatel nemá právo zápisu. Zde útočníkovi nahrává další zvláštní vlastnost – některé procesy (například Průzkumník) se za využití metod COM objektu IFileOperation mohou dopustit kopírování do těchto zakázaných oblastí, aniž by jim byl odepřen přístup. Mohou vytvářet nové soubory, ale ne měnit existující. Útočník tedy musí donutit některý z takto privilegovaných procesů nakopírovat útočící knihovnu na příslušné místo. V případě Průzkumníka stačí obyčejná injekce kódu (ať už surového nebo v podobě DLL knihovny).
  4. Spuštění obětního beránka. Tento krok by neměl představovat problém, jelikož oprávnění pro čtení a spouštění souborů má i běžný uživatel prakticky všude (jednu z výjimek tvoří profily jiných uživatelů).
  5. Slavení úspěchu. Pokud se útočník při provádění kroků (1) a (2) nezmýlil, spuštěný obětní beránek načte útočící knihovnu, jejíž inicializační rutina se volá s jeho oprávněním, tedy opravdovými administrátorským.

Praktické ukázky

Součástí tohoto textu je i zdrojový kód projektu demonstrujícího obejití Kontroly uživatelských účtů. Projekt se nese poněkud neoriginální jméno UACBypass a skládá se ze dvou částí: programu Injector zodpovědného za vložení zadané DLL knihovny do určitého běžícího procesu (v tomto případě je použit k vložení útočné DLL knihovny do Průzkumníka Windows) a z útočné DLL knihovny, jež provádní vlastní algoritmus obcházení UAC.

Jedná se o klasickou metodu popsanou v roce 2009 Leo Davidsonem, zdrojový kód UACBypass je ale v porovnání s tím Leovým asi šestkrát menší a pravděpodobně i přehlednější. Příčina spočívá v tom, že Leo do Průzkumníka nevkládá DLL knihovnu, ale pouze kód a data potřebné k obejití UAC, což je sice méně viditelné, ale může to pro některé zatemnit hlavní smysl ukázky.

Útočná knihovna je do Průzkumníka vkládána tak, že dojde k vytvoření nového vlákna v tomto procesu. Startovní adresa nového vlákna se shoduje s počátkem funkce LoadLibraryW v knihovně kernel32.dll a parametrem je adresa plného jména souboru útočné knihovny. Toto jméno je před samotným vytvořením vlákna do Průzkumníika nakopírováno. Program Injector předpokládá, že virtuální adresa knihovny kernel32.dll bude v obou procesech (tedy v Injectoru a v Průzkumníku) stejná.

Samotná DLL knihovna pracuje následovně:

  • Zjistí, zda disponuje administrátorskými právy.
    • Pokud ne, nakopíruje se do adresáře zadaného ve zdrojovém kódu. Následně spustí proces obětního beránka, který je též specifikován ve zdrojovém kódu, a počká na jeho ukončení. Předpokládá, že obětní beránek načte novou instanci útočné knihovny, tentokrát již ale s právy správce.
    • Pokud ano, spustí Příkazový řádek, který zdědí administrátorská práva od obětního beránka. Potom beránka ukončí.

Výsledkem úspěšného útoku je tedy nová instance Příkazového řádku běžící s oprávněním správce. Pro otestování, zda útok opravdu funguje, můžete vyzkoušt následující kombinace názvu útočné knihovny a obětního beránka:

  • shcore.dll a %windir%\system32\sysprep\sysprep.exe (Windows 7 – Windows 8.1),
  • NTWDBLIB.dll a %windir%\system32\cliconfig.exe (Windows 7 – Windows 10 TP 9996).

V prvním případě útok zafunguje pouze v případě, že máte povolené animace grafického uživatelského rozhraní. Ty jsou v klientských verzích Windows ve výchozím nstavení zapnuté, na serverech je tomu opačně. Zároveň je nutné po spuštění obětního beránka kliknout na některý z comboboxů.

Druhý popisovaný případ funguje bez problémů.

Použité zdroje

  1. Leo Davidson
  2. UACMe (GitHub)
  3. UACMe (kernelmode.info)

Podporte nás


Páčil sa Vám tento článok? Ak áno, prosím podporte nás ľubovoľnou čiastkou. Ďakujeme!


ITC manažer Security-portal.cz Soom.cz
Hoax.cz Antivirove centrum Crypto-world.info