Windows-Testbuild
Linux-Testbuild
Drltrace ist ein dynamischer API-Aufruf-Tracer für Windows- und Linux-Anwendungen. Drltrace basiert auf dem dynamischen Binärinstrumentierungs-Framework DynamoRIO. Drltrace wurde ursprünglich von Derek Bruening implementiert und mit den Frameworks DynamoRIO und DrMemory vertrieben. Dieses Repository enthält eine eigenständige Version von drltrace mit zusätzlichen Skripten und Materialien zur Verwendung für die Malware-Analyse. Der Release-Build kann hier heruntergeladen werden.
Die Verwendung von drltrace ist sehr einfach. Ein Benutzer muss ein Protokollverzeichnis und einen Namen eines Zielprozesses wie folgt angeben:
drltrace -logdir . -- calc.exe
Das ist alles, das Tool fügt die erforderlichen DLLs in den Zielprozess ein, startet die Instrumentierung und protokolliert parallel Informationen über alle Bibliotheksaufrufe, die im Zielprozess ausgeführt werden:
~~43600~~ msvcrt.dll!__wgetmainargs
arg 0: 0x010d2364
arg 1: 0x010d2368
and return to module id:0, offset:0x193a
~~43600~~ ntdll.dll!EtwEventRegister
arg 0: 0x002ff994
arg 1: 0x010d1490
and return to module id:0, offset:0x157e
~~43600~~ ntdll.dll!EtwEventSetInformation
arg 0: 0x007b4b40
arg 1: 0x00000033
and return to module id:0, offset:0x15a1
~~43600~~ SHELL32.dll!ShellExecuteW
arg 0: <null> (type=<unknown>, size=0x0)
arg 1: <null> (type=wchar_t*, size=0x0)
arg 2: calculator:// (type=wchar_t*, size=0x0)
arg 3: <null> (type=wchar_t*, size=0x0)
arg 4: <null> (type=wchar_t*, size=0x0)
arg 5: 0x1 (type=int, size=0x4)
and return to module id:0, offset:0x167d
Das Format der Ausgabe ist einfach und kann problemlos von einem externen Skript analysiert werden:
~~[thread id]~~ [dll name]![api call name]
arg [arg #]: [value] (type=[Windows type name], size=[size of arg])
and return to module id:[module unique id], offset:[offset in memory]
Das Parsen mit grep
kann durchgeführt werden, wenn das Argument -grepable
verwendet wird; Dies gibt die Funktionsnamen und Argumente alle in einer Zeile aus:
~~4824~~ KERNELBASE.dll!CreateFileW {0: C:WindowsFontsstaticcache.dat (type=wchar_t*, size=0x0)} {1: 0x80000000 (type=DWORD, size=0x4)} {2: 0x3 (type=DWORD, size=0x4)} {3: 0x005cde8c (type=<unknown>*, size=0x0)} {4: 0x3 (type=DWORD, size=0x4)} {5: 0x80 (type=DWORD, size=0x4)}
Die Tabelle der eindeutigen Modulidentifikatoren wird am Ende der Protokolldatei gedruckt:
Module Table: version 3, count 70
Columns: id, containing_id, start, end, entry, checksum, timestamp, path
0, 0, 0x010d0000, 0x010da000, 0x010d1b80, 0x0000f752, 0xb5fe3575, C:WindowsSysWOW64calc.exe
1, 1, 0x6d4c0000, 0x6d621000, 0x6d563940, 0x00136d65, 0x59ce1b0b, C:UsersMaxDownloadsdrltracedrltracedynamoriolib32releasedynamorio.dll
2, 2, 0x73800000, 0x73975000, 0x7380dbf7, 0x00000000, 0x59ce1b0f, C:UsersMaxDownloadsdrltracedrltracebinrelease/drltracelib.dll
3, 3, 0x742f0000, 0x742fa000, 0x742f2a00, 0x0000c877, 0x0adc52c1, C:WindowsSystem32CRYPTBASE.dll
4, 4, 0x74300000, 0x74320000, 0x7430c9b0, 0x0002c617, 0x245970b4, C:WindowsSystem32SspiCli.dll
5, 5, 0x74410000, 0x74431000, 0x74416900, 0x0002a940, 0x88a53c1d, C:WindowsSystem32GDI32.dll
6, 6, 0x74440000, 0x74500000, 0x7446fb20, 0x000cc410, 0xd343d532, C:WindowsSystem32RPCRT4.dll
7, 7, 0x74500000, 0x74525000, 0x745047d0, 0x00026737, 0xa39c8991, C:WindowsSystem32IMM32.DLL
8, 8, 0x74550000, 0x745c7000, 0x7456e8a0, 0x00081857, 0x73b971e1, C:WindowsSystem32advapi32.dll
9, 9, 0x748f0000, 0x74929000, 0x748febd0, 0x00045303, 0xa58be652, C:WindowsSystem32cfgmgr32.dll
10, 10, 0x74930000, 0x75c78000, 0x74aa09d0, 0x01377aa6, 0x4b39926b, C:WindowsSystem32SHELL32.dll
Drltrace kann problemlos Interbibliotheksaufrufe herausfiltern und nur API-Aufrufe drucken, die vom Hauptmodul (oder von einem Heap) einer Zielanwendung ausgeführt werden, indem die Option -only_from_app
angegeben wird, was bei Anwendungen, die große Protokolle generieren, sehr nützlich ist. Für eine detailliertere Steuerung ermöglicht die Option -filter
dem Benutzer, eine Filterkonfigurationsdatei anzugeben, um bestimmte Funktionen auf der Whitelist zu filtern oder Funktionen auf der Blacklist zu ignorieren (Beispiele finden Sie in der Datei filter.config ). Drltrace verfügt außerdem über mehrere nützliche externe Skripte, um API-Aufrufe für bestimmte Bibliotheken zu filtern und nur potenziell interessante API-Aufrufe und Zeichenfolgen auszugeben.
Die Hauptmodule von Drltrace werden unter BSD vertrieben.
Einige für drltrace erforderliche Dateien werden unter LGPL verteilt. Weitere Informationen finden Sie in den Quelldateien.
Die Analyse von Malware ist keine leichte Aufgabe. Hochentwickelte Software-Packer wie Themida und Armadillo und natürlich Dutzende namenloser Packer, die von Malware-Autoren geschrieben wurden, sowie Code- und Datenverschlüsselung erleichtern das statische Reverse Engineering solcher Proben erheblich (in manchen Fällen sogar völlig unmöglich), was das Leben von Malware-Analysten kompliziert macht. In einem solchen Fall kann die Nachverfolgung von API-Aufrufen die Zeit, die erforderlich ist, um eine tatsächliche böswillige Absicht zu verstehen, erheblich verkürzen und viele technische Details über geschützten bösartigen Code offenlegen.
Während die traditionelle Technik des API-Hooking in mehreren Lösungen erfolgreich implementiert wurde, ist der Ansatz von Malware-Autoren gut untersucht und kann leicht erkannt und/oder umgangen werden. Darüber hinaus werden diese Tools als eigenständige, umfangreiche GUI-Anwendungen (als proprietäre Produkte) vertrieben, die oft nicht einfach in den vorhandenen Malware-Analyse-Workflow zu integrieren sind.
Wenn wir uns die Linux-Welt ansehen, gibt es ein wunderbares Tool namens ltrace. Mit einem einzigen Bash-Befehl können wir ganz einfach den vollständigen Trace der API-Aufrufe einer bestimmten ausführbaren Datei abrufen.
Warum haben wir nicht ein solches Tool (wie ltrace unter Linux) für Windows, das auch gegenüber Anti-Research-Tricks moderner Malware transparent ist?
Es stellt sich heraus, dass es eine Technik gibt, die uns dabei helfen kann, ein solches Tool für Windows zu haben und API-Aufrufe transparent für ausgeführte Programme zu verfolgen. Diese Technik wird als dynamische binäre Instrumentierung, auch DBI genannt, bezeichnet. DBI ist eine Technik zur Analyse des Verhaltens einer Binäranwendung zur Laufzeit durch die Injektion von Instrumentierungscode.
Die Anwendung von DBI für die Malware-Analyse wird jedoch zu Unrecht durch die Entpackungsautomatisierung und mehrere Proofs of Concepts für Anweisungen, Basisblöcke und Funktionsaufrufverfolgung eingeschränkt. Soweit wir wissen, handelt es sich bei drltrace um ein erstes Tool zur API-Aufrufverfolgung auf Basis von DBI, das in der Praxis zur Malware-Analyse eingesetzt werden kann. Wir haben in unserem Wiki mehrere Beispiele für Malware-Analysen bereitgestellt, in denen wir beschrieben haben, wie drltrace es ermöglichte, in wenigen Minuten viele interne technische Details über hochentwickelte bösartige Beispiele zu entdecken, ohne IDA oder Debugger überhaupt zu starten.
-logdir [ .] Log directory to print library call data
-only_from_app [ false] Reports only library calls from the app
-follow_children [ true] Trace child processes
-print_ret_addr [ false] Print library call's return address
-num_unknown_args [ 2] Number of unknown libcall args to print
-num_max_args [ 6] Maximum number of arguments to print
-default_config [ true] Use default config file.
-config [ ""] The path to custom config file.
-filter [filter.config] The path of the whitelist/blacklist file.
-ignore_underscore [ false] Ignores library routine names starting with "_".
-help [ false] Print this message.
-version [ false] Print version number.
-verbose [ 1] Change verbosity.
-use_config [ true] Use config file
-grepable [ false] Grepable output
Drltrace unterstützt externe Konfigurationsdateien, in denen ein Benutzer beschreiben kann, wie drltrace Argumente für bestimmte API-Aufrufe drucken soll.
HANDLE|CreateRemoteThread|HANDLE|SECURITY_ATTRIBUTES*|size_t|THREAD_START_ROUTINE*|VOID*|DWORD|__out DWORD*
Jedes Funktionsargument sollte durch |
getrennt werden . Das erste Argument ist der Rückgabetyp, das zweite Argument ist ein Funktionsname selbst und der Rest sind die Funktionsargumente. Ein Token __out
wird zum Markieren von Ausgabeargumenten und ___inout
wird zum Markieren von Eingabe- und Ausgabeargumenten verwendet.
Beispiele für den Einsatz von drltrace zur Analyse komplexer Malware finden Sie auf unserer Wiki-Seite.
Um die Arbeit mit Protokolldateien zu erleichtern, haben wir ein Skript namens api_calls_viz.py
implementiert, mit dem RGB-Bilder generiert werden können, bei denen jede Pixelfarbe einen eindeutigen API-Aufruf darstellt. Das Bild unten zeigt beispielsweise eine Protokolldatei der WannaCry-Malware.
Die großen grünen Bereiche auf dem Bild stellen API-Aufrufe ( wcscmp/wcsicmp
) dar, mit denen Dateien mit interessanten Erweiterungen (z. B. docx, xls, py) ausgewählt werden, um sie zu verschlüsseln. Die violetten Bereiche stellen API-Aufrufe ( FindFirstFile/FindNextFile/CryptEncrypt
) dar, die zum Aufzählen und Verschlüsseln von Dateien und Ordnern auf der Festplatte verwendet werden.
Das Skript kann auch eine HTML-Darstellung des generierten RGB-Bilds generieren, wobei jedes Element ausgewählt werden kann, um einen Namen des API-Aufrufs anzuzeigen.
Rohe HTML-Datei.
Weitere Informationen finden Sie im Verzeichnis api_calls_viz
.
Eine ausführliche Anleitung finden Sie auf dieser Wiki-Seite.
Windows, Linux (zukünftig macOS).
x86, x64 (ARM auf der Liste).
C- und C++-Standardbibliothek (und Protokolle zur Verarbeitung von in Python geschriebenen Skripten).
Wir haben uns entschieden, unseren API-Aufruf-Tracer zusätzlich zum dynamischen Binärinstrumentierungs-Framework DynamoRIO zu implementieren. Drltrace fordert DynamoRIO auf, die Instrumentierung des LoadLibrary-Aufrufs durchzuführen, um neue Bibliotheken verarbeiten zu können, die vom Zielprozess geladen werden. Wenn der Prozess versucht, eine neue Bibliothek zu laden, leitet DynamoRIO den Kontrollfluss an drltracelib.dll
um. Drltrace wiederum zählt exportierte Funktionen in der neu geladenen DLL auf und registriert für jede von ihnen einen speziellen Rückruf. Wenn also eine exportierte Funktion von Malware aufgerufen würde, wird der Rückruf von drltrace vor dieser Funktion ausgeführt und das Tool kann alle erforderlichen Informationen wie Funktionsnamen und Argumente protokollieren. Nach der Funktion kann ein weiterer Rückruf registriert werden, um die Ausführungsergebnisse zu speichern.
Warum nicht Intel Pin? Wir haben uns aus folgenden Gründen für den Einsatz von DynamoRIO entschieden:
-syswide_on
von drrun.exe
). Zukünftig ist es jedoch notwendig, für solche Situationen eine spezielle Unterstützung in drltrace zu implementieren.Unser Issue-Tracker enthält weitere Details zur Zukunft von drltrace.
Maksim Shudrak https://github.com/mxmssh
Derek Bruening https://github.com/derekbruening
Joe Testa https://github.com/jtesta