🧠 Première analyse d'un dump mémoire Windows avec Volatility 3 - les 5 commandes essentielles pour commencer

🧠 Première analyse d'un dump mémoire Windows avec Volatility 3 - les 5 commandes essentielles pour commencer
Photo by Markus Winkler / Unsplash

📌 Informations générales

  • Catégorie : Forensics mémoire
  • Niveau : Débutant
  • Outils principaux : Volatility 3 (windows.info, windows.pslist, windows.pstree, windows.psscan, windows.cmdline, windows.ldrmodules, windows.netscan, windows.filescan, windows.dumpfiles)
  • Prérequis : Une machine Linux ou Windows avec Python 3 installé, et l'envie d'apprendre

🧩 Introduction

Avant de se lancer dans une investigation — que ce soit sur une capture mémoire d'une machine réellement infectée ou dans le cadre d'un CTF — il faut d'abord apprendre à mener un début d'analyse structuré.

Les questions à se poser avant toute chose :

  • Quelle est la version de Windows sur laquelle on enquête ?
  • Quel processus est malveillant, et depuis quand tourne-t-il ?
  • Quelles commandes ont été exécutées sur la machine ? Où se trouve exactement l'exécutable suspect ?
  • Une connexion est-elle ouverte vers un C2 ou une IP suspecte ?
  • Que contient concrètement le processus malveillant ?

Cet article sera rédigé à partir du lab RedLine de CyberDefenders, accessible via le lien ci-dessous :

Je précise que de mon côté je travaille uniquement sous Linux, mais le fonctionnement et les commandes restent strictement identiques sous Windows.


🔎 Phase 0 – Installation de volatility 3

Sous Linux :

git clone https://github.com/volatilityfoundation/volatility3.git
cd volatility3
pip3 install -r requirements.txt

Sous Windows :

Les commandes sont identiques, à exécuter dans PowerShell ou CMD après avoir installé Python 3 et Git for Windows :

git clone https://github.com/volatilityfoundation/volatility3.git
cd volatility3
pip install -r requirements.txt
ℹ️ Au premier lancement, Volatility télécharge automatiquement les symboles de debug Windows (fichiers PDB) depuis les serveurs Microsoft. Il faut donc une connexion Internet active lors de la première analyse d'un dump donné.

🔎 Phase 1 – Comprendre l'environnement qu'on analyse avec windows.info

Pour identifier les informations sur le système compromis, on commence par le module windows.info.

vol -f MemoryDump.mem windows.info

Voici la sortie complète :

Volatility 3 Framework 2.28.1
Progress:  100.00               PDB scanning finished
Variable        Value

Kernel Base     0xf8076221a000
DTB     0x1ad000
Symbols file:///opt/venv/lib/python3.13/site-packages/volatility3/symbols/windows/ntkrnlmp.pdb/68A17FAF3012B7846079AEECDBE0A583-1.json.xz
Is64Bit True
IsPAE   False
layer_name      0 WindowsIntel32e
memory_layer    1 FileLayer
KdVersionBlock  0xf80762e29398
Major/Minor     15.19041
MachineType     34404
KeNumberProcessors      4
SystemTime      2023-05-21 23:02:39+00:00
NtSystemRoot    C:\Windows
NtProductType   NtProductWinNt
NtMajorVersion  10
NtMinorVersion  0
PE MajorOperatingSystemVersion  10
PE MinorOperatingSystemVersion  0
PE Machine      34404
PE TimeDateStamp        Wed Jun 28 04:14:26 1995

Les informations essentielles à retenir :

  • La machine est un Windows 10NtMajorVersion 10 + NtMinorVersion 0 correspondent à un Internal Version Number 10.0. À savoir que 10.0 correspond également à Windows Server 2016, d'où l'importance du champ suivant.
  • Il s'agit d'une version Workstation (donc bien un Windows 10 client) → NtProductType : NtProductWinNt. À l'inverse, NtProductServer ou NtProductLanManNt désignent une édition Serveur.
  • Le build exact est le 19041Major/Minor : 15.19041, ce qui correspond à la version 20H1 (mise à jour de mai 2020).
  • La capture a été réalisée le 2023-05-21 à 23:02 UTCSystemTime : 2023-05-21 23:02:39+00:00, information cruciale pour corréler avec d'autres sources (logs Windows, EDR, captures réseau).

