pslist vs psscan vs psxview : trouver les processus cachés
4 min de lecture
"Lister les processus" semble simple. En forensique mémoire il y a
trois manières de le faire, et les différences entre elles sont
précisément là où les rootkits se font attraper. La technique n'a pas
changé en quinze ans ; elle marche toujours parce que les adversaires
qui se délient de ActiveProcessLinks laissent toujours l'objet
_EPROCESS traîner dans le pool.
pslist : la liste chaînée vivante
pslist parcourt ActiveProcessLinks, la liste doublement chaînée
du noyau des structures _EPROCESS (la même liste que le
Gestionnaire de tâches reflète).
ramparser le fait avec des offsets exacts depuis le PDB noyau : il
localise le processus System (PID 4), prend son DirectoryTableBase
comme CR3 noyau, et parcourt la liste via les vraies tables de pages.
Précis, mais la technique ne voit que les processus encore liés dans
la liste. Un rootkit DKOM ("Direct Kernel Object Manipulation") qui
délie son propre _EPROCESS de ActiveProcessLinks devient
invisible à pslist.
psscan : scan pool
psscan ignore complètement la liste. Il balaye la mémoire physique
à la recherche d'allocations _EPROCESS par leur signature pool
(_POOL_HEADER tagué Proc pour les processus). Il trouve :
- Les processus qui ont terminé (la mémoire n'a pas encore été réutilisée).
- Les processus qui ont été déliés de
ActiveProcessLinks. - Les processus que le noyau n'a jamais fini de lier (rares, mais réels sur certains malwares qui font la course au démarrage).
Le compromis : le scan pool est plus sensible à la disposition
spécifique au build qu'un parcours de liste piloté par les symboles.
ramparser valide chaque _EPROCESS candidat avec des heuristiques
structurelles (PID plausible, nom d'image imprimable,
DirectoryTableBase aligné sur la page, pointeur de liste noyau
canonique) pour garder les faux positifs bas.
psxview : la vue croisée
Un rootkit DKOM classique délie son processus de
ActiveProcessLinks pour que pslist ne puisse le voir. L'objet
_EPROCESS est encore en mémoire, donc psscan le peut.
psxview est le diff :
| Vu par psscan | Vu par pslist | Verdict |
|---|---|---|
| ✔ | ✔ | normal |
| ✔ | ✘ | HIDDEN, délié, à investiguer |
| ✘ | ✔ | course transitoire habituellement ; à revoir |
Une ligne présente dans le scan pool mais absente de la liste vivante est la signature d'un processus caché. C'est l'un des rares endroits en forensique mémoire où l'absence de preuve dans une source est en soi la preuve.
Au-delà du DKOM
Le savoir-faire adversarial réel va au-delà du simple déliement de
ActiveProcessLinks. À ajouter à la vue croisée dans une enquête
sérieuse :
- Table de handles de
csrss.exe: le session manager Windows conserve des handles vers chaque processus. Une ligne dans les handlescsrssabsente à la fois de pslist et psscan est très cachée. - Parcours du répertoire d'objets sous
\BaseNamedObjectset\KernelObjects. Certains masqueurs oublient de nettoyer le namespace. - Scans d'objets thread / job. Un processus caché a encore des threads en cours.
Le psxview de Volatility 3 ajoute plus de sources par défaut ;
l'implémentation actuelle de ramparser se concentre sur le diff
pslist/psscan. Pour des scénarios de masquage plus profonds, escaladez
vers Volatility 3.
Flux pratique
- Lancez pslist pour l'arbre vivant de référence.
- Lancez psscan pour faire ressortir les objets sortis/déliés.
- Utilisez psxview pour signaler automatiquement les écarts.
- Pour toute ligne
HIDDEN, pivotez verscmdline,dlllist, etnetscanpour ce PID. Deux pivots qui s'accordent sur quelque chose de suspect constituent une vraie conclusion.
ramparser exécute ces vues ensemble pour que le diff soit un seul
tableau ouvert, pas trois outils. Quand le triage signale des
processus cachés, le
flux d'analyse mémoire couvre les
étapes suivantes (malfind, callbacks noyau, YARA) qui construisent
le tableau complet de masquage noyau.