Tatort Internet: Operation am offenen Herzen

Seite 3: Dateisystem

Inhaltsverzeichnis

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.

Das Rootkit klinkt sich in die Treiber-Hierarchie ein und bringt sein eigenes Dateisystem mit.

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.