Sicheres Laden von Bibliotheken, um DLL-Vorabladeangriffe zu verhindern

Der Support Windows Vista Service Pack 1 (SP1) endet am 12. Juli 2011. Wenn Sie weiterhin Sicherheitsupdates für Windows erhalten möchten, stellen Sie sicher, dass Sie Windows Vista mit Service Pack 2 (SP2) ausführen. Weitere Informationen finden Sie auf dieser Microsoft-Webseite: Der Support für einige Versionenvon Windows.

Wenn eine Anwendung eine DLL (Dynamic Link Library) dynamisch lädt, ohne einen vollqualifizierten Pfad anzugeben, versucht Windows, die DLL zu finden, indem ein klar definierter Satz von Verzeichnissen durchsucht wird. Wenn ein Angreifer die Kontrolle über eines der Verzeichnisse erhält, kann er die Anwendung erzwingen, eine schädliche Kopie der DLL zu laden, statt sie erwartet. Diese Angriffe werden als "DLL-Vorabladeangriffe" bezeichnet und werden für alle Betriebssysteme verwendet, die das dynamische Laden freigegebener DLL-Bibliotheken unterstützen. Der Effekt solcher Angriffe kann sein, dass ein Angreifer Code im Kontext des Benutzers ausführen kann, der die Anwendung ausführen soll. Wenn die Anwendung als Administrator ausgeführt wird, kann dies zu einer lokalen Berechtigungserweiterung führen. Wir wissen über das verlängerte Interesse an diesen Angriffen. Um die Auswirkungen dieses Problems auf unsere gemeinsamen Kunden zu beschränken, veröffentlichen wir dieses Dokument für die Entwicklergemeinschaft, um sicherzustellen, dass sie dieses Problem kennen und über die notwendigen Tools verfügen, um das Problem in ihren Anwendungen zu beheben.

Zusammenfassung

Beschreibung von DLL-Vorabladeangriffen

LoadLibrary-basierte Angriffe

Wenn eine Anwendung eine DLL dynamisch lädt, ohne einen vollqualifizierten Pfad anzugeben, versucht Windows, diese DLL zu finden, indem eine klar definierte Gruppe von Verzeichnissen, die als DLL-Suchreihenfolge bezeichnet werden, linear durchsucht wird. Wenn Windows DLL in der DLL-Suchreihenfolge sucht, wird diese DLL geladen. Wenn die Windows DLL jedoch nicht in einem der Verzeichnisse in der DLL-Suchreihenfolge gefunden wird, führt dies zu einem Fehler beim DLL-Ladevorgang. Es folgt die DLL-Suchreihenfolge für die Funktionen LoadLibraryund LoadLibraryEx,die zum dynamischen Laden von DLLs verwendet werden:

  1. Das Verzeichnis, aus dem die Anwendung geladen wurde

  2. Im Systemverzeichnis

  3. Im 16-Bit-Systemverzeichnis

  4. Im Windows-Verzeichnis

  5. Im aktuellen Arbeitsverzeichnis

  6. Die Verzeichnisse, die in der Path-Umgebungsvariablen aufgelistet sind



Beachten Sie das folgende Szenario:


  • Eine Anwendung lädt eine DLL, ohne einen vollqualifizierten Pfad anzugeben, den sie im CWD der Anwendung erwartet.

  • Die Anwendung ist vollständig für die Verarbeitung des Falls vorbereitet, wenn sie die DLL nicht findet.

  • Der Angreifer kennt diese Informationen über die Anwendung und steuert das CWD.

  • Der Angreifer kopiert seine eigene, eigens entwickelte Version der DLL im CWD. Dabei wird davon ausgegangen, dass der Angreifer über die Berechtigung dazu verfügt.

  • Windows die Verzeichnisse in der DLL-Suchreihenfolge durchsucht, und die DLL wird im CWD der Anwendung gefunden.

In diesem Szenario wird die speziell hergestellte DLL innerhalb der Anwendung ausgeführt und erhält die Berechtigungen des aktuellen Benutzers.

