Skip to content

CrashDump

This content is not available in your language yet.

Scenario

Un systeme Windows a ete compromis par un framework C2. Deux fichiers minidump (.DMP) sont fournis pour identifier l’intrusion et extraire les indicateurs de compromission (IOC).

Fichiers fournis

  • notepad.DMP - Dump du processus injecte (notepad.exe)
  • update.DMP - Dump du processus malveillant (update.exe)

Qu’est-ce qu’un Minidump ?

Un minidump est un fichier de diagnostic Windows contenant un instantane partiel de la memoire d’un processus. Contrairement a un full dump, il ne contient que les informations essentielles pour le debogage.

Structures principales d’un minidump

StreamDescription
SystemInfoVersion OS, architecture, processeur
ModuleListListe des DLL/EXE charges avec leurs versions
ThreadListListe des threads avec leur contexte CPU
ThreadInfoListMetadonnees des threads (timestamps, priorite)
MemoryListRegions memoire capturees
MemoryInfoListInformations sur toutes les regions (permissions, type)
MiscInfoPID, timestamps du processus

Documentation

Installation

Fenêtre du terminal
pip install minidump

Exemple de base

from minidump.minidumpfile import MinidumpFile
mf = MinidumpFile.parse('fichier.DMP')
# Informations systeme
print(f'OS: {mf.sysinfo.OperatingSystem}')
print(f'Version: {mf.sysinfo.MajorVersion}.{mf.sysinfo.MinorVersion}')
# PID du processus
print(f'PID: {mf.misc_info.ProcessId}')
# Modules charges
for mod in mf.modules.modules:
print(f'{mod.name}')
# Threads
print(f'Nombre de threads: {len(mf.threads.threads)}')

Tache 1 : Quelle est la version de l’OS ?

Format attendu : X.X.XXXXX.XXXXX

Methode : L’information de version du systeme est stockee dans le stream SystemInfo du minidump. On peut egalement l’obtenir via les informations de version des modules systeme (ntdll.dll, kernel32.dll).

from minidump.minidumpfile import MinidumpFile
mf = MinidumpFile.parse('notepad.DMP')
# Version depuis SystemInfo
si = mf.sysinfo
print(f'OS: {si.OperatingSystem}')
print(f'Version: {si.MajorVersion}.{si.MinorVersion}.{si.BuildNumber}')
# Version complete depuis ntdll.dll
for mod in mf.modules.modules:
if 'ntdll' in mod.name.lower():
vi = mod.versioninfo
major = vi.dwFileVersionMS >> 16
minor = vi.dwFileVersionMS & 0xFFFF
build = vi.dwFileVersionLS >> 16
revision = vi.dwFileVersionLS & 0xFFFF
print(f'Full version: {major}.{minor}.{build}.{revision}')

Tache 2 : Quel est le nombre de threads du processus malveillant ?

Methode : Le processus malveillant est update.exe. On compte les threads dans son minidump.

mf = MinidumpFile.parse('update.DMP')
print(f'Nombre de threads: {len(mf.threads.threads)}')

Tache 3 : Quel processus a ete compromis ?

Methode : Analyser les modules charges dans chaque dump pour identifier le processus legitime utilise comme cible d’injection.

for mod in mf.modules.modules:
print(f'{mod.name} - Version: {mod.versioninfo}')

Indices :

  • Le processus malveillant aura souvent une version 0.0.0.0 (pas de version info)
  • Le processus injecte sera un executable Windows legitime

Tache 4 : Quel est le Named Pipe (canal IPC) utilise ?

Format attendu : ****-****-******

Methode : Les named pipes sont un mecanisme de communication inter-processus utilise par certains frameworks C2 pour la communication entre le beacon et les processus injectes.

Fenêtre du terminal
strings update.DMP | grep -iE 'pipe|MSSE|postex' | grep -v 'api-ms\|Broken'

Le pattern MSSE-XXXX-server est caracteristique de Cobalt Strike (Microsoft Security Service Emulator).


Tache 5 : Quel est le PID du processus injecte ?

