Saugus bibliotekų įkėlimas, kad būtų išvengta DLL išankstinio įkėlimo atakų

"Windows Vista" 1 pakeitimų paketo (SP1) palaikymas baigiasi 2011 m. liepos 12 d. Norėdami ir toliau gauti sistemai "Windows" skirtus saugos naujinimus įsitikinkite, kad naudojate "Windows Vista" su 2 pakeitimų paketu (SP2). Daugiau informacijos pateikiama šiame "„Microsoft“" tinklalapyje: Nutraukiamas kai kurių "Windows" versijų palaikymas.

Kai programa dinamiškai įkelia dinaminių saitų biblioteką (DLL) nenurodydama visiškai apibrėžto kelio, Windows bando rasti DLL ieškodama tiksliai apibrėžtame katalogų rinkinyje. Jei užpuolikas įgyja vieno iš katalogų kontrolę, jis gali priversti programą įkelti kenkėjišką DLL kopiją vietoj DLL, kurios ji tikėjosi. Šios atakos yra žinomos kaip "DLL išankstinio įkėlimo atakos" ir yra būdingos visoms operacinėms sistemoms, kurios palaiko dinamišką bendro DLL bibliotekų įkėlimą. Tokių atakų poveikis gali būti toks, kad užpuolikas gali vykdyti kodą programą vykdančio vartotojo kontekste. Kai programa vykdoma kaip administratorius, tai gali lemti vietinį teisių suteikimą. Žinome apie atsinaujinusį susidomėjimą šiais išpuoliais. Siekdami apriboti šios problemos poveikį mūsų bendriems klientams, išleidžiame šį dokumentą kūrėjų bendruomenei, kad įsitikintume, jog jie žino apie šią problemą ir turi reikiamus įrankius šiai problemai spręsti savo programose.

Suvestinė

DLL išankstinio įkėlimo atakų aprašymas

LoadLibrary pagrįstos atakos

Kai programa dinamiškai įkelia DLL nenurodydama visiškai apibrėžto kelio, Windows bando rasti tą DLL tiesiškai ieškodama tiksliai apibrėžtame katalogų rinkinyje, vadinamame DLL ieškos tvarka. Jei Windows randa DLL DLL ieškos tvarkoje, ji įkelia tą DLL. Tačiau jei Windows neras DLL nė viename iš DLL ieškos tvarkos katalogų, ji grąžins DLL įkėlimo operacijos triktį. Toliau pateikiama DLL ieškos tvarka, skirta LoadLibrary ir LoadLibraryEx funkcijoms, kurios naudojamos dinamiškai įkelti DLL:

  1. Katalogas, iš kurio buvo įkelta programa
  2. Sistemos katalogas
  3. 16 bitų sistemos katalogas
  4. "Windows" katalogas
  5. Dabartinis darbo katalogas (CWD)
  6. The directories that are listed in the PATH environment variable

                
Apsvarstykite šį scenarijų:

  • Programa įkelia DLL nenurodydama visiškai apibrėžto kelio, kurį ji tikisi rasti programos CWD.
  • Programa yra visiškai pasirengusi tvarkyti bylą, kai ji neranda DLL.
  • Užpuolikas žino šią informaciją apie programą ir kontroliuoja CWD.
  • Užpuolikas kopijuoja savo specialiai sukurtą DLL versiją CWD. Daroma prielaida, kad pažeidėjas turi teisę tai padaryti.
  • Windows ieško kataloguose DLL ieškos tvarkoje ir randa DLL programos CWD.

Pagal šį scenarijų specialiai sukurta DLL veikia programoje ir įgyja dabartinio vartotojo teises.

Rekomendacija

Siekdamos užkirsti kelią šiai atakai, programos gali pašalinti dabartinį darbinį katalogą (CWD) iš DLL paieškos kelio, iškviesdamos SetDllDirectory API naudodamos tuščią eilutę (""). Jei programa priklauso nuo DLL įkėlimo iš dabartinio katalogo, įsigykite dabartinį darbo katalogą ir naudokite jį, kad pereitumėte į visiškai kvalifikuotą LoadLibrary kelią.

Taip pat žinome, kad kai kurie kūrėjai naudoja "LoadLibrary", norėdami patikrinti, ar yra konkreti DLL, kad nustatytų, kurią "Windows" versiją naudoja vartotojas. Turėtumėte žinoti, kad dėl to programa gali tapti pažeidžiama. Jei paveiktos bibliotekos iš tikrųjų nėra "Windows" leidime, kuriame vykdoma programa, užpuolikas gali įvesti biblioteką tuo pačiu pavadinimu į CWD. Primygtinai rekomenduojame nenaudoti šios technikos. Vietoj to naudokite rekomenduojamus metodus, aprašytus MSDN straipsnyje "Sistemos versijos gavimas".