Empfehlung Um diesen Angriff zu verhindern, können Anwendungen das aktuelle Arbeitsverzeichnis (CWD) aus dem DLL-Suchpfad entfernen, indem sie die
SetDllDirectory-API mit einer leeren Zeichenfolge
("") aufrufen. Wenn eine Anwendung davon abhängt, dass eine DLL aus dem aktuellen Verzeichnis geladen wird, rufen Sie das aktuelle Arbeitsverzeichnis ab, und übergeben Sie damit einen vollqualifizierten Pfad von LoadLibrary.



Wir wissen auch, dass einige Entwickler LoadLibrary verwenden, um zu überprüfen, ob eine bestimmte DLL vorhanden ist, um zu ermitteln, welche Windows-Version vom Benutzer ausgeführt wird. Beachten Sie, dass die Anwendung dadurch anfällig werden könnte. Wenn die betroffene Bibliothek tatsächlich nicht auf der Windows-Version vorhanden ist, für die die Anwendung ausgeführt wird, könnte ein Angreifer eine Bibliothek mit demselben Namen in CWD einführen. Wir empfehlen dringend, dieses Verfahren zu verwenden. Verwenden Sie stattdessen die empfohlenen Techniken, die im MSDN-Artikel "Abrufen der Systemversion" beschrieben werden.

Eine Anwendung, die Plug-Ins von Drittanbietern lädt und die Plug-Ins nicht dazu zwingen kann, für ihre LoadLibrary-Aufrufe einen qualifizierten Pfad zu verwenden, sollte SetDllDirectory("") aufrufen, um CWD zu entfernen, und dann SetDllDirectory("Plug-In-Installationsspeicherort") aufrufen, um das Plug-In-Installationsverzeichnis dem DLL-Suchpfad hinzuzufügen.

SearchPath-basierte Angriffe

Ein ähnlicher Angriff liegt vor, wenn eine Anwendung die SearchPath-API verwendet, um eine DLL zu suchen und dynamisch den Pfad zu laden, der von SearchPath zurückgegeben wird. Es folgt die Standardsuchreihenfolge für die SearchPath-API:

  • Das Verzeichnis, aus dem die Anwendung geladen wurde

  • Im aktuellen Arbeitsverzeichnis

  • Im Systemverzeichnis

  • Im 16-Bit-Systemverzeichnis

  • Im Windows-Verzeichnis

  • Die Verzeichnisse, die in der Path-Umgebungsvariablen aufgelistet sind

Dieses Muster wird nicht empfohlen, da es nicht sicher ist. Die SearchPath-Funktion wird nicht als Methode zum Auffinden einer .dll-Datei empfohlen, wenn die beabsichtigte Verwendung der Ausgabe in einem Aufruf der LoadLibrary-Funktion besteht. Dies kann dazu führen, dass die falsche .dll gefunden wird, da sich die Suchreihenfolge der SearchPath-Funktion von der Suchreihenfolge unterscheidet, die von der LoadLibrary-Funktion verwendet wird. Wenn Sie eine Datei suchen und laden .dll, verwenden Sie die LoadLibrary-Funktion.

ShellExecute und CreateProcess


Variationen dieser Probleme können auch auftreten, wenn Entwickler ähnliche Funktionen wie ShellExecuteund CreateProcessaufrufen, um externe ausführbare Dateien zu laden. Es wird empfohlen, dass Entwickler beim Laden von Binärdateien vorsichtig sind und den vollqualifizierten Pfad angeben. Dies sollte weniger Komplex sein, wenn Sie eine Binärdatei anstelle einer Bibliothek laden.

Empfohlene Schritte für Softwareentwickler

