Podpora Windows Vista Service Pack 1 (SP1) končí 12. července 2011. Pokud chcete i nadále dostávat aktualizace zabezpečení pro Windows, ujistěte se, že používáte Windows Vista s aktualizací Service Pack 2 (SP2). Další informace naleznete na této webové stránce společnosti Microsoft: Podpora některých verzí systému Windows končí.
Když aplikace dynamicky načte dynamicky propojenou knihovnu (DLL) bez zadání plně kvalifikované cesty, systém Windows se pokusí najít knihovnu DLL prohledáním dobře definované sady adresářů. Pokud útočník získá kontrolu nad jedním z adresářů, může donutit aplikaci, aby místo očekávané knihovny DLL načetla škodlivou kopii knihovny DLL. Tyto útoky jsou známé jako "útoky předběžného načtení DLL" a jsou společné pro všechny operační systémy, které podporují dynamické načítání sdílených knihoven DLL. Výsledkem takových útoků může být to, že útočník může spustit kód v kontextu uživatele, který aplikaci spouští. Pokud je aplikace spouštěna jako správce, může to vést k místnímu zvýšení oprávnění. Víme o obnoveném zájmu o tyto útoky. Abychom omezili dopad tohoto problému na naše společné zákazníky, vydáváme tento dokument pro komunitu vývojářů, abychom se ujistili, že o tomto problému vědí a mají potřebné nástroje k vyřešení problému ve svých aplikacích.
Shrnutí
Popis útoků na předběžné načítání DLL
Útoky založené na LoadLibrary
Když aplikace dynamicky načte knihovnu DLL bez zadání plně kvalifikované cesty, pokusí se systém Windows tuto knihovnu DLL vyhledat lineárním prohledáváním v dobře definované sadě adresářů, známé jako pořadí hledání DLL. Pokud systém Windows vyhledá knihovnu DLL v pořadí hledání DLL, načte tuto knihovnu DLL. Pokud však systém Windows nenajde knihovnu DLL v žádném z adresářů v pořadí hledání DLL, vrátí chybu operace načítání knihovny DLL. Následuje pořadí hledání knihoven DLL pro funkce LoadLibrary a LoadLibraryEx , které se používají k dynamickému načítání knihoven DLL:
- Adresář, ze kterého se aplikace načetla
- Systémový adresář
- 16bitový systémový adresář
- Adresář Windows
- Aktuální pracovní adresář (CWD)
- Adresáře, které jsou uvedeny v proměnné prostředí PATH
Vezměte v úvahu následující scénář:
- Aplikace načte knihovnu DLL bez zadání plně kvalifikované cesty, kterou očekává v CWD aplikace.
- Aplikace je plně připravena na zpracování případu, kdy nenajde knihovnu DLL.
- Útočník zná tyto informace o aplikaci a ovládá CWD.
- Útočník zkopíruje svou vlastní speciálně vytvořenou verzi knihovny DLL v CWD. Předpokládá se, že útočník má oprávnění to udělat.
- Systém Windows prohledá adresáře v pořadí vyhledávání DLL a najde knihovnu DLL v CWD aplikace.
V tomto scénáři je speciálně vytvořená knihovna DLL spuštěna v rámci aplikace a získá oprávnění aktuálního uživatele.
Doporučení
Aby se tomuto útoku zabránilo, mohou aplikace odebrat aktuální pracovní adresář (CWD) z cesty pro hledání DLL voláním rozhraní API SetDllDirectory pomocí prázdného řetězce (""). Pokud aplikace závisí na načtení knihovny DLL z aktuálního adresáře, získejte aktuální pracovní adresář a použijte jej k předání plně kvalifikované cesty LoadLibrary.
Jsme si také vědomi toho, že někteří vývojáři používají LoadLibrary k ověření, zda je k dispozici konkrétní knihovna DLL, aby určili, kterou verzi systému Windows uživatel spouští. Upozorňujeme, že tím může být aplikace zranitelná. Pokud dotčená knihovna skutečně neexistuje ve verzi Windows, na které je aplikace spuštěna, útočník by mohl do CWD zavést knihovnu se stejným názvem. Důrazně nedoporučujeme tuto techniku používat. Místo toho použijte doporučené techniky popsané v článku MSDN Získání verze systému.
Aplikace, která načítá moduly plug-in třetích stran a která nemůže vynutit, aby moduly plug-in používaly kvalifikovanou cestu pro volání LoadLibrary, by měla volat SetDllDirectory("") k odstranění CWD a poté volat SetDllDirectory ("umístění instalace modulu plug-in") k přidání instalačního adresáře modulu plug-in do cesty vyhledávání DLL.
Útoky založené na funkci SearchPath
K podobnému útoku dochází, když aplikace používá rozhraní API SearchPath k vyhledání knihovny DLL a dynamickému načtení cesty, která je vrácena funkcí SearchPath. Následující je výchozí pořadí hledání pro rozhraní SearchPath API:
- Adresář, ze kterého se aplikace načetla
- Aktuální pracovní adresář (CWD)
- Systémový adresář
- 16bitový systémový adresář
- Adresář Windows
- Adresáře, které jsou uvedeny v proměnné prostředí PATH
Tento model nedoporučujeme, protože není bezpečný. Nedoporučujeme funkci SearchPath jako metodu vyhledání souboru .dll, pokud je zamýšlené použití výstupu ve volání funkce LoadLibrary. To může mít za následek vyhledání nesprávného souboru .dll, protože pořadí hledání funkce SearchPath se liší od pořadí hledání používaného funkcí LoadLibrary. Pokud potřebujete najít a načíst soubor .dll, použijte funkci LoadLibrary.
ShellExecute a CreateProcess
Variace těchto problémů mohou také existovat, když vývojáři volají podobné funkce, jako jsou ShellExecute a CreateProcess k načtení externích spustitelných souborů. Doporučujeme, aby vývojáři byli při načítání binárních souborů opatrní a zadali plně kvalifikovanou cestu. To by mělo představovat menší složitost, když načtete binární soubor místo knihovny.
Doporučené kroky pro vývojáře softwaru
Vývojářům doporučujeme postupovat takto:
Ověřte jejich aplikace pro instance nezabezpečeného načítání knihoven (příklady každého z nich jsou uvedeny dále v tomto článku). Patří mezi ně například tyto:
- Použití SearchPath k identifikaci umístění knihovny nebo komponenty.
- Použití LoadLibrary k identifikaci verze operačního systému.
Pokud je to možné, použijte plně kvalifikované cesty pro všechna volání LoadLibrary, CreateProcess a ShellExecute.
Implementujte volání funkce SetDllDirectory s prázdným řetězcem ("") a odeberte aktuální pracovní adresář z výchozího pořadí hledání knihoven DLL, kde je to vyžadováno. Mějte na paměti, že SetDllDirectory ovlivňuje celý proces. Proto byste to měli provést jednou na začátku inicializace procesu, nikoli před a po volání LoadLibrary. Vzhledem k tomu, že SetDllDirectory ovlivňuje celý proces, více vláken volajících SetDllDirectory s různými hodnotami může způsobit nedefinované chování. Navíc, pokud je proces navržen tak, aby načítal knihovny DLL třetích stran, bude nutné testování, aby se zjistilo, zda nastavení pro celý proces nezpůsobí kompatibilitu. Známým problémem je, že když aplikace závisí na jazyce jazyk Visual Basic for Application, může nastavení v rámci celého procesu způsobit nekompatibilitu.
Pomocí funkce SetSearchPathMode povolíte režim hledání bezpečného procesu pro proces. Tím se aktuální pracovní adresář přesune na poslední místo v seznamu vyhledávání SearchPath po celou dobu životnosti procesu.
Vyhněte se použití funkce SearchPath ke kontrole existence knihovny DLL bez zadání plně kvalifikované cesty, a to i v případě, že je povolen režim bezpečného hledání, protože to stále může vést k útokům DLL Preloading.
Pokyny k identifikaci nezabezpečených zatížení knihoven
Ve zdrojovém kódu jsou následující příklady nezabezpečených načtení knihovny:
V následujícím příkladu kódu aplikace vyhledá "schannel.dll" pomocí nejméně zabezpečené cesty hledání. Pokud útočník může umístit schannel.dll do CWD, načte se ještě předtím, než aplikace prohledá adresáře Windows pro příslušnou knihovnu.
DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); HMODULE handle = LoadLibrary(result);V následujícím příkladu kódu se aplikace pokusí načíst knihovnu z různých umístění aplikace a operačního systému popsaných na začátku tohoto dokumentu pro volání LoadLibrary(). Pokud existuje nějaké riziko, že soubor není přítomen, může se aplikace pokusit načíst soubor z aktuálního pracovního adresáře. Tento scénář je o něco méně nebezpečný než předchozí příklad. Stále ale vystavuje uživatele aplikace riziku, pokud prostředí není zcela předvídatelné.
HMODULE handle = LoadLibrary("schannel.dll");
Tady jsou příklady lepšího a bezpečnějšího načítání knihoven:
V následujícím příkladu kódu se knihovna načte přímo pomocí plně kvalifikované cesty. Neexistuje žádné riziko, že by útočník zavedl škodlivý kód, pokud již nemá oprávnění k zápisu do cílového adresáře aplikace.
HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");Poznámka: Informace o tom, jak zjistit systémový adresář, naleznete v následujících zdrojích:
GetSystemDirectory
http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspx SHGetKnownFolderPath
http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspxV následujícím příkladu kódu je aktuální pracovní adresář odebrán z cesty hledání před voláním LoadLibrary. To výrazně snižuje riziko, protože útočník by musel ovládat buď adresář aplikace, adresář Windows nebo jakékoli adresáře, které jsou zadány v cestě uživatele, aby mohl použít útok na předběžné načtení DLL.
SetDllDirectory (""); HMODULE handle = LoadLibrary("schannel.dll");Ve všech systémech, které mají nainstalované aktualizace zabezpečení 963027 (popsané v MS09-014), by následující kód trvale přesunul CWD na úplně poslední místo v pořadí hledání. Všechna pozdější volání funkce SetSearchPathMode z tohoto procesu, která se pokoušejí změnit režim hledání, selžou.
SetDllDirectory (""); HMODULE handle = LoadLibrary("schannel.dll");V následujícím příkladu kódu je aktuální pracovní adresář odebrán z cesty hledání před voláním LoadLibrary. To výrazně snižuje riziko, protože útočník by musel ovládat buď adresář aplikace, adresář systému Windows nebo jakékoli adresáře, které jsou zadány v cestě uživatele, aby mohl použít útok na předběžné načtení DLL.
SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT ); HMODULE handle = LoadLibrary("schannel.dll");
Použití Process Monitor k dynamickému zjišťování nezabezpečených zatížení
Microsoft publikuje nástroj s názvem Process Monitor. Tento nástroj umožňuje vývojářům a správcům pečlivě sledovat chování spuštěného procesu. Pomocí Process Monitor můžete dynamicky zjišťovat, jestli může být některá z vašich aplikací tímto druhem problému zranitelná.
Chcete-li si stáhnout nástroj Process Monitor, navštivte následující webovou stránku společnosti Microsoft:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspxZkuste spustit aplikaci pomocí CWD nastaveného na konkrétní adresář. Poklikejte například na soubor s příponou, jejíž popisovač je přiřazen k vaší aplikaci.
Nastavte Process Monitor s následujícími filtry:
Pokud dojde k nárazu na zranitelnou cestu, zobrazí se něco podobného následujícímu:
Volání vzdálené sdílené složky pro načtení knihovny DLL označuje, že se jedná o ohrožený program.
Další informace
Další informace naleznete na následujících webových stránkách společnosti Microsoft:
Pořadí hledání v dynamické knihovně
http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx Dokumentace MSDN k funkci SearchPath
http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspx Dokumentace MSDN k funkci LoadLibrary
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx Dokumentace na webu MSDN k funkci SetDllDirectory
http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspx Dokumentace MSDN k funkci SetSearchPathMode
http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspx Blogový příspěvek od Davida LeBlanca, hlavního bezpečnostního inženýra systém Microsoft Office
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspx Blogový příspěvek od Andrewa Rothse z technického týmu MSRC o útocích na předběžné načítání DLL