| name | timeline-analysis |
| description | Guide complet de reconstruction chronologique forensique — Plaso/log2timeline, Super Timeline, MFT, Event Logs Windows, journal Linux, MAC times, corrélation d'événements, timeline explorer, et reconstruction de scénarios |
| tags | ["forensics","timeline","plaso","log2timeline","mft","event-logs","mac-times","super-timeline"] |
| version | 1 |
Analyse de Timeline — Reconstruction Chronologique
Guide exhaustif des techniques de reconstruction temporelle en investigation numérique.
1. Fondamentaux des Timelines Forensiques
Pourquoi une Timeline ?
Une timeline permet de :
- Reconstruire la séquence des événements
- Identifier les actions avant/pendant/après un incident
- Corréler les événements (réseau ↔ fichier ↔ processus)
- Détecter les anomalies temporelles
- Présenter les preuves chronologiquement
- Contredire un alibi
Types de Timelines
Timeline Simple (Body File)
Format Sleuth Kit : mtime | atime | ctime | crtime | inode | nom
Générée par : fls, icat, mactime
Utile pour : analyse rapide d'un disque
Timeline Super (Plaso)
Agrège TOUS les artefacts : FS, Registry, Event Logs, Web, Email
Générée par : log2timeline
Utile pour : investigation complète
Timeline Spécifique (Artefact)
Un seul type d'artefact : Prefetch, ShimCache, UserAssist
Générée par : Volatility, EZ Tools
Utile pour : focus sur un aspect particulier
Artefacts Temporels
SYSTÈME DE FICHIERS :
- MFT (Master File Table) : MACE / $STANDARD_INFORMATION / $FILE_NAME
- MAC times : Modified, Accessed, Changed, Created
- USN Journal : changements du volume
- $LogFile : journal NTFS transactionnel
REGISTRE :
- UserAssist : exécution de programmes GUI
- ShimCache (AppCompatCache) : .exe exécutés
- AmCache : applications installées
- ShellBags : navigation dans les dossiers
LOGS :
- Event Logs (.evtx) : Security, System, Application, PowerShell
- syslog/journald : Linux events
- auth.log : connexions SSH
APPLICATIONS :
- Web : historique, cookies, downloads, bookmarks
- Email : envoi/réception
- Messagerie : SMS, WhatsApp, Telegram
2. Plaso / log2timeline — Super Timeline
Installation
pip install plaso
sudo apt install plaso-tools
log2timeline.py --version
psort.py --version
pinfo.py --version
Création d'une Timeline
log2timeline.py --storage-file /evidence/case.plaso /evidence/disk.dd
log2timeline.py \
--storage-file /evidence/case.plaso \
--status-view window \
--partitions all \
--vss-stores all \
--hashers md5,sha256 \
/evidence/disk.dd
log2timeline.py --storage-file case.plaso \
--timezone "Europe/Paris" \
disk.dd
Analyse du Storage
pinfo.py /evidence/case.plaso
psort.py -o l2tcsv -w /evidence/timeline.csv /evidence/case.plaso
psort.py -o json -w /evidence/timeline.json /evidence/case.plaso
psort.py -o dynamic -w filtered.csv /evidence/case.plaso \
--slice '2024-07-20T00:00:00' '2024-07-21T00:00:00'
Filtrage Avancé
psort.py -o l2tcsv -w timeline.csv case.plaso \
--slice '2024-07-20T10:00:00' '2024-07-20T14:00:00'
psort.py -o l2tcsv -w webanalysis.csv case.plaso \
--parsers winreg,webhist
psort.py -o l2tcsv -w filesystem.csv case.plaso \
--query 'data_type is "fs:stat"'
psort.py -o l2tcsv -w malware_file.csv case.plaso \
--query 'filename contains "malware.exe"'
psort.py -o l2tcsv -w user_suspect.csv case.plaso \
--query 'username is "suspect"'
psort.py -o l2tcsv -w incident_window.csv case.plaso \
--slice '2024-07-20T09:30:00' '2024-07-20T10:30:00' \
--query 'data_type is "pe:compilation" or data_type contains "mft"'
Parsers Disponibles
log2timeline.py --parsers list
3. MFT (Master File Table) Timeline
Structure MFT
Chaque fichier/dossier a 2 entrées temporelles distinctes :
┌────────────────────────────────────────────────┐
│ $STANDARD_INFORMATION ($SI) │
│ - Modifié : quand l'explorateur modifie │
│ - Accédé : lecture/ouverture │
│ - Créé : création du fichier │
│ - MFT modifié : changement attributs MFT │
│ Modifiable par l'utilisateur (API) │
├────────────────────────────────────────────────┤
│ $FILE_NAME ($FN) │
│ - Mêmes 4 timestamps │
│ - MAIS mis à jour SEULEMENT par le FS │
│ - Impossible à modifier via API │
│ → SI vs FN différent = timestamp modifié ! │
└────────────────────────────────────────────────┘
Analyse MFT avec MFTECmd (EZ Tools)
MFTECmd.exe -f "C:\$MFT" --csv mft_output.csv
MFTECmd.exe -f "C:\$MFT" --csv mft.csv \
--de 2024-07-20 --dt 2024-07-22
MFTECmd.exe -f "C:\$MFT" --csv deleted.csv --deleted
MFTECmd.exe -f "C:\$MFT" --csv malware_search.csv \
--body "malware" --body "backdoor"
MFTECmd.exe -f "C:\$MFT" --csv anomaly.csv --anomaly
Analyse MFT avec Volatility
vol -f memory.raw windows.mftparser --output csv > mft_from_mem.csv
sudo pip install sleuthkit
sudo mmls disk.dd
sudo fls -o 2048 -rp disk.dd > fls_list.txt
icat -o 2048 disk.dd 0 > mft.raw
analyzeMFT.py -f mft.raw -o mft_analysis.csv
Timestamps Anormaux — Détection
grep -E "2025|2026|2030" timeline.csv
grep "1970-01-01" timeline.csv
4. Windows Event Logs (.evtx)
Événements Clés
┌──────────────────────────────────────────────────────────────┐
│ Événements de Sécurité (Security.evtx) │
├──────────────────────────────────────────────────────────────┤
│ 4624 — Logon réussi │
│ Type : 2=interactif, 3=réseau, 7=déverrouillage, │
│ 8=NetworkCleartext, 9=NewCredentials, │
│ 10=RemoteInteractive(RDP) │
│ Attributs : LogonID, TargetUser, SourceIP │
│ │
│ 4625 — Logon échoué (brute force) │
│ Status : 0xC000006D (bad password) │
│ 0xC0000064 (user not found) │
│ 0xC0000072 (account locked) │
│ │
│ 4672 — Logon avec privilèges admin (SeTcbPrivilege) │
│ 4648 — Logon avec credentials explicites (runas) │
│ │
│ 4688 — Création de processus │
│ Attributs : CreatorProcessID, ProcessName, │
│ CreatorToken (IsAdmin?) │
│ │
│ 4689 — Fin de processus │
│ 4656 — Handle ouvert vers un objet │
│ │
│ 4698 — Tâche planifiée créée │
│ 4699 — Tâche planifiée supprimée │
│ 4702 — Tâche planifiée mise à jour │
│ │
│ 4719 — Politique d'audit modifiée │
│ 1102 — Journal de sécurité effacé (ALERTE !) │
│ │
│ 5156 — Connexion sortante autorisée (Firewall) │
│ 5157 — Connexion sortante bloquée │
│ │
│ Événements Système (System.evtx) │
│ 1001 — BugCheck (BSOD / Crash dump) │
│ 7036 — Service started/stopped │
│ 7045 — Nouveau service installé │
│ │
│ PowerShell (PowerShell.evtx) │
│ 4103 — PowerShell script execution (module logging) │
│ 4104 — PowerShell script block logging │
│ 40961 — PowerShell console startup │
└──────────────────────────────────────────────────────────────┘
Extraction avec wevtutil
:: Windows natif
:: Exporter les logs
wevtutil epl Security C:\evidence\security.evtx
wevtutil epl System C:\evidence\system.evtx
wevtutil epl Application C:\evidence\app.evtx
wevtutil epl "Windows PowerShell" C:\evidence\powershell.evtx
:: Filtrage par date
wevtutil epl Security C:\evidence\security_filtered.evtx /q:"*[System[TimeCreated[timediff(@SystemTime) <= 86400000]]]"
:: 86400000 ms = 24h
:: Filtrage par EventID
wevtutil epl Security C:\evidence\sec_4624.evtx /q:"*[System[EventID=4624]]"
Extraction avec PowerShell
# Événements locaux
Get-WinEvent -LogName Security | Where-Object {$_.Id -eq 4624} | Export-Csv sec_4624.csv
# Événements d'un .evtx exporté
Get-WinEvent -Path "C:\evidence\security.evtx" -MaxEvents 1000
# Filtrage temporel
$start = Get-Date "2024-07-20"
$end = Get-Date "2024-07-22"
Get-WinEvent -FilterHashtable @{LogName='Security'; StartTime=$start; EndTime=$end} | Export-Csv timeline.csv
# Recherche de processus suspects
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4688} | Where-Object {$_.Properties[5].Value -match "powershell|cmd|rundll32|mshta"} | Format-Table TimeCreated, Properties
Extraction avec Plaso
log2timeline.py --storage-file case.plaso /evidence/windows/
psort.py -o l2tcsv -w evtx_events.csv case.plaso \
--query 'data_type is "windows:evtx:record"'
psort.py -o l2tcsv -w logon_events.csv case.plaso \
--query 'event_identifier is 4624 or event_identifier is 4625'
psort.py -o l2tcsv -w processes.csv case.plaso \
--query 'data_type contains "process" and parser contains "evtx"'
5. Timeline Linux
Journal systemd
journalctl --since "2024-07-20 00:00:00" --until "2024-07-22 23:59:59" > journal.txt
journalctl -o json-pretty --since "-7 days" > journal.json
journalctl --flush
sudo cp /var/log/journal/ /evidence/journal/ -r
journalctl -u sshd.service
journalctl -u apache2.service
journalctl _PID=1234
journalctl _COMM=sshd
journalctl -p err
log2timeline.py --storage-file case.plaso /evidence/journal/
Logs Textes Linux
/var/log/
├── auth.log
├── syslog
├── kern.log
├── dpkg.log
├── apt/
│ ├── history.log
│ └── term.log
├── apache2/
├── mysql/
├── nginx/
├── fail2ban.log
├── ufw.log
└── samba/
grep "Accepted" auth.log | awk '{print $1, $2, $9, $11, $13}' > ssh_logins.txt
grep "Failed password" auth.log | awk '{print $1, $2, $9, $11, $13}' > ssh_failures.txt
zcat auth.log.*.gz | grep "Accepted" >> ssh_logins_old.txt
cat ~/.bash_history >> bash_history.txt
Linux Timestamps MAC
stat /path/to/file
find / -mmin -60 -ls
find / -newer /tmp/reference.txt -ls
find / -not -atime -7
6. Super Timeline avec Plaso — Workflow Complet
#!/bin/bash
EVIDENCE="$1"
OUTDIR="/evidence/timeline_$(date +%Y%m%d)"
mkdir -p "$OUTDIR"
STORAGE="$OUTDIR/case.plaso"
CSV="$OUTDIR/timeline_full.csv"
echo "=== PLAZO SUPER TIMELINE ==="
echo "Source: $EVIDENCE"
echo "[1] Creating storage..."
log2timeline.py --storage-file "$STORAGE" "$EVIDENCE" --status-view window
echo "[2] Summary..."
pinfo.py "$STORAGE" > "$OUTDIR/summary.txt"
echo "[3] Exporting full timeline..."
psort.py -o l2tcsv -w "$CSV" "$STORAGE"
echo "[4] Filtered timelines..."
psort.py -o l2tcsv -w "$OUTDIR/timeline_suspicious_7d.csv" "$STORAGE" \
--slice '2024-07-15' '2024-07-22'
echo
psort.py -o l2tcsv -w \
--query
psort.py -o l2tcsv -w \
--query
psort.py -o l2tcsv -w \
--query
psort.py -o l2tcsv -w \
--query
7. USN Journal
Structure USN Journal
Le USN Journal (Update Sequence Number) enregistre TOUS les changements
sur un volume NTFS. Plus granulaire que MFT.
Format (FSCTL_READ_USN_JOURNAL) :
- USN : numéro de séquence
- Timestamp : date du changement
- Reason : MASQUES DE CAUSE
- 0x01 : USN_REASON_DATA_OVERWRITE
- 0x02 : USN_REASON_DATA_EXTEND
- 0x04 : USN_REASON_DATA_TRUNCATION
- 0x10 : USN_REASON_NAMED_DATA_EXTEND
- 0x20 : USN_REASON_NAMED_DATA_TRUNCATION
- 0x40 : USN_REASON_FILE_CREATE
- 0x80 : USN_REASON_FILE_DELETE
- 0x100 : USN_REASON_EA_CHANGE
- 0x200 : USN_REASON_SECURITY_CHANGE
- 0x400 : USN_REASON_RENAME_OLD_NAME
- 0x800 : USN_REASON_RENAME_NEW_NAME
- 0x1000 : USN_REASON_INDEXABLE_CHANGE
- 0x2000 : USN_REASON_BASIC_INFO_CHANGE
- 0x4000 : USN_REASON_HARD_LINK_CHANGE
- 0x8000 : USN_REASON_COMPRESSION_CHANGE
- 0x10000 : USN_REASON_ENCRYPTION_CHANGE
- 0x20000 : USN_REASON_OBJECT_ID_CHANGE
- 0x40000 : USN_REASON_REPARSE_POINT_CHANGE
- 0x80000 : USN_REASON_STREAM_CHANGE
- 0x100000 : USN_REASON_CLOSE
Extraction USN
fsutil usn readdata C: > usn_journal.txt
MFTECmd.exe -f "C:\$Extend\$UsnJrnl\$J" --csv usn_output.csv
MFTECmd.exe -f "C:\$Extend\$UsnJrnl\$J" --csv usn.csv --de 2024-07-20
vol -f memory.raw windows.mftparser > mft_with_usn.txt
8. Corrélation d'Événements
Reconstruction de Scénario
EXEMPLE : Infection par malware
═══════════════════════════════════════
Étape 1 : Téléchargement
10:00:00 — Web history : visite de malicious-site.com/malware.exe
10:00:01 — Event 5156 : connexion sortante vers 185.x.x.x:443
10:00:02 — Chrome.download complété → fichier téléchargé dans Downloads
Étape 2 : Exécution
10:00:05 — ShimCache : malware.exe apparaît
10:00:05 — Prefetch : malware.exe créé
10:00:05 — Event 4688 : cmd.exe /c .\malware.exe
10:00:06 — UserAssist : compteur +1 pour malware.exe
Étape 3 : Installation
10:00:10 — Registry : Run key ajoutée
10:00:12 — Event 4698 : tâche planifiée créée
10:00:15 — Event 7045 : service installé (si persistant)
Étape 4 : C2 Communication
10:00:20 — Event 5156 : connexion sortante vers C2:4443
10:00:20 — DNS query pour evil-c2.com
10:00:45 — Event 4624 : logon suspect (tokens volés ?)
Étape 5 : Effacement des traces
10:05:00 — MFT : malware.exe marqué supprimé
10:05:05 — Event 1102 : Security log effacé !
10:05:10 — USN : $UsnJrnl modifié (effacement de traces)
Technique du "Time Gap"
Un "time gap" (trou temporel) est suspect :
- Période sans événements : logs effacés, système éteint
- Jump dans la timeline : heure système modifiée
- Désynchronisation : heures entre 2 sources différentes
DÉTECTION :
- Calculer l'intervalle moyen entre événements
- Marquer les gaps > 3× l'intervalle moyen
- Vérifier Windows Event Log 4616 (system time change)
9. Timeline Explorer (EZ Zimmerman)
TimelineExplorer.exe /evidence/timeline.csv
10. Script d'Analyse de Timeline
"""analyze_timeline.py — Analyse rapide de timeline CSV"""
import csv
import sys
from collections import Counter
from datetime import datetime, timedelta
def analyze_timeline(csv_file):
events = []
with open(csv_file) as f:
reader = csv.DictReader(f)
for row in reader:
events.append(row)
print(f"Analyse de {len(events)} événements\n")
types = Counter(e.get('data_type', 'unknown') for e in events)
print("TOP 10 EVENT TYPES:")
for t, count in types.most_common(10):
print(f" {t}: {count}")
timestamps = [e['datetime'] for e in events if 'datetime' in e]
if timestamps:
print(f"\nPÉRIODE: {min(timestamps)} à {max(timestamps)}")
()
e events:
desc = e.get(, ).lower()
(kw desc kw [, , , , ]):
()
()
e events:
e.get(, ).lower():
()
__name__ == :
analyze_timeline(sys.argv[])
11. Dépannage
PROBLÈME : Plaso out of memory
SOLUTION :
- Utiliser --worker-memory-limit 2048
- Désactiver le hash (--no-hash)
- Traiter partition par partition
PROBLÈME : Timeline trop grande (>1M events)
SOLUTION :
- Filtrer par timestamp (--slice)
- Exporter en JSON (plus compact)
- Utiliser TimelineExplorer (gère les grands fichiers)
PROBLÈME : Timestamps inconsistent (UTC vs local)
SOLUTION :
- Plaso stocke en UTC
- Définir le fuseau à l'export avec --timezone
- Vérifier le fuseau du système source
PROBLÈME : Événements manquants
SOLUTION :
- Le log a été effacé (Event 1102)
- Volume Shadow Copy peut contenir des versions passées
- Utiliser --vss-stores all dans Plaso
12. Ressources