Asistența pentru Windows Vista Service Pack 1 (SP1) se termină pe 12 iulie 2011. Pentru a continua primirea actualizărilor de securitate pentru Windows, asigurați-vă că executați Windows Vista cu pachetul Service Pack 2 (SP2). Pentru mai multe informații, consultați această pagină Web Microsoft: asistența se termină pentru unele versiuni de Windows.
Atunci când o aplicație încarcă dinamic o bibliotecă de linkuri dinamice (DLL) fără a specifica o cale complet calificată, Windows încearcă să localizeze DLL-ul căutând un set de directoare bine definit. Dacă un atacator câștigă controlul asupra unuia dintre directoare, acesta poate impune aplicației să încarce o copie rău-intenționată a DLL-ului în locul DLL-ului la care se așteaptă. Aceste atacuri sunt cunoscute sub numele de "atacuri de preîncărcare DLL" și sunt comune pentru toate sistemele de operare care acceptă încărcarea dinamică a bibliotecilor DLL partajate. Efectul acestor atacuri ar putea fi faptul că un atacator poate executa codul în contextul utilizatorului care rulează aplicația. Atunci când aplicația este condusă ca administrator, aceasta poate duce la o elevație locală a privilegiilor. Știm despre interesul reînnoit al acestor atacuri. Pentru a limita efectul pe care îl are această problemă asupra clienților noștri comuni, lansăm acest document în comunitatea dezvoltatorilor, pentru a vă asigura că aceștia știu despre această problemă și au instrumentele necesare pentru a rezolva problema în aplicațiile lor.
Rezumat
Descrierea atacurilor de preîncărcare DLL
Atacurile bazate pe LoadLibrary
Atunci când o aplicație încarcă în mod dinamic un DLL fără a specifica o cale complet calificată, Windows încearcă să localizeze acest DLL prin căutarea liniară printr-un set de directoare bine definit, cunoscut sub numele de comandă de căutare DLL. Dacă Windows localizează DLL-ul în ordinea de căutare DLL, acesta va încărca acel DLL. Cu toate acestea, dacă Windows nu găsește DLL-ul în niciuna dintre directoarele din ordinea de căutare DLL, acesta va returna o eroare la operațiunea de încărcare DLL. Următoarea este ordinea de căutare DLL pentru funcțiile LoadLibraryși LoadLibraryEx, care sunt utilizate pentru a încărca dinamic DLL-uri:
-
Directorul din care a fost încărcată aplicația
-
Directorul de sistem
-
Directorul de sistem pe 16 biți
-
Directorul Windows
-
Directorul de lucru curent (CWD)
-
Directoarele listate în variabila de mediu PATH
Luați în considerare următorul scenariu:
-
O aplicație încarcă un DLL fără a specifica o cale complet calificată pe care se așteaptă să o găsească în CWD aplicației.
-
Aplicația este complet pregătită să gestioneze cazul atunci când nu găsește DLL-ul.
-
Atacatorul știe aceste informații despre aplicație și controlează CWD.
-
Atacatorul copiază propria versiune creată special a DLL-ului din CWD. Acest lucru presupune că atacatorul are permisiunea de a face acest lucru.
-
Windows caută în directoarele din ordinea de căutare DLL și găsește DLL-ul în CWD aplicației.
În acest scenariu, DLL-ul special creat rulează în aplicație și câștigă privilegiile utilizatorului curent.
Recomandare
pentru a împiedica acest atac, aplicațiile pot elimina directorul de lucru curent (CWD) din calea de căutare dll, apelând API-ul SetDllDirectory utilizând un șir gol (""). Dacă o aplicație depinde de încărcarea unui DLL din directorul curent, vă rugăm să obțineți directorul de lucru curent și să îl utilizați pentru a trece pe o cale complet calificată de LoadLibrary.
De asemenea, suntem conștienți că unii dezvoltatori utilizează LoadLibrary pentru a valida dacă un anumit DLL este prezent pentru a determina ce versiune de Windows este condusă de utilizator. Trebuie să fiți conștienți de faptul că acest lucru poate face aplicația vulnerabilă. Dacă Biblioteca afectată într-adevăr nu există în versiunea Windows la care este executată aplicația, un atacator poate introduce o bibliotecă cu același nume în CWD. Vă recomandăm insistent să utilizați această tehnică. În schimb, utilizați tehnicile recomandate descrise în articolul MSDN, "Obțineți versiunea sistemului"
. O aplicație care încarcă inserturi de la terți și care nu poate impune inserturile să utilizeze o cale calificată pentru apelurile sale LoadLibrary ar trebui să apeleze SetDllDirectory ("") pentru a elimina CWD, apoi apelați SetDllDirectory ("locul de instalare a insertului") pentru a adăuga directorul de instalare a pluginului în calea de căutare DLL.
Atacurile bazate pe SearchPath
Un atac similar există atunci când o aplicație utilizează API-ul SearchPath pentru a găsi un DLL și a încărca dinamic calea returnată de SearchPath. Iată ordinea implicită de căutare pentru API-ul SearchPath:
-
Directorul din care a fost încărcată aplicația
-
Directorul de lucru curent (CWD)
-
Directorul de sistem
-
Directorul de sistem pe 16 biți
-
Directorul Windows
-
Directoarele listate în variabila de mediu PATH
Nu recomandăm acest model, deoarece nu este sigur. Nu recomandăm funcția SearchPath ca metodă de localizare a unui fișier. dll dacă utilizarea intenționată a producției este într-un apel către funcția LoadLibrary. Acest lucru poate duce la localizarea fișierului. dll greșit, deoarece ordinea de căutare a funcției SearchPath diferă de ordinea de căutare utilizată de funcția LoadLibrary. Dacă trebuie să găsiți și să încărcați un fișier. dll, utilizați funcția LoadLibrary.
ShellExecute și CreateProcess
De asemenea, pot exista variații ale acestor probleme atunci când dezvoltatorii apelează funcții similare, cum ar fi ShellExecuteși CreateProcess, pentru a încărca executabilele externe. Recomandăm dezvoltatorilor să aibă grijă atunci când încarcă fișiere binare și să specifice calea complet calificată. Acest lucru ar trebui să fie mai puțin complex atunci când încărcați un binar în locul unei biblioteci.
Pașii recomandați pentru dezvoltatorii de software
Vă recomandăm ca dezvoltatorii să facă următoarele:
-
Validați aplicațiile lor pentru instanțe ale sarcinilor de bibliotecă nesecurizate (exemple de fiecare sunt prezentate mai jos în acest articol). Acestea includ următoarele:
-
Utilizarea SearchPath pentru a identifica locația unei biblioteci sau a unei componente.
-
Utilizarea LoadLibrary pentru a identifica versiunea sistemului de operare.
-
-
Utilizați căi complet calificate pentru toate apelurile către LoadLibrary, CreateProcess și ShellExecute, unde puteți.
-
Implementați apeluri către SetDllDirectory cu un șir gol ("") pentru a elimina directorul curent de lucru din ordinea de căutare implicită a DLL-ului, unde este necesar. Rețineți că SetDllDirectory afectează întregul proces. Prin urmare, trebuie să faceți acest lucru o singură dată la începutul procesului de inițializare, nu înainte și după apeluri către LoadLibrary. Deoarece SetDllDirectory afectează întregul proces, mai multe fire de apelare SetDllDirectory cu valori diferite pot provoca comportament nedefinit. În plus, dacă procesul este proiectat pentru a încărca DLL-uri de la terți, va fi necesară testarea pentru a determina dacă efectuarea unei setări la nivel de proces va provoca incompatibilități. O problemă cunoscută este că, atunci când o aplicație depinde de Visual Basic for Applications, o setare la nivel de proces poate provoca incompatibilități.
-
Utilizați funcția SetSearchPathModepentru a activa modul de căutare în condiții de siguranță pentru proces. Acest lucru mută directorul curent de lucru până la ultimul rând din lista de căutare SearchPath pentru durata de viață a procesului.
-
Evitați să utilizați SearchPath pentru a verifica existența unui DLL fără a specifica o cale complet calificată, chiar dacă este activată modul de căutare sigur, deoarece acest lucru poate duce în continuare la atacuri de preîncărcare DLL.
Instrucțiuni pentru identificarea încărcărilor de bibliotecă nesecurizate
În codul sursă, următoarele sunt exemple de încărcări nesecurizate ale bibliotecii:
-
În următorul exemplu de cod, aplicația caută "schannel.dll" utilizând cea mai puțin sigură cale de căutare. Dacă un atacator poate să plaseze schannel.dll în CWD, acesta se va încărca chiar înainte ca aplicația să caute în directoarele Windows pentru biblioteca corespunzătoare.
DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL);
HMODULE handle = LoadLibrary(result); -
În următorul exemplu de cod, aplicația încearcă să încarce biblioteca din diferitele locații ale sistemului de operare, descrise la începutul acestui document pentru apelul LoadLibrary (). Dacă există riscul ca fișierul să nu fie prezent, aplicația poate încerca să încarce fișierul din directorul de lucru curent. Acest scenariu este ușor mai puțin periculos decât exemplul anterior. Cu toate acestea, încă expune utilizatorul aplicației să riște dacă mediul nu este complet predictibil.
HMODULE handle = LoadLibrary("schannel.dll");
Iată câteva exemple de încărcări mai bune și mai sigure ale bibliotecilor:
-
În următorul exemplu de cod, biblioteca este încărcată direct, utilizând o cale complet calificată. Nu există riscul ca atacatorul să introducă cod rău intenționat decât dacă are deja permisiuni de scriere în directorul țintă al aplicației.
HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");
Notă pentru informații despre cum să determinați directorul de sistem, consultați următoarele resurse:
GetSystemDirectoryhttp://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspxSHGetKnownFolderPath
http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspx
-
În următorul exemplu de cod, directorul curent de lucru este eliminat din calea de căutare înainte de a apela LoadLibrary. Acest lucru reduce semnificativ riscul, deoarece atacatorul va trebui să controleze directorul de aplicații, directorul Windows sau orice directoare specificate în calea utilizatorului pentru a utiliza un atac de preîncărcare DLL.
SetDllDirectory ("");
HMODULE handle = LoadLibrary("schannel.dll"); -
Pe toate sistemele care au instalat actualizarea de securitate 963027 (descrisă în MS09-014), următorul cod va muta definitiv cwd în ultimul loc din ordinea de căutare. Orice apeluri ulterioare către funcția SetSearchPathMode din interiorul acelui proces care încearcă să modifice modul de căutare nu vor reuși.
SetDllDirectory ("");
HMODULE handle = LoadLibrary("schannel.dll"); -
În următorul exemplu de cod, directorul curent de lucru este eliminat din calea de căutare înainte de a apela LoadLibrary. Acest lucru reduce semnificativ riscul, deoarece atacatorul va trebui să controleze directorul de aplicații, directorul Windows sau orice directoare specificate în calea utilizatorului pentru a utiliza un atac de preîncărcare DLL.
SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
HMODULE handle = LoadLibrary("schannel.dll");
Utilizarea monitorului proces pentru a detecta dinamic sarcinile nesecurizate
Microsoft publică un instrument denumit monitor Process. Acest instrument permite dezvoltatorilor și administratorilor să urmărească îndeaproape comportamentul unui proces în execuție. Monitorul de proces poate fi utilizat pentru a detecta în mod dinamic dacă una dintre aplicațiile dumneavoastră poate fi vulnerabilă la acest tip de problemă.
-
Pentru a descărca procesul monitor, vizitați următoarea pagină Web Microsoft:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
-
Încercați să porniți aplicația utilizând CWD setat la un anumit director. De exemplu, faceți dublu clic pe un fișier care are o extensie al cărei handler de fișier este atribuit aplicației.
-
Configurați monitorul de proces cu următoarele filtre:
-
Dacă o cale vulnerabilă este în curs de lovire, veți vedea ceva asemănător cu următorul:
apelul la partajarea de fișiere la distanță pentru a încărca un dll indică faptul că acesta este un program vulnerabil.
Mai multe informații
Pentru mai multe informații, vizitați următoarele pagini Web Microsoft:
ordinea de căutare a bibliotecii de linkuri dinamice
http://MSDN.Microsoft.com/en-us/library/ms682586 (VS. 85). aspxDocumentația MSDN în funcția SearchPath
http://MSDN.Microsoft.com/en-us/library/aa365527 (VS. 85). aspxDocumentația MSDN în funcția LoadLibrary
http://MSDN.Microsoft.com/en-us/library/ms684175 (VS. 85). aspxDocumentația MSDN în funcția SetDllDirectory
http://MSDN.Microsoft.com/en-us/library/ms686203 (VS. 85). aspxDocumentația MSDN în funcția SetSearchPathMode
http://MSDN.Microsoft.com/en-us/library/dd266735 (VS. 85). aspxBlog post de David Leblanc, inginer principal de securitate cu Microsoft Office
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspxBlog post de Andrew Roths, echipa MSRC Engineering în atacurile de preîncărcare DLL