Der Support für Windows Vista Service Pack 1 (SP1) endet am 12. Juli 2011. Um weiterhin Sicherheitsupdates für Windows zu erhalten, müssen Sie Windows Vista mit Service Pack 2 (SP2) ausführen. Weitere Informationen finden Sie auf dieser Microsoft-Webseite: Support endet für einige Versionen von Windows.
Wenn eine Anwendung dynamisch eine Dynamic Link Library (DLL) lädt, ohne einen vollqualifizierten Pfad anzugeben, versucht Windows, die DLL zu finden, indem eine klar definierte Gruppe von Verzeichnissen durchsucht wird. Wenn ein Angreifer die Kontrolle über eines der Verzeichnisse erhält, kann er die Anwendung zwingen, eine schädliche Kopie der DLL anstelle der erwarteten DLL zu laden. Diese Angriffe werden als "DLL-Vorabladeangriffe" bezeichnet und gelten für alle Betriebssysteme, die das dynamische Laden freigegebener DLL-Bibliotheken unterstützen. Die Auswirkungen solcher Angriffe könnten sein, dass ein Angreifer Code im Kontext des Benutzers ausführen kann, der die Anwendung ausführt. Wenn die Anwendung als Administrator ausgeführt wird, kann dies zu einer lokalen Rechteerweiterung führen. Wir wissen um ein erneutes Interesse an diesen Angriffen. Um die Auswirkungen dieses Problems auf unsere gemeinsamen Kunden zu begrenzen, veröffentlichen wir dieses Dokument für die Entwicklercommunity, um sicherzustellen, dass sie über dieses Problem informiert sind und über die erforderlichen Tools verfügen, um das Problem in ihren Anwendungen zu beheben.
Zusammenfassung
Beschreibung der DLL-Vorabladeangriffe
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 linear durchsucht wird, die als DLL-Suchreihenfolge bezeichnet wird. Wenn Windows die DLL in der DLL-Suchreihenfolge findet, wird diese DLL geladen. Wenn Windows die DLL jedoch in keinem der Verzeichnisse in der DLL-Suchreihenfolge findet, gibt es einen Fehler an den DLL-Ladevorgang zurück. Im Folgenden finden Sie die DLL-Suchreihenfolge für die Funktionen LoadLibrary und LoadLibraryEx , die zum dynamischen Laden von DLLs verwendet werden:
- Das Verzeichnis, aus dem die Anwendung geladen wurde
- Das Systemverzeichnis
- Das 16-Bit-Systemverzeichnis
- Das Windows-Verzeichnis
- Das aktuelle Arbeitsverzeichnis (CWD)
- Die Verzeichnisse, die in der PATH-Umgebungsvariablen aufgeführt sind
Nehmen Sie folgendes Szenario an:
- Eine Anwendung lädt eine DLL ohne Angabe eines vollqualifizierten Pfads, den sie in der CWD der Anwendung erwartet.
- Die Anwendung ist vollständig darauf vorbereitet, den Fall zu behandeln, wenn sie die DLL nicht findet.
- Der Angreifer kennt diese Informationen über die Anwendung und steuert die CWD.
- Der Angreifer kopiert seine eigene, speziell gestaltete Version der DLL im CWD. Dies setzt voraus, dass der Angreifer dazu über die Berechtigung verfügt.
- Windows durchsucht die Verzeichnisse in der DLL-Suchreihenfolge und findet die DLL im CWD der Anwendung.
In diesem Szenario wird die speziell gestaltete 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 mithilfe einer leeren Zeichenfolge ("") aufrufen. Wenn eine Anwendung vom Laden einer DLL aus dem aktuellen Verzeichnis abhängt, rufen Sie das aktuelle Arbeitsverzeichnis ab, und verwenden Sie dieses, um einen vollqualifizierten Pfad von LoadLibrary zu übergeben.
Wir sind uns auch bewusst, dass einige Entwickler LoadLibrary verwenden, um zu überprüfen, ob eine bestimmte DLL vorhanden ist, um zu bestimmen, welche Version von Windows vom Benutzer ausgeführt wird. Sie sollten sich bewusst sein, dass dies die Anwendung anfällig machen könnte. Wenn die betroffene Bibliothek in der Windows-Version, auf der die Anwendung ausgeführt wird, tatsächlich nicht vorhanden ist, könnte ein Angreifer eine Bibliothek mit demselben Namen in CWD einführen. Es wird dringend davon abgeraten, diese Technik 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 nicht erzwingen kann, dass die Plug-Ins einen qualifizierten Pfad für ihre LoadLibrary-Aufrufe 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 den pfad dynamisch zu laden, der von SearchPath zurückgegeben wird. Im Folgenden sehen Sie die Standardsuchreihenfolge für die SearchPath-API:
- Das Verzeichnis, aus dem die Anwendung geladen wurde
- Das aktuelle Arbeitsverzeichnis (CWD)
- Das Systemverzeichnis
- Das 16-Bit-Systemverzeichnis
- Das Windows-Verzeichnis
- Die Verzeichnisse, die in der PATH-Umgebungsvariablen aufgeführt sind
Dieses Muster wird nicht empfohlen, da es nicht sicher ist. Die SearchPath-Funktion wird nicht als Methode zum Suchen einer .dll Datei empfohlen, wenn die beabsichtigte Verwendung der Ausgabe in einem Aufruf der LoadLibrary-Funktion erfolgt. Dies kann dazu führen, dass die falsche .dll Datei gesucht wird, da die Suchreihenfolge der SearchPath-Funktion von der von der LoadLibrary-Funktion verwendeten Suchreihenfolge abweicht. Wenn Sie eine .dll Datei suchen und laden müssen, verwenden Sie die LoadLibrary-Funktion.
ShellExecute und CreateProcess
Variationen dieser Probleme können auch auftreten, wenn Entwickler ähnliche Funktionen wie ShellExecute und CreateProcess aufrufen, um externe ausführbare Dateien zu laden. Entwickler sollten beim Laden von Binärdateien vorsichtig sein und den vollqualifizierten Pfad angeben. Dies sollte weniger Komplexität bedeuten, wenn Sie eine Binärdatei anstelle einer Bibliothek laden.
Empfohlene Schritte für Softwareentwickler
Es wird empfohlen, dass Entwickler die folgenden Schritte ausführen:
Überprüfen Sie ihre Anwendungen auf Instanzen von nicht sicheren Bibliotheksladevorgängen (Beispiele für diese werden weiter unten in diesem Artikel angegeben). Dazu gehören die Folgenden:
- Die Verwendung von SearchPath zum Identifizieren des Speicherorts einer Bibliothek oder Komponente.
- Die Verwendung von LoadLibrary zum Identifizieren der Version des Betriebssystems.
Verwenden Sie nach Möglichkeit vollqualifizierte Pfade für alle Aufrufe von LoadLibrary, CreateProcess und ShellExecute.
Implementieren Sie Aufrufe von SetDllDirectory mit einer leeren Zeichenfolge (""), um das aktuelle Arbeitsverzeichnis aus der standardmäßigen DLL-Suchreihenfolge zu entfernen, wo dies erforderlich ist. Beachten Sie, dass Sich SetDllDirectory auf den gesamten Prozess auswirkt. Daher sollten Sie dies einmal früh in der Prozessinitialisierung durchführen, nicht vor und nach Aufrufen von LoadLibrary. Da SetDllDirectory den gesamten Prozess beeinflusst, können mehrere Threads, die SetDllDirectory mit unterschiedlichen Werten aufrufen, zu nicht definiertem Verhalten führen. Wenn der Prozess für das Laden von Drittanbieter-DLLs konzipiert ist, müssen Außerdem Tests durchgeführt werden, um zu ermitteln, ob das Festlegen einer prozessweiten Einstellung zu Inkompatibilitäten führt. Ein bekanntes Problem besteht darin, 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 für sichere Prozesse für den Prozess zu aktivieren. Dadurch wird das aktuelle Arbeitsverzeichnis für die Lebensdauer des Prozesses an den letzten Platz in der SearchPath-Suchliste verschoben.
Vermeiden Sie die Verwendung von SearchPath, um zu überprüfen, ob eine DLL vorhanden ist, ohne einen vollqualifizierten Pfad anzugeben, auch wenn der sichere Suchmodus aktiviert ist, da dies weiterhin zu DLL Preloading-Angriffen führen kann.
Leitfaden zum Identifizieren unsicherer Bibliotheksladevorgänge
Im Quellcode sind die folgenden Beispiele für nicht sichere Bibliotheksladevorgänge aufgeführt:
Im folgenden Codebeispiel sucht die Anwendung unter Verwendung des am wenigsten sicheren Suchpfads nach "schannel.dll". Wenn ein Angreifer schannel.dll in CWD platzieren kann, wird es geladen, noch bevor die Anwendung die Windows-Verzeichnisse 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 Betriebssystemspeicherorten zu laden, die am Anfang dieses Dokuments für den LoadLibrary()-Aufruf beschrieben wurden. Wenn das Risiko besteht, 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 im vorherigen Beispiel. Es setzt jedoch weiterhin ein Risiko für den Anwendungsbenutzer aus, wenn die Umgebung nicht vollständig vorhersagbar ist.
HMODULE handle = LoadLibrary("schannel.dll");
Im Folgenden sind Beispiele für bessere und sicherere Bibliotheksladevorgänge aufgeführt:
Im folgenden Codebeispiel wird die Bibliothek direkt über einen vollqualifizierten Pfad geladen. Es besteht kein Risiko, dass der Angreifer schädlichen Code einführt, 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.aspx SHGetKnownFolderPath
http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspxIm folgenden Codebeispiel wird das aktuelle Arbeitsverzeichnis aus dem Suchpfad entfernt, bevor LoadLibrary aufgerufen wird. 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, die Sicherheitsupdates 963027 installiert haben (beschrieben in MS09-014), würde der folgende Code CWD dauerhaft an den letzten Platz in der Suchreihenfolge verschieben. Alle späteren Aufrufe der SetSearchPathMode-Funktion innerhalb dieses Prozesses, die versuchen, den Suchmodus zu ändern, schlagen fehl.
SetDllDirectory (""); HMODULE handle = LoadLibrary("schannel.dll");Im folgenden Codebeispiel wird das aktuelle Arbeitsverzeichnis aus dem Suchpfad entfernt, bevor LoadLibrary aufgerufen wird. 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.
SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT ); HMODULE handle = LoadLibrary("schannel.dll");
Verwenden des Prozessmonitors zum dynamischen Erkennen unsicherer Lasten
Microsoft veröffentlicht ein Tool mit dem Namen Prozessmonitor. Mit diesem Tool können Entwickler und Administratoren das Verhalten eines ausgeführten Prozesses genau nachverfolgen. Der Prozessmonitor kann verwendet werden, um dynamisch zu erkennen, ob eine Ihrer Anwendungen für diese Art von Problem anfällig ist.
Um den Prozessmonitor herunterzuladen, besuchen Sie die folgende Microsoft-Webseite:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspxVersuchen Sie, Ihre Anwendung zu starten, indem Sie CWD verwenden, die auf ein bestimmtes Verzeichnis festgelegt ist. Doppelklicken Sie beispielsweise auf eine Datei mit einer Erweiterung, deren Dateihandler Ihrer Anwendung zugewiesen ist.
Richten Sie den Prozessmonitor mit den folgenden Filtern ein:
Wenn ein anfälliger Pfad erreicht wird, sehen Sie etwas, das dem folgenden ähnelt:
Der Aufruf der Remotedateifreigabe zum Laden einer DLL zeigt an, dass es sich um ein anfälliges Programm handelt.
Weitere Informationen
Weitere Informationen finden Sie auf den folgenden Microsoft-Webseiten:
Dynamic Link Library-Suchreihenfolge
http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx MSDN-Dokumentation zur SearchPath-Funktion
http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspx MSDN-Dokumentation zur LoadLibrary-Funktion
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx MSDN-Dokumentation zur SetDllDirectory-Funktion
http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspx MSDN-Dokumentation zur SetSearchPathMode-Funktion
http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspx Blogbeitrag von David Leblanc, Principal Security Engineer bei Microsoft Office
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspx Blogbeitrag von Andrew Roths, MSRC Engineering-Team zu DLL-Vorabladeangriffen