Programa, kuri įkelia trečiųjų šalių priedus ir negali priversti priedų naudoti kvalifikuoto kelio savo LoadLibrary iškvietimams, turėtų iškviesti SetDllDirectory(""), kad pašalintų CWD, tada iškviesti SetDllDirectory("plugin install location"), kad pridėtų priedų diegimo katalogą prie DLL ieškos kelio.

"SearchPath" pagrįstos atakos

Panaši ataka įvyksta, kai programa naudoja "SearchPath" API, kad surastų DLL ir dinamiškai įkeltų " SearchPath" grąžintą kelią. Toliau nurodyta numatytoji SearchPath API ieškos tvarka:

  • Katalogas, iš kurio buvo įkelta programa
  • Dabartinis darbo katalogas (CWD)
  • Sistemos katalogas
  • 16 bitų sistemos katalogas
  • "Windows" katalogas
  • The directories that are listed in the PATH environment variable

Nerekomenduojame šio modelio, nes jis nėra saugus. Nerekomenduojame funkcijos "SearchPath" kaip .dll failo vietos nustatymo būdo, jei išvesties paskirtis yra iškvietimas funkcijai "LoadLibrary". Dėl to gali būti rastas netinkamas .dll failas, nes funkcijos SearchPath ieškos tvarka skiriasi nuo ieškos tvarkos, kurią naudoja funkcija LoadLibrary. Jei reikia rasti ir įkelti .dll failą, naudokite funkciją LoadLibrary.

ShellExecute ir CreateProcess

Šių problemų variantai taip pat gali pasitaikyti, kai kūrėjai iškviečia panašias funkcijas, pvz., "ShellExecute " ir "CreateProcess ", kad įkeltų išorinius vykdomuosius failus. Rekomenduojame programuotojams būti atsargiems įkeliant dvejetainius failus ir nurodyti tinkamą kelią. Įkeliant dvejetainį, o ne biblioteką, turėtų būti mažiau sudėtinga.

Kūrėjams rekomenduojame atlikti šiuos veiksmus:

  • Patikrinkite savo programas dėl nesaugių bibliotekų įkėlimų (kiekvienos iš jų pavyzdžiai pateikiami toliau šiame straipsnyje). Tai gali būti:

    • "SearchPath" naudojimas norint nustatyti bibliotekos arba komponento vietą.
    • LoadLibrary naudojimas operacinės sistemos versijai nustatyti.
  • Jei galite, naudokite visiškai tinkamus kelius visiems iškvietimams į LoadLibrary, CreateProcess ir ShellExecute.

  • Įgyvendinkite iškvietimus į SetDllDirectory su tuščia eilute (""), kad pašalintumėte dabartinį darbinį katalogą iš numatytosios DLL paieškos tvarkos, kur to reikia. Atminkite, kad "SetDllDirectory" turi įtakos visam procesui. Todėl turėtumėte tai padaryti vieną kartą proceso inicijavimo pradžioje, o ne prieš ir po iškvietimų į LoadLibrary. Kadangi "SetDllDirectory" veikia visą procesą, kelios gijos, iškviečiančios "SetDllDirectory" su skirtingomis reikšmėmis, gali sukelti neapibrėžtą veikimą. Be to, jei procesas skirtas įkelti trečiųjų šalių DLL, reikės atlikti bandymus, kad būtų galima nustatyti, ar viso proceso nustatymas sukels nesuderinamumą. Žinoma problema, kad kai programa priklauso nuo "Visual Basic for Applications", viso proceso parametras gali sukelti nesuderinamumą.

  • Naudokite funkciją SetSearchPathMode , kad įjungtumėte proceso saugiosios proceso ieškos režimą. Tokiu būdu dabartinis darbinis katalogas perkeliamas į paskutinę vietą "SearchPath" ieškos sąraše per visą procesą.

  • Venkite naudoti SearchPath, kad patikrintumėte, ar yra DLL, nenurodę visiškai apibrėžto kelio, net jei įjungtas saugiosios ieškos režimas, nes tai vis tiek gali sukelti DLL išankstinio įkėlimo atakas.

Rekomendacijos, kaip nustatyti nesaugias bibliotekos apkrovas

