Tous les articles

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 psscanVu par pslistVerdict
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 handles csrss absente à la fois de pslist et psscan est très cachée.
  • Parcours du répertoire d'objets sous \BaseNamedObjects et \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

  1. Lancez pslist pour l'arbre vivant de référence.
  2. Lancez psscan pour faire ressortir les objets sortis/déliés.
  3. Utilisez psxview pour signaler automatiquement les écarts.
  4. Pour toute ligne HIDDEN, pivotez vers cmdline, dlllist, et netscan pour 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.

Pour aller plus loin