Ondersteuning voor Windows Vista Service Pack 1 (SP1) eindigt op 12 juli 2011. Als u beveiligingsupdates voor Windows wilt blijven ontvangen, moet u Windows Vista met Service Pack 2 (SP2) uitvoeren. Raadpleeg voor meer informatie deze Microsoft-webpagina: Ondersteuning voor sommige versies van Windows wordt beëindigd.
Wanneer een toepassing dynamisch een DLL (Dynamic Link Library) laadt zonder een volledig gekwalificeerd pad op te geven, probeert Windows het DLL-bestand te vinden door te zoeken in een goed gedefinieerde set mappen. Als een aanvaller de controle over een van de mappen krijgt, kan deze de toepassing dwingen om een schadelijke kopie van het DLL-bestand te laden in plaats van de DLL die het verwachtte. Deze aanvallen staan bekend als 'DLL preloading attacks' en zijn gebruikelijk voor alle besturingssystemen die ondersteuning bieden voor dynamisch laden van gedeelde DLL-bibliotheken. Het effect van dergelijke aanvallen kan zijn dat een aanvaller code kan uitvoeren in de context van de gebruiker die de toepassing uitvoert. Wanneer de toepassing wordt uitgevoerd als beheerder, kan dit leiden tot een lokale uitbreiding van bevoegdheden. We weten van hernieuwde interesse in deze aanvallen. Om het effect van dit probleem op onze gemeenschappelijke klanten te beperken, geven we dit document uit aan de ontwikkelaarscommunity om ervoor te zorgen dat ze op de hoogte zijn van dit probleem en over de benodigde hulpprogramma's beschikken om het probleem in hun toepassingen op te lossen.
Overzicht
Beschrijving van dll-preloading-aanvallen
Op LoadLibrary gebaseerde aanvallen
Wanneer een toepassing dynamisch een DLL laadt zonder een volledig gekwalificeerd pad op te geven, probeert Windows dit DLL-bestand te vinden door lineair te zoeken in een goed gedefinieerde set mappen, ook wel dll-zoekvolgorde genoemd. Als Windows de DLL in de DLL-zoekvolgorde vindt, wordt die DLL geladen. Als Windows de DLL echter niet vindt in een van de mappen in de DLL-zoekvolgorde, wordt er een fout geretourneerd in de DLL-laadbewerking. Hier volgt de DLL-zoekvolgorde voor de functies LoadLibrary en LoadLibraryEx , die worden gebruikt om DLL's dynamisch te laden:
- De map waaruit de toepassing is geladen
- De systeemmap
- De 16-bits systeemmap
- De Windows-map
- De huidige werkmap (CWD)
- De mappen die worden vermeld in de omgevingsvariabele PATH
Neem als voorbeeld het volgende scenario:
- Een toepassing laadt een DLL zonder een volledig gekwalificeerd pad op te geven dat wordt verwacht te vinden in de CWD van de toepassing.
- De toepassing is volledig voorbereid om de case af te handelen wanneer het DLL-bestand niet wordt gevonden.
- De aanvaller kent deze informatie over de toepassing en beheert de CWD.
- De aanvaller kopieert zijn eigen speciaal vervaardigde versie van de DLL in de CWD. Hierbij wordt ervan uitgegaan dat de aanvaller gemachtigd is om dit te doen.
- Windows doorzoekt de mappen in de DLL-zoekvolgorde en vindt de DLL in de CWD van de toepassing.
In dit scenario wordt de speciaal ontworpen DLL uitgevoerd in de toepassing en krijgt het de bevoegdheden van de huidige gebruiker.
Aanbeveling
Om deze aanval te voorkomen, kunnen toepassingen de huidige werkmap (CWD) verwijderen uit het DLL-zoekpad door de SetDllDirectory-API aan te roepen met behulp van een lege tekenreeks (""). Als een toepassing afhankelijk is van het laden van een DLL uit de huidige map, haalt u de huidige werkmap op en gebruikt u deze om een volledig gekwalificeerd pad van LoadLibrary door te geven.
We zijn ons er ook van bewust dat sommige ontwikkelaars LoadLibrary gebruiken om te valideren of een specifieke DLL aanwezig is om te bepalen welke versie van Windows door de gebruiker wordt uitgevoerd. Houd er rekening mee dat dit de toepassing kwetsbaar kan maken. Als de betrokken bibliotheek inderdaad niet bestaat in de Windows-release waarop de toepassing wordt uitgevoerd, kan een aanvaller een bibliotheek met dezelfde naam in CWD introduceren. We raden u ten zeerste af deze techniek te gebruiken. Gebruik in plaats daarvan de aanbevolen technieken die worden beschreven in het MSDN-artikel 'De systeemversie ophalen'.
Een toepassing die invoegtoepassingen van derden laadt en die de invoegtoepassingen niet kan dwingen een gekwalificeerd pad te gebruiken voor de LoadLibrary-aanroepen, moet SetDllDirectory("") aanroepen om CWD te verwijderen en vervolgens SetDllDirectory("installatielocatie van de invoegtoepassing") aan te roepen om de installatiemap van de invoegtoepassing toe te voegen aan het DLL-zoekpad.
Aanvallen op basis van SearchPath
Een vergelijkbare aanval treedt op wanneer een toepassing de SearchPath-API gebruikt om een DLL te zoeken en het pad dat wordt geretourneerd door SearchPath dynamisch te laden. Hier volgt de standaardzoekvolgorde voor de SearchPath-API:
- De map waaruit de toepassing is geladen
- De huidige werkmap (CWD)
- De systeemmap
- De 16-bits systeemmap
- De Windows-map
- De mappen die worden vermeld in de omgevingsvariabele PATH
We raden dit patroon niet aan omdat het niet veilig is. We raden de functie SearchPath niet aan als methode voor het zoeken naar een .dll-bestand als het beoogde gebruik van de uitvoer een aanroep van de functie LoadLibrary is. Dit kan ertoe leiden dat de verkeerde .dll bestand wordt gevonden, omdat de zoekvolgorde van de functie SearchPath verschilt van de zoekvolgorde die wordt gebruikt door de functie LoadLibrary. Als u een .dll-bestand moet zoeken en laden, gebruikt u de functie LoadLibrary.
ShellExecute en CreateProcess
Variaties van deze problemen kunnen ook optreden wanneer ontwikkelaars vergelijkbare functies aanroepen, zoals ShellExecute en CreateProcess om externe uitvoerbare bestanden te laden. We raden ontwikkelaars aan voorzichtig te zijn met het laden van binaire bestanden en het volledig gekwalificeerde pad op te geven. Dit zou minder complex moeten zijn wanneer u een binair bestand laadt in plaats van een bibliotheek.
Aanbevolen stappen voor softwareontwikkelaars
We raden ontwikkelaars aan het volgende te doen:
Valideer hun toepassingen voor exemplaren van niet-beveiligde bibliotheekbelastingen (voorbeelden hiervan worden verderop in dit artikel gegeven). Deze omvatten de volgende:
- Het gebruik van SearchPath om de locatie van een bibliotheek of onderdeel te identificeren.
- Het gebruik van LoadLibrary om de versie van het besturingssysteem te identificeren.
Gebruik waar mogelijk volledig gekwalificeerde paden voor alle aanroepen naar LoadLibrary, CreateProcess en ShellExecute.
Implementeer aanroepen naar SetDllDirectory met een lege tekenreeks (') om de huidige werkmap te verwijderen uit de standaard-DLL-zoekvolgorde waar deze is vereist. Houd er rekening mee dat SetDllDirectory van invloed is op het hele proces. Daarom moet u dit één keer in het begin van de proces initialisatie doen, niet voor en na aanroepen naar LoadLibrary. Omdat SetDllDirectory van invloed is op het hele proces, kunnen meerdere threads die SetDllDirectory aanroepen met verschillende waarden ongedefinieerd gedrag veroorzaken. Als het proces is ontworpen om DLL's van derden te laden, moet u bovendien testen om te bepalen of het maken van een instelling voor het hele proces incompatibiliteit veroorzaakt. Een bekend probleem is dat wanneer een toepassing afhankelijk is van Visual Basic for Applications, een instelling voor het hele proces incompatibiliteit kan veroorzaken.
Gebruik de functie SetSearchPathMode om de zoekmodus voor een veilig proces in te schakelen voor het proces. Hiermee wordt de huidige werkmap verplaatst naar de laatste plaats in de SearchPath-zoeklijst voor de levensduur van het proces.
Vermijd het gebruik van SearchPath om te controleren op het bestaan van een DLL zonder een volledig gekwalificeerd pad op te geven, zelfs als de veilige zoekmodus is ingeschakeld, omdat dit nog steeds kan leiden tot DLL Preloading-aanvallen.
Richtlijnen voor het identificeren van niet-beveiligde bibliotheekbelastingen
In broncode zijn de volgende voorbeelden van niet-beveiligde bibliotheekladingen:
In het volgende codevoorbeeld zoekt de toepassing naar 'schannel.dll' met behulp van het minst veilige zoekpad. Als een aanvaller schannel.dll in CWD kan plaatsen, wordt deze geladen nog voordat de toepassing in de Windows-mappen naar de juiste bibliotheek zoekt.
DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); HMODULE handle = LoadLibrary(result);In het volgende codevoorbeeld probeert de toepassing de bibliotheek te laden vanuit de verschillende toepassings- en besturingssysteemlocaties die in het begin van dit document worden beschreven voor de LoadLibrary()-aanroep. Als er een risico bestaat dat het bestand niet aanwezig is, kan de toepassing proberen het bestand te laden vanuit de huidige werkmap. Dit scenario is iets minder gevaarlijk dan het vorige voorbeeld. De gebruiker van de toepassing wordt echter nog steeds blootgesteld aan risico's als de omgeving niet volledig voorspelbaar is.
HMODULE handle = LoadLibrary("schannel.dll");
Hier volgen voorbeelden van betere, veiligere bibliotheekbelastingen:
In het volgende codevoorbeeld wordt de bibliotheek rechtstreeks geladen met behulp van een volledig gekwalificeerde pad. Er is geen risico dat de aanvaller schadelijke code introduceert, tenzij hij al schrijfmachtigingen heeft voor de doelmap van de toepassing.
HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");Opmerking Zie de volgende resources voor informatie over het bepalen van de systeemmap:
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.aspxIn het volgende codevoorbeeld wordt de huidige werkmap verwijderd uit het zoekpad voordat LoadLibrary wordt aangeroepen. Dit vermindert het risico aanzienlijk, omdat de aanvaller de toepassingsmap, de Windows-map of alle mappen moet beheren die zijn opgegeven in het pad van de gebruiker om een DLL-aanval vooraf te kunnen gebruiken.
SetDllDirectory (""); HMODULE handle = LoadLibrary("schannel.dll");Op alle systemen waarop de beveiligingsupdate is geïnstalleerd 963027 (beschreven in MS09-014), wordt CWD met de volgende code definitief verplaatst naar de allerlaatste plek in de zoekvolgorde. Latere aanroepen naar de functie SetSearchPathMode vanuit dat proces die proberen de zoekmodus te wijzigen, mislukken.
SetDllDirectory (""); HMODULE handle = LoadLibrary("schannel.dll");In het volgende codevoorbeeld wordt de huidige werkmap verwijderd uit het zoekpad voordat LoadLibrary wordt aangeroepen. Dit vermindert het risico aanzienlijk, omdat de aanvaller de toepassingsmap, de Windows-map of alle mappen moet beheren die zijn opgegeven in het pad van de gebruiker om een dll-aanval vooraf te kunnen gebruiken.
SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT ); HMODULE handle = LoadLibrary("schannel.dll");
Procescontrole gebruiken om niet-beveiligde belasting dynamisch te detecteren
Microsoft publiceert een hulpprogramma met de naam Procescontrole. Met dit hulpprogramma kunnen ontwikkelaars en beheerders het gedrag van een actief proces nauwlettend volgen. Procescontrole kan worden gebruikt om dynamisch te detecteren of een van uw toepassingen mogelijk kwetsbaar is voor dit soort problemen.
Als u Process Monitor wilt downloaden, gaat u naar de volgende Microsoft-webpagina:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspxProbeer uw toepassing te starten met behulp van CWD ingesteld op een specifieke map. Dubbelklik bijvoorbeeld op een bestand met een extensie waarvan de bestandshandler is toegewezen aan uw toepassing.
Stel Process Monitor in met de volgende filters:
Als er een kwetsbaar pad wordt bereikt, ziet u iets dat vergelijkbaar is met het volgende:
De aanroep naar de externe bestandsshare om een DLL te laden geeft aan dat dit een kwetsbaar programma is.
Meer informatie
Ga naar de volgende Microsoft-webpagina's voor meer informatie:
Zoekvolgorde dynamische koppelingsbibliotheek
http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx MSDN-documentatie over de functie SearchPath
http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspx MSDN-documentatie over de functie LoadLibrary
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx MSDN-documentatie over de functie SetDllDirectory
http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspx MSDN-documentatie over de functie SetSearchPathMode
http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspx Blogbericht van David Leblanc, Principal Security Engineer bij Microsoft Office
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspx Blogbericht van Andrew Roths, MSRC Engineering-team over DLL-preloading-aanvallen