Toliau pateikiami nesaugių bibliotekų įkėlimų šaltinio kode pavyzdžiai:

  • Toliau pateiktame kodo pavyzdyje programa ieško "schannel.dll" naudodama nesaugiausią ieškos kelią. Jei užpuolikas gali įdėti schannel.dll į CWD, jis bus įkeltas dar prieš programai ieškant atitinkamos bibliotekos "Windows" kataloguose.

    DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); 
    HMODULE handle = LoadLibrary(result);
    
  • Toliau pateiktame kodo pavyzdyje programa bando įkelti biblioteką iš įvairių programų ir operacinės sistemos vietų, aprašytų šio dokumento pradžioje LoadLibrary() iškvietimui. Jei yra pavojus, kad failo nėra, programa gali bandyti įkelti failą iš dabartinio darbo katalogo. Šis scenarijus yra šiek tiek mažiau pavojingas nei ankstesnis pavyzdys. Tačiau programos vartotojui vis tiek kyla pavojus, jei aplinka nėra visiškai nuspėjama.

    HMODULE handle = LoadLibrary("schannel.dll");
    

                
                
Toliau pateikiami geresnių, saugesnių bibliotekų įkėlimų pavyzdžiai:

  • Toliau pateiktame kodo pavyzdyje biblioteka įkeliama tiesiogiai naudojant visiškai apibrėžtą kelią. Nėra jokios rizikos, kad užpuolikas įves kenkėjišką kodą, nebent jis jau turi rašymo leidimus programos tiksliniame kataloge.

    HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");
    

    Pastaba Informacijos, kaip nustatyti sistemos katalogą, ieškokite šiuose ištekliuose:

    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.aspx

  • Toliau pateiktame kodo pavyzdyje, dabartinis darbinis katalogas pašalinamas iš ieškos kelio prieš iškviečiant LoadLibrary. Tai žymiai sumažina riziką, nes užpuolikas turėtų valdyti programos katalogą, "Windows" katalogą arba bet kokius katalogus, nurodytus vartotojo kelyje, kad galėtų naudoti DLL išankstinio įkėlimo ataką.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
    
  • Visose sistemose, kuriose įdiegta saugos naujinimo 963027 (aprašyta MS09-014), toliau nurodytas kodas visam laikui perkeltų CWD į pačią paskutinę ieškos tvarkos vietą. Bet kokie vėlesni funkcijos SetSearchPathMode iškvietimai iš proceso vidaus, kuriais bandoma pakeisti ieškos režimą, nepavyks.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
    
    
  • Toliau pateiktame kodo pavyzdyje, dabartinis darbinis katalogas pašalinamas iš ieškos kelio prieš iškviečiant LoadLibrary. Tai žymiai sumažina riziką, nes užpuolikas turėtų valdyti programos katalogą, "Windows" katalogą arba bet kokius katalogus, nurodytus vartotojo kelyje, kad galėtų naudoti DLL išankstinio įkėlimo ataką.

    SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
    HMODULE handle = LoadLibrary("schannel.dll");
    
    
    

"Process Monitor" naudojimas dinamiškai aptikti nesaugias apkrovas

"„Microsoft“" publikuoja įrankį, pavadintą "Process Monitor". Šis įrankis leidžia kūrėjams ir administratoriams atidžiai stebėti vykdomo proceso veikimą. "Process Monitor" gali būti naudojamas dinamiškai nustatyti, ar viena iš jūsų programų gali būti pažeidžiama tokio tipo problemų.

  • Norėdami atsisiųsti "Process Monitor", apsilankykite šiame "„Microsoft“" tinklalapyje:
    http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

  • Pabandykite paleisti programą naudodami CWD nustatytą konkrečiame kataloge. Pavyzdžiui, dukart spustelėkite failą, kurio plėtinys priskirtas jūsų taikomajai programai.

  • Nustatykite "Process Monitor" su šiais filtrais:

    371495f2-14de-f99c-c55a-f75d31fe9ca8

  • Jei pataikysite į pažeidžiamą kelią, matysite kažką panašaus į šį: 9acdd1ae-29b9-e499-9de9-8bc665b95e76

     Iškvietimas į nuotolinį failų bendrinimą, norint įkelti DLL nurodo, kad tai yra pažeidžiama programa.

Daugiau informacijos

Norėdami gauti daugiau informacijos, apsilankykite šiuose "„Microsoft“" tinklalapiuose:

Dinaminių saitų bibliotekos ieškos tvarka

http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx MSDN dokumentacija apie funkciją "SearchPath"

http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspx MSDN dokumentacija apie funkciją LoadLibrary

http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx MSDN dokumentacija apie funkciją "SetDllDirectory"

http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspx MSDN dokumentacija apie funkciją SetSearchPathMode

http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspx David Leblanc, "Microsoft Office" vyriausiojo saugos inžinieriaus, tinklaraščio įrašas

http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspx Andrew Roths, MSRC inžinierių komanda apie DLL išankstinio įkėlimo atakas, tinklaraščio įrašas

http://blogs.technet.com/b/srd/archive/2009/04/14/ms09-014-addressing-the-safari-carpet-bomb-vulnerability.aspx

Papildomi ištekliai