Tatort Internet: Operation am offenen Herzen
Seite 3: Dateisystem
Ganz tief unten
Ich hangel mich weiter und schau mir nun mit dt _driver_object
das Treiber-Objekt an, das laut Device-Object bei 0x82166c40
liegt. Wieder erscheint ein ungültiger Typ 0 – richtig wäre 4. Immerhin der Name ist auf den korrekten Unicode-String "\Driver\atapi"
gesetzt und auch die Funktionen wie DriverInit
und DriverStartIO
zeigen auf den Original-Windows-Atapi-Treiber. Doch das „MajorFunction Array
“, das die I/O-Operationen des Treibers wie IRP_MJ_READ
und IRP_MJ_WRITE
enthält, liegt erneut im bereits einschlägig bekannten Adressbereich 0x820dxxxx
– höchst verdächtig. Die schau ich mir doch mal genauer an.
Dazu muss ich den Code gar nicht allzu genau studieren. Schon bei einer oberflächlichen Analyse wird mir klar, was hier passiert. Das mit dem Befehl uf
erzeugte Disassembly zeigt dank Symbol-Tabelle viele bekannte Aufrufe der File System Runtime Library wie FsRtlProcessFileLock
oder FsRtlAllocatePool
. Darüber hinaus finden sich in den Funktionen typische Return-Codes wie 0xC0000123
(STATUS_FILE_DELETED)
oder 0xC000007F
(STATUS_ DISK_FULL)
.
„Dieses verdammte Rootkit hat ein eigenes Dateisystem implementiert!“, entfährt es mir unwillkürlich. Hans, der mir die ganze Zeit geduldig über die Schulter geschaut hat, fährt erschrocken zusammen und schaut mich mit großen Fragezeichen in den Augen an. Ich versuche ihm zu erklären, dass Windows typischerweise die Dateisysteme FAT32 oder NTFS benutzt, um Dateien zu verwalten. Doch dieses Rootkit bringt dafür seine eigenen Funktionen mit und operiert dabei auf unterster Treiberebene. Kein herkömmliches Betriebssystem kann somit auf die Dateien so ohne Weiteres zugreifen.
Als Hans immer noch verständnislos schaut, zucke ich die Achseln und widme mich wieder dem Debugger. Das hier ist richtig spannend; mal sehen, was da noch so ans Tageslicht kommt. Bei einer genaueren Inspektion der Schreib- und Lesefunktionen fällt mir eine seltsame Schleife auf, die eine vertraute Struktur aufweist. Tatsächlich: Eine kurze Analyse der disassemblierten Funktion bestätigt mir, dass es sich um den RC4-Verschlüsselungsalgorithmus handelt.
Das heißt also: Nicht nur, dass Analysesysteme das Dateisystem nicht kennen – selbst wenn sie die Rohdaten Byte-weise auslesen und analysieren, finden sie keinerlei verräterische Spuren, sondern nur ein paar kryptische Blocks mit scheinbarem Datenmüll. Die Kerle, die das verbrochen haben, haben echt was drauf – so tief ist bisher noch kein Rootkit in den Kernel vorgedrungen.
Eine genauere Analyse des eigentlichen ATAPI-Treiber-Objekts via !drvobj \driver\atapi 2
zeigt mir dann noch, dass TDL dort die StartIO
-Routine auf sich selbst umgebogen hat. Dazu muss man wissen, dass Lese- und Schreibvorgänge typischerweise mehrstufig erfolgen, aber letztlich immer StartIO
die Daten vom I/O-Port der Platte abholt beziehungsweise dort abliefert. Somit hat das Rootkit alle Schreib- und Lesevorgänge unter seiner Kontrolle. Der Anwender, sein Virenwächter und sogar das restliche Betriebssystem sehen nur, was TDL ihnen zeigen will. Und außerdem kann es an dieser Stelle natürlich auch sicherstellen, dass der Bereich mit seinen eigenen Dateien nicht überschrieben wird.
Um den vom Rootkit belegten Speicherbereich einzugrenzen, werfe ich dem Befehl !pool
die Adresse von DriverStartIO
vor die Füße und erhalte die Auskunft, dass sie zu einem Block gehört, der bei 0x820d6000
anfängt und die Länge 0xF000
hat. Mit dem Such-Kommando „s“ suche ich diesen Bereich auf Strings ab und finde gleich mehrere interessante Einträge – unter anderem das charakteristische „!This program cannot be run …“ und einen Hinweis auf eine Konfigurationsdatei cfg.ini.
Spannender finde ich jedoch die Meldungen „Invalid partition table“ beziehungsweise „Error loading operating system“. Das sind deutliche Hinweise, dass sich das Rootkit auch am Master Boot Record zu schaffen macht. Die Strings „ldr32“ und „ldr64“ klingen nach getrennten Bootloader-Prozessen für 32- und 64-Bit-Betriebssysteme. Die Dateien „drv32“ und „drv64“ sind dann wohl das eigentliche Rootkit und „cmd.dll“ beziehungsweise „cmd64.dll“ die Usermode-Komponenten dazu.
Die Details hierzu lassen sich bei einem späteren Reverse Engineering sicherlich genau aufdecken. Doch eines ist jetzt schon klar: Das Rootkit verbreitet sich offensichtlich auf 32- und 64-Bit-Systemen und kontrolliert dabei das Betriebssystem bereits in der frühest möglichen Phase.
Mir stellt sich die Frage, wo sich die Usermode-Komponente des Rootkits versteckt hat. Ich tippe auf den Internet Explorer und besorge mir via !process 0 1 iexplore.exe
dessen Adresse im Speicher. Die setze ich mit .process /r /d
als Debugger-Kontext. Der Schalter /r stellt sicher, dass dabei auch die Symbole dieses Prozesses nachgeladen werden. Nun lasse ich mir mit dem Befehl !vad
und der VadRoot-Adresse aus der Prozessstruktur die Liste der Virtual Address Descriptors – kurz VADs – anzeigen.
Das ist eine komplette Liste aller Speicherbereiche, die mit einem Prozess assoziiert sind. Sie enthält neben dem eigentlichen Image nicht nur alle DLLs, die ein Prozess angezogen hat, sondern auch dynamisch zur Laufzeit allozierten Speicher. Wenn irgendwas in den Browser eingeschmuggelt wurde, sollte es hier auftauchen.
Gleich als zweiter Eintrag sticht mir dann auch schon ein Block bei 0x250
ins Auge, der mit EXECUTE_READWRITE
als ausführbar und beschreibbar markiert ist, aber zu keiner Datei gehört. Um sich diesen Speicherbereich anzeigen zu lassen, muss man den Offset zunächst mit der Blocklänge 0x1000 multiplizieren. Dann spuckt mir der Display-Content-Befehl dc
auch schon den typischen PE-Header mit dem magischen String „MZ…“ zu Ehren von Mark Zbikowski aus. Darf ich vorstellen: die Usermode-Komponente cmd.dll.
Ein weiteres Mal kommt die String-Suche zum Einsatz und ein weiteres Mal liefert sie interessante Ergebnisse. Neben diversen URLs wie youtube.com oder facebook.com finden sich dort auch Kommandos wie DownloadAndExecute
oder DownloadCrypted2
, über die anscheinend der Command & Control-Server seine Anweisungen erteilt. Besonders interessant ist der Eintrag \\?\globalroot\device\
00000f9f\7a256516\cfg.ini
, denn er verrät mir, wie die Usermode-Komponente auf das hauseigene Dateisystem zugreift.