Pourquoi ces informations sont-elles cruciales ?

  • Connaître le système d'exploitation permet de savoir quels plugins Volatility sont applicables, et quels artefacts mémoire peuvent être présents.
  • Distinguer une Workstation d'un Server oriente l'analyse : une attaque ne suit pas le même scénario sur un poste utilisateur et sur un serveur (pas les mêmes services exposés, pas le même profil de compromission).
  • Le build Windows détermine les vulnérabilités applicables au moment de l'attaque et peut conditionner certaines techniques d'investigation.
  • Le timestamp de la capture offre le point d'ancrage temporel indispensable pour reconstituer la chronologie d'une attaque.
ℹ️ Le champ PE TimeDateStamp affichant Wed Jun 28 04:14:26 1995 est trompeur : il s'agit d'un timestamp déterministe que Microsoft fixe volontairement sur certains binaires système. Ce n'est pas la date réelle de compilation.

⚙️ Phase 2 – Identifier les processus suspects avec windows.pslist et windows.pstree

Maintenant que l'on connaît le système sur lequel on enquête, on utilise le module windows.pslist pour lister tous les processus encore actifs au moment de la capture.

vol -f MemoryDump.mem windows.pslist

Voici un extrait de la sortie, où j'ai conservé uniquement les lignes qui me semblent les plus pertinentes :

PID     PPID    ImageFileName   Offset(V)       Threads Handles SessionId   Wow64   CreateTime                      ExitTime                        File output
824     676     svchost.exe     0xad818761d240  22      -       0           False   2023-05-21 22:27:32.000000 UTC  N/A                             Disabled
448     676     svchost.exe     0xad8187721240  54      -       0           False   2023-05-21 22:27:41.000000 UTC  N/A                             Disabled
3556    588     userinit.exe    0xad818c02f340  0       -       1           False   2023-05-21 22:30:28.000000 UTC  2023-05-21 22:30:43.000000 UTC  Disabled
3580    3556    explorer.exe    0xad818c047340  76      -       1           False   2023-05-21 22:30:28.000000 UTC  N/A                             Disabled
6724    3580    Outline.exe     0xad818e578080  0       -       1           True    2023-05-21 22:36:09.000000 UTC  2023-05-21 23:01:24.000000 UTC  Disabled  
4224    6724    Outline.exe     0xad818e88b080  0       -       1           True    2023-05-21 22:36:23.000000 UTC  2023-05-21 23:01:24.000000 UTC  Disabled
4628    6724    tun2socks.exe   0xad818de82340  0       -       1           True    2023-05-21 22:40:10.000000 UTC  2023-05-21 23:01:24.000000 UTC  Disabled
5808    824     HxTsr.exe       0xad818de5d080  0       -       1           False   2023-05-21 21:59:58.000000 UTC  2023-05-21 22:07:45.000000 UTC  Disabled
5480    448     oneetx.exe      0xad818d3d6080  6       -       1           True    2023-05-21 23:03:00.000000 UTC  N/A                             Disabled

Ce qui paraît suspect à première vue :

  • Un processus du nom de oneetx.exe en PID 5480, parfaitement inconnu du catalogue Windows, dont le processus parent est svchost.exe en PID 448. Un svchost.exe légitime ne lance pas d'exécutable utilisateur — c'est déjà un signal fort.
  • Deux instances de Outline.exe (PID 6724 et 4224) accompagnées d'un tun2socks.exe (PID 4628), ce qui ressemble à un client VPN. À confirmer lors de l'analyse réseau.
  • Un processus HxTsr.exe au nom peu familier, à investiguer par précaution.

Quelques rappels utiles sur les processus système légitimes :

  • svchost.exe : processus hôte générique qui charge et exécute les services Windows implémentés sous forme de DLL. Son parent légitime est toujours services.exe.
  • userinit.exe : exécuté lors de la connexion d'un utilisateur, il lance explorer.exe puis se termine. Sa présence courte est normale.
  • explorer.exe : le shell Windows (bureau, barre des tâches, explorateur de fichiers). Toujours présent sur une session interactive.
  • Offset(V) : adresse virtuelle de la structure _EPROCESS dans la mémoire kernel. Utile pour des plugins qui demandent cet offset en entrée.
  • SessionId : identifiant de la session Windows. 0 correspond aux services système, 1+ aux sessions utilisateur interactives.