Wir empfehlen Entwicklern, folgende Schritte zu verwenden:

  • Überprüfen Sie ihre Anwendungen auf Instanzen von nicht unsicheren Bibliotheks laden (Beispiele für diese finden Sie weiter später in diesem Artikel). Hierzu zählen:

    • Die Verwendung von SearchPath zum Identifizieren des Speicherorts einer Bibliothek oder Komponente.

    • Die Verwendung von LoadLibrary zum Identifizieren der Version des Betriebssystems.

  • Verwenden Sie vollqualifizierte Pfade für alle Aufrufe von LoadLibrary, CreateProcess und ShellExecute, wo Sie können.

  • Implementieren Sie Aufrufe von SetDllDirectory mit einer leeren Zeichenfolge (""), um das aktuelle Arbeitsverzeichnis aus der dll-Standardsuchreihenfolge zu entfernen, in der dies erforderlich ist. Beachten Sie, dass SetDllDirectory sich auf den gesamten Prozess auswirkt. Daher sollten Sie dies ein Mal früh in der Prozess initialisierung tun, nicht vor und nach dem Aufruf von LoadLibrary. Da SetDllDirectory sich auf den gesamten Prozess auswirkt, können mehrere Threads, die SetDllDirectory mit unterschiedlichen Werten aufrufen, ein undefiniertes Verhalten verursachen. Wenn der Prozess zum Laden von DRITTANBIETER-DLLs konzipiert ist, ist außerdem ein Test erforderlich, um festzustellen, ob eine prozessweite Einstellung Zu Inkompatibilitäten verursacht. Ein bekanntes Problem ist, dass eine prozessweite Einstellung zu Inkompatibilitäten führen kann, wenn eine Anwendung von Visual Basic for Applications abhängig ist.

  • Verwenden Sie die SetSearchPathMode-Funktion,um den Suchmodus eines sicheren Prozesses für den Prozess zu aktivieren. Dadurch wird das aktuelle Arbeitsverzeichnis an die letzte Stelle in der SearchPath-Suchliste für die Lebensdauer des Prozesses bewegt.

  • Verwenden Sie SearchPath nicht, um das Vorhandensein einer DLL zu überprüfen, ohne einen vollqualifizierten Pfad anzugeben, auch wenn der abgesicherte Suchmodus aktiviert ist, da dies trotzdem zu DLL-Vorabladeangriffen führen kann.

Leitfaden zum Identifizieren von nicht unsicheren Bibliotheks laden

Im Quellcode sind die folgenden Beispiele für nicht unsichere Laden von Bibliotheken enthalten:

  • Im folgenden Codebeispiel sucht die Anwendung nach "schannel.dll" unter Verwendung des am wenigsten sicheren Suchpfads. Wenn ein Angreifer ein Dokument schannel.dll CWD platzieren kann, wird es geladen, noch bevor die Anwendung die Windows Nach der entsprechenden Bibliothek durchsucht.

    DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); 
    HMODULE handle = LoadLibrary(result);
  • Im folgenden Codebeispiel versucht die Anwendung, die Bibliothek aus den verschiedenen Anwendungs- und Betriebssystemstandorten zu laden, die am Anfang dieses Dokuments für den LoadLibrary()-Aufruf beschrieben sind. Besteht das Risiko, dass die Datei nicht vorhanden ist, versucht die Anwendung möglicherweise, die Datei aus dem aktuellen Arbeitsverzeichnis zu laden. Dieses Szenario ist etwas weniger gefährlich als das vorherige Beispiel. Es macht den Anwendungsbenutzer jedoch trotzdem einem Risiko ausgesetzt, wenn die Umgebung nicht vollständig vorhersagbar ist.

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




