CreateRemoteThread DLL Injection
La technique classique d'injection de DLL à distance : allouer le chemin d'une DLL dans un processus cible, l'y écrire, puis lancer un thread distant démarrant sur LoadLibrary pour mapper la DLL dans la victime.
L'injection de DLL par CreateRemoteThread est la primitive d'injection de
processus de référence sous Windows. L'injecteur écrit le chemin complet d'une
DLL contrôlée par l'attaquant dans l'espace d'adressage de la cible, puis crée
dans ce processus un thread dont la routine de démarrage est
LoadLibraryA/LoadLibraryW et dont l'unique argument est le chemin de la DLL.
Le chargeur du système d'exploitation mappe alors et exécute la DLL au sein de la
victime — aucun exploit n'est requis, juste un handle avec les droits d'accès
adéquats.
Fonctionnement
Comme LoadLibraryA possède le même prototype qu'une routine de démarrage de
thread (LPTHREAD_START_ROUTINE — un seul argument pointeur), son adresse peut
être passée directement à CreateRemoteThread, et l'argument du thread distant
devient le chemin de la DLL. kernel32.dll est chargée à la même base dans tous
les processus pour un démarrage donné, de sorte que l'injecteur peut résoudre
LoadLibraryA localement et réutiliser l'adresse à distance.
hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE, FALSE, targetPid);
remoteBuf = VirtualAllocEx(hProc, NULL, sizeof(dllPath),
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, remoteBuf, dllPath, sizeof(dllPath), NULL);
loadLib = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hProc, NULL, 0,
(LPTHREAD_START_ROUTINE)loadLib, remoteBuf, 0, NULL);Détection & contournement
- Statique — L'injecteur importe le quatuor révélateur
OpenProcess,VirtualAllocEx,WriteProcessMemoryetCreateRemoteThread, généralement à proximité deGetProcAddress("LoadLibraryA"). Une chaîne de chemin de DLL en clair ou faiblement obfusquée (.dll, un répertoire temp/AppData) est un indicateur fort. Contrairement à la plupart des variantes d'injection, la charge utile est ici une vraie DLL sur le disque, donc le fichier déposé est lui-même un artefact statique. - Dynamique — Dans API Monitor ou une trace ETW, surveillez une séquence
VirtualAllocEx+WriteProcessMemory+CreateRemoteThreadoù les PID source et cible diffèrent et où l'adresse de démarrage du thread résout versLoadLibraryA/Wdanskernel32. Sysmon Event ID 8 (CreateRemoteThread) enregistre le processus source, le processus cible et l'adresse de démarrage ; l'EID 7 (ImageLoad) montre ensuite le nouveau module inattendu dans la victime. - Forensique mémoire — Le module injecté est une DLL légitimement mappée et
adossée à une image, il n'apparaît donc pas comme RWX privé. Il se présente
plutôt comme un module inattendu chargé dans un processus qui ne devrait jamais
l'héberger (p. ex. une DLL utilisateur dans
lsass.exeouexplorer.exe). pe-sieve énumère les modules chargés et signale la DLL étrangère/non signée ; les commandesdlllist/ldrmodulesde Volatility révèlent un module présent dans le VAD mais absent de l'une des listes du chargeur du PEB si l'entrée a été altérée. - Outils — Sysmon (EID 8/7) + ETW, API Monitor, Process Hacker (inspection
des modules et des threads), pe-sieve, Moneta et Volatility (
dlllist,ldrmodules,malfind).