Il est maintenant temps d'utiliser windows.pstree, qui fonctionne sur le même principe que pslist mais affiche en plus la hiérarchie parent/enfant et le chemin complet des exécutables — ce qui permet de valider ou d'invalider nos hypothèses.

⚠️ À savoir qu'un processus n'est pas forcément suspect sur la base d'un seul module. C'est la corrélation de plusieurs indicateurs qui permet de conclure.

Au premier coup d'œil sur pslist, j'avais noté HxTsr.exe parmi les processus suspects — le nom ne me disait rien. Mais en passant à pstree et en voyant le chemin Program Files\WindowsApps\microsoft.windowscommunicationsapps..., j'ai compris que c'était en fait l'application Courrier de Microsoft. Première leçon : un nom inconnu ne suffit pas, il faut toujours vérifier le chemin d'exécution.
vol -f MemoryDump.mem windows.pstree

Voici les lignes pertinentes pour les processus repérés plus haut :

PID     PPID    ImageFileName   Offset(V)       Threads Handles SessionId       Wow64   CreateTime      ExitTime        Audit   Cmd     Path

# svchost.exe / pid : 824
** 824  676     svchost.exe     0xad818761d240  22      -       0       False   2023-05-21 22:27:32.000000 UTC  N/A     \Device\HarddiskVolume3\Windows\System32\svchost.exe    C:\Windows\system32\svchost.exe -k DcomLaunch -p        C:\Windows\system32\svchost.exe

# svchost.exe / pid : 448
** 448  676     svchost.exe     0xad8187721240  54      -       0       False   2023-05-21 22:27:41.000000 UTC  N/A     \Device\HarddiskVolume3\Windows\System32\svchost.exe    C:\Windows\system32\svchost.exe -k netsvcs -p   C:\Windows\system32\svchost.exe

# Outline.exe / pid : 6724
*** 6724        3580    Outline.exe     0xad818e578080  0       -       1       True    2023-05-21 22:36:09.000000 UTC  2023-05-21 23:01:24.000000 UTC  \Device\HarddiskVolume3\Program Files (x86)\Outline\Outline.exe -       -

# Outline.exe / pid : 4224
**** 4224       6724    Outline.exe     0xad818e88b080  0       -       1       True    2023-05-21 22:36:23.000000 UTC  2023-05-21 23:01:24.000000 UTC  \Device\HarddiskVolume3\Program Files (x86)\Outline\Outline.exe -       -

# tun2socks.exe / pid : 4628
**** 4628       6724    tun2socks.exe   0xad818de82340  0       -       1       True    2023-05-21 22:40:10.000000 UTC  2023-05-21 23:01:24.000000 UTC  \Device\HarddiskVolume3\Program Files (x86)\Outline\resources\app.asar.unpacked\thir  
d_party\outline-go-tun2socks\win32\tun2socks.exe

# HxTsr.exe / pid : 5808
*** 5808        824     HxTsr.exe       0xad818de5d080  0       -       1       False   2023-05-21 21:59:58.000000 UTC  2023-05-21 22:07:45.000000 UTC  \Device\HarddiskVolume3\Program Files\WindowsApps\microsoft.windowscommunicationsapps_16005.11629.20316.0_x64__8wekyb3d8bbwe\HxTsr.exe

# oneetx.exe / pid : 5480
*** 5480        448     oneetx.exe      0xad818d3d6080  6       -       1       True    2023-05-21 23:03:00.000000 UTC  N/A     \Device\HarddiskVolume3\Users\Tammam\AppData\Local\Temp\c3912af058\oneetx.exe   -       -

