Après ennuyeux stage 1, ce fut difficile de se motiver pour la deuxième étape. Mais ça valait la peine, je pensai que ce sample était un keylogger, comme documenté sur le net mais ce n’est pas le cas. C’est un moteur générique de hooking assez sympa. Les hooks sont placé sur:
Pour suivre l’article utilisez l’idb duqu.0x5098.idb.
Le début du code 401A8Eh (début) configure le contexte d’exception et transfert le flot à 402C2Eh (startmain) où un thread est lancé sur 402B29h (main). (Oui, nous sommes dans la section ennuyeuse.) Le code prend un handle sur le processus courant, et aquière les privilège débugger pour ouvrir le processus à hooker dont pid est stocké dans 403024h (dwProcessId).
4028Bh (injectstage3) injecte de le troisième stage dans le processus cible. L’injection procéde comme suit.
402244h (GetFileName) obtien un nom de fichier. Ce nom est soit fourni en argument, 403030h (path), ou construits à partir du produit du TickCount et du TID (comme dans stage 1,) le nom du fichier résultant est
sorte [0-F] 4,4. nls_
Les chaînes sort et .nls sont xoré avec le même algorithme que celui du stage1. Je pense que ce fichier est utilisé comme un espace de travail pour le stage3.
Tout d’abord, le stage3 ne sait pas où il est. Ainsi il a besoin d’obtenir ses adresse virtuelle. Ainsi 401709h (get_VA_401709) fournit sa propre adresse via le callpop habituel:
appeler à 5 $, appelez la prochaine instruction
pop eax; pop l'adresse de retour
Cela fournit un point de référence, puis les autres adresses sont calculées par rapport à l’adresse de 401709h. C’est tout à fait propre. Grâce à cela 40186Dh (get_VA_imports) obtient l’adresse de la table d’import maison.
401C39h (initenv) configure des donnée d’environnement sizeofimage locale, sizeofstack… je n’ai pas regardé dans le détail.
Maintenant, nous allons passer à la partie intéressante. 401DCAh (registerhooks) met en place plusieurs hooks sur ntdll.dll avec une charge utile obtenu depuis le fake ntdll.dll
%Systemroot%\ntdll.dll
4012C9h (getviewonNTDLLDLL) construit le chemin%systemroot%\ntdll.dll l’ouvrir et le mapper.
Ensuite, il y a six code similaires, un pour chaque hook ZwMapViewOfSection six API, ZwCreateSection, ZwOpenFile, ZwClose, ZwQueryAttributesFile et ZwQuerySection.
Obtien l’adresse du handler local via 401709h (getVA_401709) comme expliqué précédemment. Les handler ont deux branches. (i) La normale qui se contente d’appeler le payload dans la table d’import maison. (ii) La branche magique qui manipule le fichier magique précédemment défini par 401709h (get_VA_401709). Cette partie détourne les API hookées pour faire autre chose, je ne comprends pas bien cette partie peut être parce que je n’ai pas le ntdll.dll associé faux. Grosso merdo la partie magique fonctionne comme suit.
Le tableau des export du faux ntdll.dll parsé pour récupérer les payload des hooks; le payload est exporté avec le même nom que l’API hookée correspondante. La recherche des export est réalisée par la technique d’offuscation d’API que dans stage1. L’adresse du payload est sauvée dans la table d’import maison.
4017E2h (setuphook) met en place les hook avec un PAGE_EXECUTE_WRITECOPY VirtalProtect et une copie de sept octets sur l’API hookée:
B8 DR AD OK HO FF E0: mov eax, HOOKADDR; jmp eax