Im Folgenden finden Sie Beispiele für bessere, sicherere Laden von Bibliotheken:

  • Im folgenden Codebeispiel wird die Bibliothek direkt mithilfe eines vollqualifizierten Pfads geladen. Es besteht kein Risiko, dass der Angreifer schädlichen Code einleitiert, es sei denn, er verfügt bereits über Schreibberechtigungen für das Zielverzeichnis der Anwendung.

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



    Hinweis Informationen zum Ermitteln des Systemverzeichnisses finden Sie in den folgenden

    Ressourcen: GetSystemDirectory

    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

  • Im folgenden Codebeispiel wird das aktuelle Arbeitsverzeichnis aus dem Suchpfad entfernt, bevor LoadLibrary aufruft. Dadurch wird das Risiko erheblich reduziert, da der Angreifer entweder das Anwendungsverzeichnis, das Windows-Verzeichnis oder alle Verzeichnisse steuern müsste, die im Pfad des Benutzers angegeben sind, um einen DLL-Vorabladeangriff zu verwenden.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • Auf allen Systemen mit dem Sicherheitsupdate 963027 (beschrieben in MS09-014)würde CWD mit dem folgenden Code dauerhaft an den letzten Punkt in der Suchreihenfolge verschieben. Alle späteren Aufrufe der SetSearchPathMode-Funktion innerhalb dieses Prozesses, die versuchen, den Suchmodus zu ändern, führen zu einem Fehler.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • Im folgenden Codebeispiel wird das aktuelle Arbeitsverzeichnis aus dem Suchpfad entfernt, bevor LoadLibrary aufruft. Dies verringert das Risiko erheblich, da der Angreifer entweder das Anwendungsverzeichnis, das Windows-Verzeichnis oder alle Verzeichnisse steuern müsste, die im Pfad des Benutzers angegeben sind, um einen DLL-Vorabladeangriff zu verwenden.

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

Verwenden der Prozessüberwachung zum dynamischen Erkennen nicht unsicherer Ladelasten

Microsoft veröffentlicht ein Tool mit dem Namen Prozessüberwachung. Mit diesem Tool können Entwickler und Administratoren das Verhalten eines laufenden Prozesses genau verfolgen. Die Prozessüberwachung kann verwendet werden, um dynamisch zu erkennen, ob eine Ihrer Anwendungen anfällig für diese Art von Problem ist.

  • Zum Herunterladen des Prozessmonitors besuchen Sie die folgende Microsoft-Webseite:

    http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

  • Versuchen Sie, Ihre Anwendung zu starten, indem Sie CWD auf ein bestimmtes Verzeichnis festlegen. Doppelklicken Sie beispielsweise auf eine Datei mit einer Erweiterung, deren Dateihandler Ihrer Anwendung zugewiesen ist.

  • Richten Sie den Prozessmonitor mit den folgenden Filtern ein:



    Alternativtext

  • Wenn ein anfälliger Pfad betroffen ist, wird etwas ähnliches wie das folgende angezeigt: AlternativtextDer Aufruf der Remotedateifreigabe zum Laden einer DLL weist darauf hin, dass es sich um ein angreifbares Programm

    handelt.

Weitere Informationen

Weitere Informationen finden Sie auf den folgenden Microsoft-Webseiten:

Suchreihenfolge der Dynamic Link Library

http://msdn.microsoft.com/en-de/library/ms682586(VS.85).aspxMSDN-Dokumentation zur SearchPath-Funktion

http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspxMSDN-Dokumentation zur LoadLibrary-Funktion

http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspxMSDN-Dokumentation zur SetDllDirectory-Funktion

http://msdn.microsoft.com/en-de/library/ms686203(VS.85).aspxMSDN-Dokumentation zur SetSearchPathMode-Funktion

http://msdn.microsoft.com/en-de/library/dd266735(VS.85).aspxBlogbeitrag von David Leblanc, Principal Security Engineer bei Microsoft Office

http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspxBlogbeitrag von Andrew Eines, MSRC-Entwicklungsteam zum Vorabladen von DLL-Angriffen

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

Weitere Informationsquellen

Benötigen Sie weitere Hilfe?

Ihre Office-Fähigkeiten erweitern
Schulungen erkunden
Neue Funktionen als Erster erhalten
Microsoft Insider beitreten

War diese Information hilfreich?

Vielen Dank für Ihr Feedback!

Vielen Dank für Ihr Feedback. Es klingt, als ob es hilfreich sein könnte, Sie mit einem unserer Office-Supportmitarbeiter zu verbinden.

×