Ce que l'on observe :

  • Les deux svchost.exe (PID 824 et 448) sont légitimes : ils se trouvent bien dans C:\Windows\System32\ et sont lancés avec des paramètres -k DcomLaunch -p et -k netsvcs -p, ce qui correspond au comportement attendu.
  • HxTsr.exe est en réalité légitime : il appartient à l'application Courrier de Microsoft (microsoft.windowscommunicationsapps). Fausse alerte — preuve qu'un nom peu familier n'est pas suffisant pour conclure.
  • Le binôme Outline.exe + tun2socks.exe est bien un client VPN légitime (le projet Outline de Jigsaw/Google), installé dans Program Files (x86). À noter pour l'analyse réseau, mais ce n'est pas une compromission.
  • oneetx.exe est clairement suspect : il est situé dans C:\Users\Tammam\AppData\Local\Temp\c3912af058\ — un sous-dossier temporaire avec un nom aléatoire, emplacement typique des malwares. Les répertoires à considérer comme immédiatement suspects incluent AppData\Local\Temp, C:\Windows\Temp, ou encore C:\Users\<user>\Downloads.

La priorité d'investigation se confirme : oneetx.exe.

💡 Astuce : une fois un processus suspect identifié, windows.pstree --pid <PID> permet de cibler son arborescence directe. Pratique pour confirmer une hypothèse sans être noyé dans la sortie complète.

Bonus : windows.psscan pour les processus terminés

En bonus, je vais présenter un troisième angle d'analyse avec windows.psscan, qui fonctionne différemment de pslist. Là où pslist suit la liste chaînée des processus maintenue par le kernel (donc ne voit que ce qui est actif), psscan scanne toute la mémoire à la recherche de structures _EPROCESS. Il détecte donc aussi les processus terminés, masqués ou détruits dont la structure subsiste en RAM.

vol -f MemoryDump.mem windows.psscan

Un processus visible uniquement dans psscan (absent de pslist) n'est pas toujours suspect — ça peut simplement être un processus qui s'est terminé normalement. Mais dans notre cas, le résultat est parlant :

7732    5896    rundll32.exe    0xad818d1912c0  1       -       1       True    2023-05-21 22:31:53.000000 UTC  N/A     Disabled

On découvre un rundll32.exe (PID 7732) dont le parent porte le PID 5896. Or ce PID ne correspond à aucun processus visible dans notre pslist précédent — il s'agit d'une instance antérieure de oneetx.exe aujourd'hui terminée. Cela nous indique que oneetx.exe a lancé un processus rundll32.exe avant qu'une nouvelle instance (PID 5480) ne le remplace.

Pourquoi rundll32.exe dans ce contexte est suspect ? rundll32.exe est un utilitaire Windows légitime dont le rôle est d'exécuter des fonctions exposées par des DLL. Il est massivement détourné par les attaquants pour exécuter du code arbitraire depuis une DLL malveillante tout en gardant l'apparence d'un processus signé Microsoft.


⚙️ Phase 3 – Examiner les lignes de commande exécutées

Le module windows.cmdline affiche, pour chaque processus, la ligne de commande complète qui l'a lancé.

vol -f MemoryDump.mem windows.cmdline

Voici des sorties intéressantes :

PID     Process Args
676     services.exe    C:\Windows\system32\services.exe
3028    dllhost.exe     C:\Windows\system32\dllhost.exe /Processid:{02D4B3F1-FD88-11D1-960D-00805FC79235}

On observe ici un dllhost.exe (PID 3028) qui charge un COM component identifié par le CLSID {02D4B3F1-FD88-11D1-960D-00805FC79235}. Ce pattern est intéressant à connaître : dllhost.exe est l'hôte standard des objets COM+ sous Windows, et les attaquants l'utilisent parfois comme vecteur de persistance ou d'élévation via des CLSID malveillants enregistrés dans le registre.

Aller plus loin avec windows.ldrmodules

Pour confirmer la nature malveillante de oneetx.exe, on peut utiliser le module windows.ldrmodules. Ce plugin compare la présence de chaque module (DLL) dans les trois listes maintenues par le PEB (Process Environment Block) du processus :

  • InLoadOrderModuleList
  • InMemoryOrderModuleList
  • InInitializationOrderModuleList

Ces trois listes sont censées contenir l'ensemble des DLL chargées normalement via le loader Windows. Si une DLL apparaît comme présente en mémoire (VAD) mais absente des trois listes PEB (trois False), c'est l'indication qu'elle a été chargée en contournant le loader officiel — technique typique d'injection de code.

