A Windows Vista Service Pack 1 (SP1) támogatása 2011. július 12-én véget ér. Ha továbbra is megszereteti kapni a Windows biztonsági frissítéseit, győződjön meg arról, hogy a Windows Vista Service Pack 2 (SP2) csomagot futtatja. További információért olvassa el ezt a Microsoft-weblapot: A Támogatás a Windows egyes verzióiban véget ér.
Amikor egy alkalmazás dinamikusan betölt egy dinamikus csatolású tárat (DLL-t) egy teljesen minősített elérési út megadása nélkül, a Windows egy jól definiált könyvtárakban keresve megpróbálja megkeresni a DLL-t. Ha egy támadó átveheti az irányítást az egyik könyvtár felett, kényszerítheti az alkalmazást, hogy a várt DLL helyett a DLL egy kártékony példányát töltse be. Ezeket a támadásokat "DLL-előbetöltési támadásoknak" nevezik, és minden olyan operációs rendszerben gyakoriak, amelyek támogatják a megosztott DLL-tárak dinamikus betöltését. Az ilyen támadások hatása az lehet, hogy a támadó az alkalmazást futtató felhasználó környezetében futtathatja a kódot. Ha az alkalmazást rendszergazdaként futtatja, az helyi jogosultsági szinthez vezethet. Tudunk a támadások iránti megújult érdeklődésről. A probléma közös ügyfeleinkre gyakorolt hatásának korlátozása érdekében kiadjuk ezt a dokumentumot a fejlesztői közösségnek, hogy biztos legyen abban, hogy tudnak a problémáról, és hogy rendelkezésre állnak az alkalmazásokban a probléma megoldásához szükséges eszközök.
Összefoglalás
A DLL-előbetöltési támadások leírása
LoadLibrary-alapú támadások
Amikor egy alkalmazás dinamikusan betölt egy DLL-t anélkül, hogy teljesen minősített elérési utat adna meg, a Windows megpróbálja megtalálni ezt a DLL-t úgy, hogy lineárisan keres egy jól definiált könyvtárakat, más néven DLL-keresési sorrendet. Ha a Windows a DLL keresési sorrendben találja meg a DLL-t, betölti a DLL-t. Ha azonban a Windows egyik könyvtárban sem találja meg a DLL-t a DLL keresési sorrendjében, hibát ad vissza a DLL betöltési műveletében. Az alábbi táblázat a Dll keresési sorrendje a LoadLibraryés a LoadLibraryExfüggvényhez, amelyek a DLL-ek dinamikus betöltésére használhatók:
-
Az a könyvtár, amelyből az alkalmazás betöltődött
-
A rendszerkönyvtár
-
A 16 bites rendszerkönyvtár
-
A Windows-címtár
-
Az aktuális munkakönyvtár (CWD)
-
A PATH környezeti változóban felsorolt könyvtárak
Vegyük a következő esetet:
-
Az alkalmazások a várt teljes elérési út megadása nélkül töltik be a DLL-eket az alkalmazás CWD-ében.
-
Az alkalmazás készen áll arra, hogy kezelje az esetet, ha nem találja a DLL-t.
-
A támadó ismeri ezt az információt az alkalmazásról, és ellenőrzi a CWD-t.
-
A támadó másolatot készített a DLL-nek a CWD-ben a saját különlegesen kialakított verziójáról. Ez abból indul ki, hogy a támadónak van erre engedélye.
-
A Windows a DLL keresési sorrendben keres a könyvtárak között, és megkeresi a DLL-t az alkalmazás CWD-ében.
Ebben az esetben a különlegesen kialakított DLL az alkalmazáson belül fut, és az aktuális felhasználó jogosultságait használja.útján való áthaladáshoz. Tisztában vagyunk azzal is, hogy egyes fejlesztők a LoadLibrary segítségével ellenőrzik, hogy van-e egy adott DLL-jük annak megállapítására, hogy a felhasználó a Windows melyik verzióját futtatja. Ne feledje, hogy ez sebezhetővé teszi az alkalmazást. Ha az érintett tár valóban nem létezik abban a Windows-kiadásban, amelynél az alkalmazást végrehajtják, a támadó egy hasonló nevű tárat is bevezethet a CWD szolgáltatásban. Kifejezetten ajánljuk, hogy ne használja ezt a módszert. Ehelyett használja az MSDN-cikkben ismertetett "A rendszer verziószámának leszerzése" ajánlott technikákat. Egy olyan alkalmazás, amely külső gyártótól származó bővítményeket tölt be, és nem kényszeríti a beépülő modulokat arra, hogy minősített elérési utat használjanak a LoadLibrary-hívásokhoz, a SetDllDirectory("") nevet hívja a CWD eltávolításához, majd a SetDllDirectory("plugin install location") függvényt a bővítmény telepítési könyvtárának a DLL-keresési útvonalhoz való hozzáadásához.
Javaslat A támadás megelőzéséhez az alkalmazások eltávolítják az aktuális munkakönyvtárat (CWD) a DLL keresési útvonalából úgy, hogy a SetDllDirectory API-t egy üres karakterlánc ("") használatával hívja meg. Ha egy alkalmazás egy DLL aktuális címtárból való betöltésétől függ, szerezze be az aktuális munkakönyvtárat, és használja azt a LoadLibrary teljes elérésiSearchPath-alapú támadások
Hasonló támadás akkor áll fenn, ha egy alkalmazás a SearchPath API segítségével megkeres egy DLL-t, és dinamikusan betölti a SearchPath által visszaadott elérési utat. A SearchPath API alapértelmezett keresési sorrendje a következő:
-
Az a könyvtár, amelyből az alkalmazás betöltődött
-
Az aktuális munkakönyvtár (CWD)
-
A rendszerkönyvtár
-
A 16 bites rendszerkönyvtár
-
A Windows-címtár
-
A PATH környezeti változóban felsorolt könyvtárak
Ezt a mintát nem javasoljuk, mert nem biztonságos. Nem javasoljuk a SearchPath függvényt .dll-fájl megkeresését, ha a kimenet tervezett használata a LoadLibrary függvény hívásában van. Ennek következtében nem a megfelelő .dll fájlt találhatja meg, mert a SearchPath függvény keresési sorrendje eltér a LoadLibrary függvény által használt keresési sorrendtől. Ha meg kell találnia és be kell töltenie egy .dll-fájlt, használja a LoadLibrary függvényt.
ShellExecute és CreateProcess
ShellExecutevagy CreateProcess)hívnak külső végrehajtható fájlok betöltéséhez. Azt javasoljuk, hogy a fejlesztők óvatosan töltsék be a bináris fájlokat, és adja meg a teljes elérési utat. Ez kisebb összetettséget jelenthet, ha egy bináris adatot tölt be tár helyett.
E problémák változatai akkor is létezhetnek, ha a fejlesztők hasonló függvényeket (példáulAjánlott lépések szoftverfejlesztőknek
Azt javasoljuk, hogy a fejlesztők tegyenek az alábbiakat:
-
Érvényesítse az alkalmazásokat a nem biztonságos tárak betöltése esetén (a cikk későbbi, példákat is tartalmaz). Ezek közé tartoznak az alábbiak:
-
A SearchPath használata egy tár vagy összetevő helyének azonosítására.
-
A LoadLibrary használata az operációs rendszer verziójának azonosítására.
-
-
A LoadLibrary, a CreateProcess és a ShellExecute minden híváshoz használhat teljesen minősített elérési utakat, ahol csak tudja.
-
A SetDllDirectory alkalmazásba küldött hívásokat egy üres karakterláncot ("") alkalmazva eltávolíthatja az aktuális munkakönyvtárat az alapértelmezett DLL-keresési sorrendből, ahol az szükséges. Ne feledje, hogy a SetDllDirectory a teljes folyamatot érinti. Ezért ezt a folyamatot az inicializáció elején kell megtennie, nem a LoadLibrary-hoz való hívások előtt és után. Mivel a SetDllDirectory a teljes folyamatot érinti, a SetDllDirectory különböző értékeket hívó több szála meghatározatlan működést okozhat. Ezenkívül, ha a folyamat külső gyártótól származó DLL-ek betöltésére van tervezve, tesztelni kell, hogy a folyamat egészére kiterjedő beállítás inkompatibilitást okoz-e. Ismert probléma, hogy amikor egy alkalmazás a Visual Basic for Applications alkalmazástól függ, egy folyamatszintű beállítás inkompatibilitást okozhat.
-
A SetSearchPathModefüggvény használatával engedélyezheti a biztonságos folyamatkeresési módot a folyamathoz. Ezzel áthelyezi az aktuális munkakönyvtárat a SearchPath keresési listájának utolsó helyére a folyamat teljes időtartama alatt.
-
Ne használja a SearchPath-t a DLL-fájlok meglétének keresésére anélkül, hogy teljes elérési utat ad meg, még akkor is, ha a csökkentett keresési mód engedélyezve van, mert ez továbbra is a DLL előbetöltési támadásait okozza.
Útmutató a nem biztonságos tárbeterhelések azonosításához
A forráskódban az alábbi példák szemléltetik a nem biztonságos tárak betöltését:
-
Az alábbi példakódban az alkalmazás a legkevésbé biztonságos keresési útvonalat schannel.dll rá a "schannel.dll" kifejezésre. Ha egy támadható schannel.dll a CWD-ben, akkor a rendszer akkor is betöltődik, ha az alkalmazás rákeres a windowsos könyvtárakban a megfelelő tárra.
DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL);
HMODULE handle = LoadLibrary(result); -
A következő kód példában az alkalmazás megkísérli betölteni a tárat a jelen dokumentum elején a LoadLibrary() hívásban ismertetett különféle alkalmazás- és operációsrendszer-helyekről. Ha fennáll a veszélye annak, hogy a fájl nem található meg, az alkalmazás megpróbálhatja betölteni a fájlt az aktuális munkakönyvtárból. Ez a helyzet valamivel kevésbé veszélyes, mint az előző példában. Az alkalmazás felhasználóját azonban továbbra is kockázatnak teszi ki, ha a környezet nem teljesen kiszámítható.
HMODULE handle = LoadLibrary("schannel.dll");
Az alábbiakban példákat talál a tárak jobb és biztonságosabb betöltéseire:
-
Az alábbi példakódban a tár betöltődik közvetlenül egy teljesen minősített elérési út használatával. A támadó csak akkor vezet be kártékony kódot, ha már rendelkezik írási engedélyekkel az alkalmazás célkönyvtárához.
HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");
http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspxSHGetKnownFolderPath
http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspx
-
Az alábbi példakódban a loadLibrary hívása előtt a rendszer eltávolítja az aktuális munkakönyvtárat a keresési útvonalról. Ez jelentősen csökkenti a kockázatot, mivel a támadónak vagy az alkalmazáskönyvtárat, a Windows-címtárat, illetve a felhasználó elérési útában megadott könyvtárakat kell szabályozni ahhoz, hogy DLL-t használva előbetöltési támadásokat használjon.
SetDllDirectory ("");
HMODULE handle = LoadLibrary("schannel.dll"); -
Minden olyan rendszerben, amely telepítette a 963027-es biztonsági frissítést (az MS09-014-esverzióban leírtak szerint), a következő kód véglegesen áthelyezi a CWD-t a keresési sorrend utolsó útjára. Az adott folyamaton belülről a SetSearchPathMode függvényre való későbbi, a keresési módot módosítani próbáló hívások sikertelenek lesznek.
SetDllDirectory ("");
HMODULE handle = LoadLibrary("schannel.dll"); -
Az alábbi példakódban a loadLibrary hívása előtt a rendszer eltávolítja az aktuális munkakönyvtárat a keresési útvonalról. Ez jelentősen csökkenti a kockázatot, mivel a támadónak vagy az alkalmazáskönyvtárat, a windowsos címtárat vagy a felhasználó elérési útában megadott könyvtárakat kell szabályozni ahhoz, hogy DLL-t használva előbetöltési támadásokat használjon.
SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
HMODULE handle = LoadLibrary("schannel.dll");
Nem biztonságos terhelések dinamikus észlelése a Folyamatfigyelővel
A Microsoft közzéteszi a Folyamatfigyelő nevű eszközt. Ezzel az eszközzel a fejlesztők és a rendszergazdák szorosan nyomon követhetik a futó folyamatok működését. A Folyamatfigyelővel dinamikusan észlelheti, hogy az egyik alkalmazása sebezhető-e az ilyen típusú problémaokkal.
-
A Folyamatfigyelő letöltéséhez keresse fel a Microsoft következő weblapját:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
-
Próbálja meg elindítani az alkalmazást egy adott címtárra vonatkozó CWD-halmaz használatával. Kattintson például duplán egy olyan fájlra, amelynek kiterjesztésű fájlkezelője hozzá van rendelve az alkalmazáshoz.
-
A Folyamatfigyelő beállítása az alábbi szűrőkkel:
-
Ha egy sebezhető elérési út ütközik, az alábbihoz hasonlót fog látni: A DLL betöltéséhez a távoli fájlmegosztásra való hívás azt jelzi, hogy ez egy sebezhető
program.
További információ
További információért keresse fel a Microsoft következő weblapjait:
Dinamikus hivatkozástár keresési sorrendjehttp://msdn.microsoft.com/library/ms682586(VS.85).aspxMSDN-dokumentáció a SearchPath függvényről
http://msdn.microsoft.com/library/aa365527(VS.85).aspxMSDN-dokumentáció a LoadLibrary függvényről
http://msdn.microsoft.com/library/ms684175(VS.85).aspxMSDN-dokumentáció a SetDllDirectory függvényről
http://msdn.microsoft.com/library/ms686203(VS.85).aspxMSDN-dokumentáció a SetSearchPathMode függvényről
http://msdn.microsoft.com/library/dd266735(VS.85).aspxDavid Leblanc, a Microsoft Office fő biztonsági szakemberének blogbejegyzése
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspxAndrew Fogs, a DLL-hez való előzetes betöltési támadásokról az MSRC mérnöki csapatának blogbejegyzése