Methode : Le PID est stocke dans le stream MiscInfo du minidump.

mf = MinidumpFile.parse('notepad.DMP')
print(f'PID: {mf.misc_info.ProcessId}')

Tache 6 : Quel est le timestamp du dernier thread cree ?

Format attendu : YYYY-MM-DD hh:mm:ss

Methode : Les informations de thread incluent le CreateTime en format Windows FILETIME (intervalles de 100 nanosecondes depuis le 1er janvier 1601).

from datetime import datetime, timedelta
EPOCH_AS_FILETIME = 116444736000000000
def filetime_to_dt(ft):
us = (ft - EPOCH_AS_FILETIME) // 10
return datetime(1970, 1, 1) + timedelta(microseconds=us)
mf = MinidumpFile.parse('notepad.DMP')
for info in mf.thread_info.infos:
dt = filetime_to_dt(info.CreateTime)
print(f'Thread {info.ThreadId}: {dt}')

Le dernier thread cree est celui avec le timestamp le plus recent.


Tache 7 : Quelle est la BaseAddress du shellcode injecte ?

Format attendu : XX`XXXXXXXX

Methode : Le shellcode est generalement place dans une region memoire avec les permissions PAGE_EXECUTE_READWRITE (RWX) de type MEM_PRIVATE - caracteristique d’une allocation suspecte.

mf = MinidumpFile.parse('notepad.DMP')
for mi in mf.memory_info.infos:
protect = str(mi.Protect)
mtype = str(mi.Type)
if 'EXECUTE' in protect and 'IMAGE' not in mtype:
print(f'Base: 0x{mi.BaseAddress:x}, Size: {mi.RegionSize}')

Pour confirmer l’adresse, correler avec le StartAddress des threads - le thread injecte aura son point d’entree dans cette region.


Tache 8 : Quelle est l’adresse IP du serveur C2 ?

Methode : Recherche d’adresses IP dans la memoire du processus injecte.

Fenêtre du terminal
strings notepad.DMP | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort | uniq -c | sort -rn

Verifier le contexte des IP suspectes :

Fenêtre du terminal
strings notepad.DMP | grep 'IP_SUSPECTE'

Indices a rechercher :

  • URLs HTTP avec chemins suspects (/submit.php, URIs courtes aleatoires)
  • Headers HTTP (Host:, GET, POST)
  • Ports non-standard

Tache 9 : Quel framework C2 a ete utilise ?

Methode : Recherche de signatures connues de frameworks C2.

Fenêtre du terminal
strings notepad.DMP | grep -iE 'beacon|cobaltstrike|metasploit|meterpreter|sliver|havoc'

Indicateurs courants de Cobalt Strike :

  • Presence de beacon.dll ou beacon.x64.dll
  • Named pipe MSSE-XXXX-server
  • Pattern d’URI HTTP caracteristique
  • Strings %s (admin), %s as %s\\%s

Techniques d’analyse complementaires

Extraction de la memoire du shellcode

# Lire le contenu memoire a une adresse specifique
for segment in mf.memory_segments:
if segment.start_virtual_address == SHELLCODE_BASE:
data = segment.read(segment.start_virtual_address, segment.size)
with open('shellcode.bin', 'wb') as f:
f.write(data)

Detection de process injection

IndicateurDescription
Region RWXMemoire avec Execute+Read+Write (suspect)
MEM_PRIVATEAllocation privee (pas un module mappe)
Thread StartAddressPointe vers une region non-image
Module sans versionDLL/EXE avec version 0.0.0.0

Commandes strings utiles

Fenêtre du terminal
# Recherche d'URLs
strings dump.DMP | grep -iE 'http://|https://'
# Recherche de chemins Windows
strings dump.DMP | grep -iE 'C:\\Users\\|C:\\Windows\\'
# Recherche de noms de fichiers
strings dump.DMP | grep -iE '\.exe|\.dll|\.bat|\.ps1'
# Recherche de named pipes
strings dump.DMP | grep -i 'pipe'

Ressources