vol -f MemoryDump.mem windows.ldrmodules --pid 5480

Extrait de sortie :

5480    oneetx.exe      0x75480000      False   False   False   \Windows\SysWOW64\mscoree.dll

Les trois False indiquent clairement que ce module n'a été enregistré dans aucune des listes légitimes de chargement. mscoree.dll est en soi une DLL Windows légitime (le moteur .NET), mais le fait qu'elle soit présente en mémoire sans être référencée par le processus est anormal, et renforce l'hypothèse d'un chargement malveillant.


⚙️ Phase 4 – Observer les connexions réseau

Il est maintenant temps d'identifier les connexions réseau potentiellement suspectes via windows.netscan :

vol -f MemoryDump.mem windows.netscan

Extrait de sortie :

Offset          Proto  LocalAddr        LocalPort  ForeignAddr   ForeignPort  State   PID   Owner          Created
0xad818de4aa20  TCPv4  10.0.85.2        55462      77.91.124.20  80           CLOSED  5896  oneetx.exe     2023-05-21 23:01:22.000000 UTC  
0xad818df1d920  TCPv4  192.168.190.141  55433      38.121.43.65  443          CLOSED  4628  tun2socks.exe  2023-05-21 23:00:02.000000 UTC

Deux connexions ressortent :

  • Une connexion TCP vers 77.91.124.20:80 initiée par oneetx.exe (PID 5896 — l'instance terminée, qui confirme qu'il s'agit du même acteur malveillant tout au long de la session). L'état CLOSED indique une connexion déjà fermée au moment de la capture. Le port 80 (HTTP) associé à un processus déjà identifié comme suspect confirme l'existence d'un canal de Command & Control (C2).
  • Une connexion TCP vers 38.121.43.65:443 initiée par tun2socks.exe. Celle-ci correspond au comportement normal du client VPN Outline : le port 443 est standard pour une communication HTTPS, et le processus s'inscrit dans l'arborescence légitime d'Outline. Pas de compromission à ce niveau.
💡 C'est quoi un C2 ?

Un Command & Control est un serveur contrôlé par l'attaquant qui sert à piloter à distance les machines compromises. C'est par ce canal que le malware reçoit ses ordres, exfiltre des données, ou télécharge de nouveaux modules.

⚙️ Phase 5 – Lister et extraire les artefacts

Pour clôturer l'investigation, on extrait l'exécutable malveillant afin de permettre une analyse approfondie (reverse engineering, soumission à VirusTotal, analyse YARA, etc.). On utilise windows.filescan combiné à un grep pour cibler uniquement oneetx.exe :

vol -f MemoryDump.mem windows.filescan | grep "oneetx.exe"

Trois offsets mémoire correspondent au fichier :

  • 0xad818d436c70
  • 0xad818da36c30
  • 0xad818ef1a0b0

Le chemin associé dans chacun des cas est :

\Users\Tammam\AppData\Local\Temp\c3912af058\oneetx.exe
📖 Un mot sur les offsets : un offset est l'emplacement d'une structure dans la mémoire. Volatility renvoie ici des adresses physiques (la localisation réelle dans le dump). À ne pas confondre avec les adresses virtuelles (utilisées par le processus lui-même pour accéder à ses données).

On peut maintenant extraire le fichier via windows.dumpfiles :

vol -f MemoryDump.mem -o ./ windows.dumpfiles --virtaddr "0xad818ef1a0b0"

Sortie :

ImageSectionObject      0xad818ef1a0b0  oneetx.exe      file.0xad818ef1a0b0.0xad818ca48660.ImageSectionObject.oneetx.exe.img

On obtient le fichier file.0xad818ef1a0b0.0xad818ca48660.ImageSectionObject.oneetx.exe.img, prêt à être analysé avec les outils classiques (strings, pefile, ghidra, IDA, soumission à un sandbox…).

Dans le cadre de cet article je ne pousse pas l'analyse plus loin, le but était de montrer la méthodologie. Mais c'est précisément ce fichier extrait qui permettrait, dans un cas réel, de caractériser la famille de malware, d'extraire les IOC supplémentaires (URL C2 dans les strings, clés de chiffrement, noms de mutex…) et de rédiger un rapport d'incident complet.

🎁 Bonus : analyse VirusTotal
Plutôt que de te laisser avec un fichier extrait dans le vide, voici le rapport VirusTotal public de notre oneetx.exe :
👉 VirusTotal - oneetx.exe (SHA-256)

Tu peux vérifier que le hash du fichier que tu viens d'extraire correspond bien, via :sha256sum file.0xad818ef1a0b0.0xad818ca48660.ImageSectionObject.oneetx.exe.img

Cela te permet de valider concrètement que ton extraction mémoire est fidèle au binaire réellement présent sur la machine. C'est également un bon réflexe à prendre : toujours hasher un artefact extrait pour pouvoir le partager, le comparer et le corréler avec d'autres sources (VirusTotal, MalwareBazaar, threat intel interne).
⚠️ Le fichier pointé par ce rapport est un malware réel (famille RedLine Stealer). Ne le télécharge et ne le manipule que dans un environnement isolé (VM sandbox sans réseau, dossier exclu de l'antivirus). Pour une simple lecture du rapport, le lien VirusTotal est sans danger.

🎯 Méthodologie synthétique

Voici la checklist d'analyse que je recommande, dans l'ordre :

# Étape Plugin Volatility 3 Ce qu'on cherche
1 Informations sur l'OS windows.info Version, build, date de capture
2 Liste des processus windows.pslist + windows.pstree Parents incohérents, chemins anormaux
3 Processus terminés (bonus) windows.psscan Processus masqués, terminés ou détruits
4 Lignes de commande windows.cmdline Arguments suspects, chemins non standards
5 Modules chargés (bonus) windows.ldrmodules DLL chargée hors du loader (trois False)
6 Connexions réseau windows.netscan Trafic C2, ports non standards, IP suspectes
7 Extraction d'artefacts windows.filescan + windows.dumpfiles Récupération du binaire malveillant pour analyse
⚠️ Aucun de ces indicateurs n'est une preuve absolue pris isolément. C'est la corrélation de plusieurs indicateurs qui bâtit une conclusion solide. Un seul est une anomalie. Trois ou plus qui convergent, c'est une compromission.

🧾 Conclusion

Cette première analyse nous a permis d'identifier, sans connaissance préalable du lab, l'ensemble du scénario de compromission : un exécutable oneetx.exe déposé dans un répertoire temporaire utilisateur, lancé comme enfant direct d'un svchost.exe légitime, ayant chargé une DLL hors du loader Windows, communiquant avec un serveur C2 externe (77.91.124.20), et ayant spawné un rundll32.exe pour exécuter du code additionnel.

Ce qu'il faut retenir de cette méthodologie :

  • 🔑 Ne jamais conclure à partir d'un seul module. Un nom inhabituel ne suffit pas (HxTsr.exe était légitime), un binaire dans Program Files n'est pas forcément clean, et un svchost.exe peut très bien être l'hôte d'une activité malveillante. C'est la cohérence globale entre emplacement, parent, DLL chargées, connexions réseau et comportement qui permet de trancher.
  • 🔑 Les répertoires temporaires sont toujours à blacklister. AppData\Local\Temp, C:\Windows\Temp, Downloads : un exécutable inconnu à ces emplacements est suspect jusqu'à preuve du contraire.
  • 🔑 Le workflow est itératif, pas linéaire. On revient sans arrêt sur les sorties précédentes pour valider ou infirmer une hypothèse. Un PID mentionné par netscan qu'on ne voit pas dans pslist ? Retour sur psscan. Un processus au comportement louche ? ldrmodules pour confirmer.

💀 L'erreur classique du débutant :

Se focaliser sur un seul processus dès le premier module et ignorer le reste. Un analyste expérimenté lit d'abord l'ensemble du contexte (OS, processus, connexions) avant de plonger sur une cible précise.

🛑 Bonnes pratiques d'analyse

❌ Ne jamais conclure à partir d'un seul indicateur isolé
❌ Ne pas ignorer les processus terminés — psscan révèle souvent des éléments que pslist cache
✅ Toujours croiser l'emplacement sur disque, le parent et les DLL chargées avant de qualifier un processus
✅ Extraire systématiquement l'exécutable suspect pour une analyse statique ultérieure

📚 Références et ressources