
Machen Sie DLL-Hijacking ganz einfach zur Waffe. Bauen Sie eine Hintertür in jede Funktion einer beliebigen DLL ein.

DllShimmer parst die ursprüngliche DLL und extrahiert Informationen über exportierte Funktionen (Name, Ordnungszahl und Weiterleitungsinformationen). Basierend auf diesen Informationen erstellt DllShimmer eine Boilerplate-C++-Datei (.cpp). Die generierte Datei ermöglicht es Ihnen, jeder Funktion, die aus der ursprünglichen DLL exportiert wird, eigenen Code hinzuzufügen, ohne den normalen Betrieb des Programms zu stören. Es ist kein Reverse Engineering oder Instrumentierung erforderlich, da DllShimmer nicht auf Funktionssignaturen angewiesen ist (siehe dazu „Einschränkungen“).
Die zweite generierte Datei ist eine .def-Datei, die sicherstellt, dass alle aus dem Proxy nach der Kompilierung exportierten DLLs dieselben Namen und Ordnungszahlen wie in der ursprünglichen DLL haben.
Nach der Kompilierung ist die EAT in der Proxy-DLL eine exakte Kopie der EAT in der ursprünglichen DLL. Alle Namen und Ordnungszahlen exportierter Funktionen stimmen überein, und weitergeleitete Funktionen werden ebenfalls weitergeleitet. DllShimmer leitet nicht explizit alle Funktionen weiter (wie die meisten Tools), wodurch eine völlig neue und verdächtige EAT-Struktur entsteht.
Kompilieren Sie den Go-Quellcode oder laden Sie die kompilierte Binärdatei herunter.
Abhängigkeiten:
x86_64-w64-mingw32-g++x86_64-w64-mingw32-dlltoolBeispiel:
# Backdoor version.dll (proxy to absolute path)
./DllShimmer -i version.dll -o project/ -x "C:/Windows/System32/version.dll" -m
# Backdoor random chat.dll (proxy to relative path)
./DllShimmer -i chat.dll -o project/ -x "lib/chat2.dll" -m
# Backdoor random app.dll (static linking to the original DLL)
./DllShimmer -i app.dll -o project/ -x "app2.dll" -m --static
Parameter:
-i / --input <path> [erforderlich]
Die ursprüngliche DLL, die Sie mit einem Hintertürchen versehen möchten.
-o / --output <path> [erforderlich]
Der Pfad zu dem Verzeichnis, in dem DllShimmer alle generierten Dateien speichert.
-x / --original <path> [erforderlich]
Im Fall der dynamischen Verknüpfung (Standard) geben Sie den Pfad an, unter dem die Proxy-DLL die ursprüngliche DLL auf dem Zielsystem findet.
Bei statischer Verknüpfung (--static) geben Sie nur den Namen der ursprünglichen DLL an. Sie wird gemäß der Standard-Ladereihenfolge unter Windows gesucht.
-m / --mutex [optional]
Wenn Sie diese Option aktivieren, wird der Quelldatei ein Mutex hinzugefügt, der verhindert, dass Ihr Hintertürchen während eines einzelnen Programmlaufs mehr als einmal ausgeführt wird. Alle ursprünglichen Funktionen funktionieren weiterhin normal.
--static [optional]
Aktiviert die statische Verknüpfung zwischen der Proxy-DLL (IAT) und der ursprünglichen DLL (EAT). Dadurch wird eine zusätzliche .lib-Datei im Ausgabeverzeichnis erzeugt, die bei der statischen Kompilierung als ursprüngliche DLL fungiert.
Diese Technik hat im Vergleich zur dynamischen Verknüpfung einige ernsthafte Einschränkungen:
Allerdings kann die statische Verknüpfung in einigen Szenarien unauffälliger und natürlicher sein.
Standard: DllShimmer verwendet immer dynamische Verknüpfung mit den Funktionen LoadLibraryA() und GetProcAddress().
--debug-file <path> [optional]
Speichert Debug-Logs in einer Datei. Die Logs werden während der Laufzeit des Programms fortlaufend in eine Datei geschrieben. Wenn diese Option ausgewählt ist, werden die Logs nicht auf STDOUT ausgegeben.
Standard: DllShimmer schreibt Debug-Logs immer auf STDOUT.
Beispiel für Debug-Ausgabe:

Bevor Sie mit der Fehlerbehebung beginnen:
--static) verwenden. Mit dynamischer Verknüpfung (Standard) lassen sich Fehler leichter beheben.--debug-file)..cpp-Datei sehe ich nicht alle exportierten Funktionen der ursprünglichen DLL.Funktionen, die in der ursprünglichen DLL als „weitergeleitet“ (forwarded) definiert sind, sind nicht in der .cpp-Datei enthalten. Sie sind jedoch in der .def-Datei sichtbar. Sie werden nach der Kompilierung ebenfalls genau wie in der ursprünglichen DLL exportiert.
Manchmal zeigt Ihre Proxy-DLL beim Laden der ursprünglichen DLL einen Fehler an, und der Fehlercode lautet 126, obwohl Sie theoretisch den richtigen relativen Pfad im Parameter -x angegeben haben. Warum funktioniert das nicht?!?
DLLs werden im Current Directory gesucht. In 98 % der Fälle ist dies einfach der Speicherort der Haupt-EXE-Datei, aber es gibt Programme (meist alte Legacy-Programme), die das Current Directory willkürlich ändern, z. B. mit SetCurrentDirectoryW(). Das Hauptprogramm ist sich dieser Änderung bewusst, sodass es Ihre Proxy-DLL korrekt lädt, aber Sie wissen nichts davon und versuchen, die ursprüngliche DLL relativ zu laden, während das Programm in dem geänderten Current Directory nach ihr sucht.
Diese Regel gilt sowohl für das statische als auch für das dynamische Laden der ursprünglichen DLL. Leider ist dieses Problem bei statischer Verknüpfung viel schwerer zu erkennen, da wir keine Debug-Informationen haben. Der Systemlader schlägt einfach fehl, und das war es. Deshalb empfehle ich immer, zuerst die standardmäßige dynamische Verknüpfung zu verwenden.
Bei dynamischer Verknüpfung haben wir zwei Möglichkeiten:
-x an die neue Situation des Current Directory an.Current Directory dynamisch, um DLLs dort zu suchen, wo wir es möchten.Bei statischer Verknüpfung haben wir wirklich nur eine Möglichkeit:
Current Directory.