🎯 Pourquoi analyser les logs Windows en SOC ?
Le défi de l'analyste SOC
Un contrôleur de domaine Active Directory génère des centaines de milliers d'événements de sécurité par jour. Parmi eux, des tentatives de brute-force, du password spraying, des énumérations de comptes... Comment distinguer le bruit légitime (connexions échouées d'utilisateurs légitimes) des véritables attaques ?
La majorité des analystes juniors se concentrent uniquement sur l'Event ID 4625 (échec de connexion), mais c'est insuffisant. Ce guide vous montre comment construire une méthodologie d'investigation complète.
Les trois piliers de l'investigation de logs
- Identification : Savoir quels Event IDs surveiller selon le contexte d'attaque
- Corrélation : Regrouper les événements pour détecter des patterns (spray vs brute-force)
- Action : Transformer l'analyse en décision opérationnelle (bloquer, alerter, investiguer)
🔍 Au-delà du 4625 : comprendre l'écosystème des Event IDs
💡 Pourquoi plusieurs Event IDs pour l'authentification ?
Windows utilise différents mécanismes d'authentification (NTLM, Kerberos, CredSSP...) et chaque mécanisme génère ses propres événements. Un attaquant sophistiqué laisse des traces dans plusieurs journaux simultanément.
Cartographie des Event IDs par scénario d'attaque
| Event ID | Nom technique | Scénario d'attaque | Champ discriminant | Pourquoi c'est important |
|---|---|---|---|---|
| 4625 | Failed Logon | Brute-force classique | Status / Sub Status | L'événement le plus fréquent, mais nécessite un filtrage fin |
| 4648 | Explicit Logon | Mouvement latéral (RunAs, PsExec) | Target Server Name | Révèle les tentatives d'élévation de privilèges |
| 4771 | Kerberos Pre-Auth Failed | Kerberoasting / AS-REP Roasting | Client Address | Attaques ciblant le protocole Kerberos |
| 4776 | NTLM Auth Failed | Attaque sur services legacy | Package Name | Cible les systèmes non migrés vers Kerberos |
Décoder les Sub Status : la clé du triage
Le champ Sub Status de l'Event ID 4625 indique pourquoi la connexion a échoué.
C'est ce champ qui permet de différencier une erreur utilisateur d'une attaque ciblée.
| Code Sub Status | Signification | Interprétation SOC | Priorité |
|---|---|---|---|
0xC0000064 |
User name does not exist | 🚨 Énumération de comptes - l'attaquant cherche des comptes valides | HAUTE |
0xC000006A |
Incorrect password | ⚠️ Brute-force sur compte existant | MOYENNE |
0xC0000234 |
Account locked out | ✅ Résultat d'une attaque - le compte est déjà protégé | INFO |
0xC0000072 |
Account disabled | 🔍 Tentative sur compte désactivé (anciens employés ?) | MOYENNE |
Exemple de log 4625 complet (réel)
TimeCreated : 2025-08-19 14:33:12
Id : 4625
Level : Information
Message : Échec de connexion d'un compte.
Sujet :
ID de sécurité : ANONYMOUS LOGON
Informations sur le compte :
Nom du compte : j.doe
Domaine : CORP
Informations sur l'échec :
Raison : Mot de passe incorrect
Statut : 0xC000006A
Sous-état : 0xC000006A
Informations réseau :
Adresse réseau source : 185.220.101.42
Port source : 49152
Informations sur le processus :
Nom du processus appelant : -
Type d'ouverture de session : 3 (Network)
💡 Ce que révèle ce log
- IP externe (185.x.x.x) : probablement pas un employé interne
- Compte existe (0xC000006A, pas 0xC0000064)
- Logon Type 3 : tentative d'accès réseau (SMB, RDP...)
- Processus = "-" : connexion distante, pas locale
Verdict : Tentative de brute-force réseau sur compte valide
⚙️ Collecte efficace : éviter le "gros CSV" qui plante
Le problème du débutant
L'erreur classique de l'analyste junior : exporter tout le journal Security en CSV.
# ❌ NE JAMAIS FAIRE ÇA
Get-WinEvent -LogName Security | Export-Csv C:\logs.csv
⚠️ Pourquoi c'est une mauvaise idée
- Volume : Le journal Security peut contenir 500 000+ événements (2+ GB en mémoire)
- Performance : PowerShell charge TOUT en RAM avant de traiter
- Pertinence : 99% des événements sont inutiles pour l'investigation
Résultat : Script qui tourne pendant 15 minutes puis crash Out-Of-Memory
La bonne approche : filtrer AVANT de collecter
PowerShell permet de filtrer directement au niveau du moteur d'événements Windows avec -FilterHashtable.
C'est 10 à 100 fois plus rapide qu'un filtrage après collecte.
# ✅ Filtrage efficace au niveau du moteur Windows Event Log
$filter = @{
LogName = 'Security'
Id = 4625 # Échecs de connexion uniquement
StartTime = (Get-Date).AddHours(-24) # Dernières 24h
}
$events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue
Write-Host "✅ $($events.Count) événements récupérés en quelques secondes"
🔍 Pourquoi -ErrorAction SilentlyContinue ?
Si aucun événement ne correspond au filtre OU si le journal est corrompu,
Get-WinEvent génère une erreur terminale qui stoppe le script.
Cette option permet de continuer l'exécution même en cas d'erreur.
Collecte multi-Event IDs pour analyse avancée
# Collecter plusieurs types d'événements d'authentification
$eventIds = 4625, 4648, 4771, 4776
$allEvents = foreach ($id in $eventIds) {
$filter = @{
LogName = 'Security'
Id = $id
StartTime = (Get-Date).AddHours(-24)
}
Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue
}
Write-Host "📊 Total événements collectés : $($allEvents.Count)"
💻 Parsing : extraire les données enfouies dans le Message
Le problème : données non structurées
Contrairement aux logs Apache (format tabulaire), les Event Logs Windows stockent les informations
dans un champ Message en texte libre. Il faut utiliser des regex pour extraire les valeurs.
Structure typique du champ Message
Message : Échec de connexion d'un compte.
Sujet :
ID de sécurité : ANONYMOUS LOGON
Informations sur le compte :
Nom du compte : j.doe
Domaine : CORP
[...]
Construction d'un parser robuste
On utilise des regex avec captures nommées pour extraire chaque champ pertinent.
La syntaxe (?s).*champ:\s+([^\r\n]+) permet de capturer jusqu'au retour à la ligne.
$parsed = foreach ($event in $events) {
$msg = $event.Message
# Extraction avec regex non-greedy
[PSCustomObject]@{
Timestamp = $event.TimeCreated
EventID = $event.Id
Account = if ($msg -match 'Nom du compte\s*:\s*([^\r\n]+)') { $matches[1].Trim() } else { 'N/A' }
Domain = if ($msg -match 'Domaine\s*:\s*([^\r\n]+)') { $matches[1].Trim() } else { 'N/A' }
SourceIP = if ($msg -match 'Adresse réseau source\s*:\s*([^\r\n]+)') { $matches[1].Trim() } else { 'N/A' }
LogonType = if ($msg -match "Type d'ouverture de session\s*:\s*(\d+)") { $matches[1] } else { 'N/A' }
Status = if ($msg -match 'Statut\s*:\s*(0x[0-9A-F]+)') { $matches[1] } else { 'N/A' }
SubStatus = if ($msg -match 'Sous-état\s*:\s*(0x[0-9A-F]+)') { $matches[1] } else { 'N/A' }
Workstation = if ($msg -match 'Nom de la station de travail\s*:\s*([^\r\n]+)') { $matches[1].Trim() } else { 'N/A' }
}
}
Write-Host "✅ Parsing terminé : $($parsed.Count) événements structurés"
Nettoyage des données : éliminer le bruit
Avant toute analyse, il faut filtrer les faux positifs courants.
# Éliminer le bruit commun
$cleaned = $parsed | Where-Object {
$_.SourceIP -ne '-' -and # Pas d'IP = événement local
$_.SourceIP -ne '127.0.0.1' -and # Localhost
$_.SourceIP -ne '::1' -and # IPv6 localhost
$_.SourceIP -notlike '169.254.*' -and # APIPA (auto-config IP)
$_.Account -ne '-' -and # Comptes vides
$_.Account -notlike '*$' # Comptes machine (se terminent par $)
}
$removedNoise = $parsed.Count - $cleaned.Count
Write-Host "🧹 $removedNoise événements de bruit supprimés"
🚨 Détection d'attaques : comprendre les signatures
Les trois patterns d'attaque par authentification
| Type d'attaque | Signature technique | Seuil SOC | Exemple réel | Pourquoi ça marche |
|---|---|---|---|---|
| Password Spray | 1 IP × 3+ comptes × 1-3 échecs/compte | > 5 comptes distincts | 185.x.x.x → alice, bob, charlie, dave, eve (1 essai chacun) | Évite le verrouillage en testant plusieurs comptes avec des mots de passe communs |
| Brute-Force | 1 IP × 1 compte × 30+ échecs | > 30 échecs/compte | 185.x.x.x → alice (127 tentatives) | Attaque classique mais bruyante, souvent détectée par les IDS |
| Credential Stuffing | 1 IP × 10+ comptes × 1 échec/compte | > 10 comptes | 185.x.x.x → liste de 500 comptes (1 essai chacun) | Utilise des fuites de données (combo lists). Très efficace si les utilisateurs réutilisent leurs mots de passe |
Implémentation de la détection
# Regroupement par IP source
$grouped = $cleaned | Group-Object SourceIP
# Analyse de chaque IP pour détecter les patterns
$threats = foreach ($ipGroup in $grouped) {
$ip = $ipGroup.Name
$events = $ipGroup.Group
# Compter les comptes uniques ciblés
$uniqueAccounts = ($events.Account | Sort-Object -Unique)
$accountCount = $uniqueAccounts.Count
$totalAttempts = $events.Count
# Calculer la moyenne d'échecs par compte
$avgAttemptsPerAccount = if ($accountCount -gt 0) {
[math]::Round($totalAttempts / $accountCount, 1)
} else { 0 }
# Classification de la menace
$threatType = if ($accountCount -gt 10 -and $avgAttemptsPerAccount -lt 3) {
'Credential Stuffing'
} elseif ($accountCount -gt 5 -and $avgAttemptsPerAccount -lt 5) {
'Password Spray'
} elseif ($accountCount -le 3 -and $totalAttempts -gt 30) {
'Brute-Force'
} else {
'Low Priority'
}
# Identifier le Sub Status le plus fréquent
$topSubStatus = ($events.SubStatus | Group-Object | Sort-Object -Descending Count | Select-Object -First 1).Name
[PSCustomObject]@{
SourceIP = $ip
TotalAttempts = $totalAttempts
UniqueAccounts = $accountCount
AvgAttemptsPerAccount = $avgAttemptsPerAccount
ThreatType = $threatType
TopSubStatus = $topSubStatus
FirstSeen = ($events.Timestamp | Measure-Object -Minimum).Minimum
LastSeen = ($events.Timestamp | Measure-Object -Maximum).Maximum
Duration = (($events.Timestamp | Measure-Object -Maximum).Maximum - ($events.Timestamp | Measure-Object -Minimum).Minimum).TotalMinutes
TopTargetedAccounts = ($uniqueAccounts | Select-Object -First 5) -join ', '
}
}
# Filtrer uniquement les menaces réelles (pas le bruit)
$realThreats = $threats | Where-Object { $_.ThreatType -ne 'Low Priority' } | Sort-Object -Descending TotalAttempts
Write-Host "🚨 $($realThreats.Count) menaces détectées"
$realThreats | Format-Table -AutoSize
💡 Pourquoi ces seuils ?
Les seuils (5 comptes, 30 échecs) sont basés sur des retours d'expérience SOC réels. Ils minimisent les faux positifs (utilisateurs légitimes qui se trompent) tout en détectant les attaques automatisées. Ajustez-les selon votre environnement :
- PME : Seuils plus bas (3 comptes, 20 échecs)
- Grande entreprise : Seuils plus élevés (10 comptes, 50 échecs)
🌐 Enrichissement OSINT : contextualiser les IPs
Pourquoi enrichir ?
Une IP seule ne donne aucun contexte. L'enrichissement permet de répondre à :
- 📍 Où se trouve l'attaquant ? (géolocalisation)
- 🏢 Qui est le propriétaire ? (ISP, hébergeur)
- 🚨 Réputation : Cette IP est-elle déjà connue pour des activités malveillantes ?
- 🔍 Infrastructure : Quels services expose-t-elle ? (Shodan)
Sources d'enrichissement gratuites et payantes
| Service | Type de données | Limite gratuite | Cas d'usage |
|---|---|---|---|
| ip-api.com | Géolocalisation (pays, ville, ISP, ASN) | 45 req/min | Cartographie géographique des attaques |
| AbuseIPDB | Score de réputation (0-100) | 1000 req/jour | Priorisation des menaces connues |
| Shodan | Ports ouverts, vulnérabilités, banners | 100 req/mois (gratuit) | Profiling de l'infrastructure attaquante |
| VirusTotal | IOC, malware associés | 4 req/min | Vérifier si l'IP distribue des malwares |
Implémentation de l'enrichissement
$enriched = foreach ($threat in $realThreats) {
$ip = $threat.SourceIP
Write-Host "🔍 Enrichissement de $ip..." -NoNewline
# Rate limiting : 1.5 secondes entre chaque requête (40 req/min pour ip-api)
Start-Sleep -Milliseconds 1500
try {
# Géolocalisation
$geo = Invoke-RestMethod -Uri "http://ip-api.com/json/$ip" -TimeoutSec 5
# AbuseIPDB (nécessite une clé API gratuite)
$abuseHeaders = @{
'Key' = 'VOTRE_CLE_API_ABUSEIPDB'
'Accept' = 'application/json'
}
$abuse = Invoke-RestMethod -Uri "https://api.abuseipdb.com/api/v2/check?ipAddress=$ip" -Headers $abuseHeaders -TimeoutSec 5
$threat | Add-Member -NotePropertyName Country -NotePropertyValue $geo.country -PassThru |
Add-Member -NotePropertyName City -NotePropertyValue $geo.city -PassThru |
Add-Member -NotePropertyName ISP -NotePropertyValue $geo.isp -PassThru |
Add-Member -NotePropertyName ASN -NotePropertyValue $geo.as -PassThru |
Add-Member -NotePropertyName Latitude -NotePropertyValue $geo.lat -PassThru |
Add-Member -NotePropertyName Longitude -NotePropertyValue $geo.lon -PassThru |
Add-Member -NotePropertyName AbuseScore -NotePropertyValue $abuse.data.abuseConfidenceScore -PassThru
Write-Host " ✅ $($geo.country) - Score: $($abuse.data.abuseConfidenceScore)%"
} catch {
Write-Host " ⚠️ Échec" -ForegroundColor Yellow
$threat | Add-Member -NotePropertyName Country -NotePropertyValue 'Unknown' -PassThru
}
}
# Tri par score d'abus décroissant
$enriched = $enriched | Sort-Object -Descending AbuseScore
⚠️ Attention aux rate limits
Les APIs gratuites ont des limites strictes. Si vous analysez 100 IPs avec ip-api.com (45 req/min), le script mettra environ 2-3 minutes. C'est normal et nécessaire pour respecter les conditions d'utilisation.
Pour des analyses plus rapides, envisagez une base de données locale de géolocalisation (MaxMind GeoLite2).
📊 Visualisation : carte interactive et heatmap
Pourquoi visualiser ?
Un tableau de 50 IPs est difficile à interpréter. Une carte permet de :
- Identifier les zones géographiques d'où proviennent les attaques
- Détecter les patterns de clustering (même hébergeur, même pays)
- Communiquer efficacement avec le management (impact visuel)
Génération d'une carte Leaflet avec clustering
# Conversion en JSON pour injection dans le HTML
$mapData = $enriched | Select-Object SourceIP, Latitude, Longitude, Country, City, ISP, TotalAttempts, UniqueAccounts, ThreatType, AbuseScore | ConvertTo-Json -Compress
$htmlReport = @"
Analyse des Tentatives d'Intrusion Windows
"@
$reportPath = "C:\Temp\rapport_intrusions_windows.html"
$htmlReport | Out-File -FilePath $reportPath -Encoding UTF8
Write-Host "✅ Rapport HTML généré : $reportPath"
Start-Process $reportPath
🛡️ Remédiation : du détection à l'action
Philosophie de la réponse à incident
Détecter une attaque sans agir ne sert à rien. La remédiation doit être proportionnée, automatisable et traçable. Voici les trois niveaux de réponse selon la criticité.
Matrice de décision : action selon le contexte
| Action | Déclencheur | Outil | Commande | Impact |
|---|---|---|---|---|
| 🔍 Investigation | Score < 50, 5-10 comptes | SIEM / Elastic | | where SourceIP == "x.x.x.x" |
Aucun - Collecte d'informations |
| 📧 Alerte SOC | Score 50-75, >10 comptes | Teams / Email | Send-MailMessage |
Notification uniquement |
| 🚫 Blocage temporaire | Score > 75, Password Spray | Firewall / WAF | New-NetFirewallRule -RemoteAddress $ip |
Blocage 24h (risque de faux positif) |
| 🔒 Blocage permanent | Score > 90, IoC connu | EDL / Threat Intel | Add-PanAddressGroupMember |
Blocage définitif |
| 👤 Verrouillage compte | Compte compromis confirmé | Active Directory | Disable-ADAccount |
Impact utilisateur fort |
Implémentation : playbook automatisé
# Playbook de réponse automatisée
foreach ($threat in $enriched) {
$ip = $threat.SourceIP
$score = $threat.AbuseScore
$type = $threat.ThreatType
# NIVEAU 1 : Investigation (tous les cas)
Write-Host "🔍 Investigation de $ip ($type, Score: $score%)"
# NIVEAU 2 : Alerte si score modéré
if ($score -gt 50 -and $score -le 75) {
$alertBody = @"
🚨 ALERTE SOC - Tentative d'intrusion détectée
IP Source : $ip
Localisation : $($threat.City), $($threat.Country)
ISP : $($threat.ISP)
Score d'abus : $score%
Type d'attaque : $type
Tentatives : $($threat.TotalAttempts)
Comptes ciblés : $($threat.UniqueAccounts)
Comptes les plus ciblés : $($threat.TopTargetedAccounts)
Action recommandée : Investigation manuelle
"@
# Envoi email
Send-MailMessage `
-To "soc@votreentreprise.com" `
-From "noreply@votreentreprise.com" `
-Subject "[SOC] Tentative d'intrusion - $ip" `
-Body $alertBody `
-SmtpServer "smtp.votreentreprise.com"
Write-Host "📧 Alerte envoyée au SOC" -ForegroundColor Yellow
}
# NIVEAU 3 : Blocage temporaire si score élevé
if ($score -gt 75 -and $score -le 90) {
Write-Host "🚫 Blocage temporaire de $ip (24h)" -ForegroundColor Red
# Exemple avec Windows Firewall
$ruleName = "SOC_Block_$($ip -replace '\.','_')"
New-NetFirewallRule `
-DisplayName $ruleName `
-Direction Inbound `
-Action Block `
-RemoteAddress $ip `
-Description "Auto-blocked by SOC - Score: $score%" `
-ErrorAction SilentlyContinue
# Planifier la suppression après 24h
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-Command `"Remove-NetFirewallRule -DisplayName '$ruleName'`""
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddHours(24)
Register-ScheduledTask -TaskName "SOC_Unblock_$($ip -replace '\.','_')" -Action $action -Trigger $trigger
}
# NIVEAU 4 : Blocage permanent si score critique
if ($score -gt 90) {
Write-Host "🔒 BLOCAGE PERMANENT de $ip" -ForegroundColor Red -BackgroundColor White
# Ajout à une blacklist permanente
$blacklistPath = "C:\SOC\blacklist.txt"
Add-Content -Path $blacklistPath -Value "$ip`t$score`t$(Get-Date)`t$type"
# Blocage firewall permanent
$ruleName = "SOC_Permanent_Block_$($ip -replace '\.','_')"
New-NetFirewallRule `
-DisplayName $ruleName `
-Direction Inbound `
-Action Block `
-RemoteAddress $ip `
-Description "Permanent block - Score: $score% - $type" `
-ErrorAction SilentlyContinue
}
}
Write-Host "`n✅ Playbook de remédiation exécuté"
⚠️ Attention aux faux positifs
Le blocage automatique peut impacter des utilisateurs légitimes (VPN partagés, proxies d'entreprise). Recommandations :
- Toujours vérifier manuellement avant un blocage permanent
- Maintenir une whitelist d'IPs critiques (partenaires, services cloud)
- Logger toutes les actions pour audit
📋 Checklist de l'analyste SOC
Workflow complet en 8 étapes
- ⏰ Définir la fenêtre temporelle : 24h pour incident récent, 7j pour analyse de tendance
- 🔍 Collecter les Event IDs pertinents : 4625, 4648, 4771, 4776
- 🧹 Nettoyer le bruit : Éliminer localhost, IPs internes, comptes machine
- 📊 Parser et structurer : Extraire IP, compte, Sub Status, timestamp
- 🚨 Détecter les patterns : Spray (>5 comptes), Brute-force (>30 échecs)
- 🌐 Enrichir avec OSINT : Géolocalisation, AbuseIPDB, Shodan
- 📈 Visualiser et rapporter : Carte interactive + export CSV
- 🛡️ Remédier selon playbook : Alerte → Blocage temporaire → Blocage permanent
Temps estimé par étape (100 IPs suspectes)
| Étape | Temps manuel | Temps automatisé | Gain |
|---|---|---|---|
| Collecte et filtrage | 15 minutes | 10 secondes | 99% |
| Parsing des logs | 30 minutes | 5 secondes | 99% |
| Détection de patterns | 20 minutes | 2 secondes | 99% |
| Enrichissement OSINT | 2 heures | 3-5 minutes | 95% |
| Rapport et visualisation | 30 minutes | 5 secondes | 99% |
| TOTAL | 3h35min | 5-7 minutes | 97% |
🚀 Aller plus loin : techniques avancées
1. Analyse temporelle : détecter les attaques distribuées
Les attaquants sophistiqués utilisent des botnets pour répartir les tentatives sur plusieurs IPs. Une analyse temporelle révèle ces coordinations.
# Regroupement par fenêtres de 5 minutes
$timeWindows = $parsed | Group-Object {
$_.Timestamp.ToString("yyyy-MM-dd HH:") + ([Math]::Floor($_.Timestamp.Minute / 5) * 5)
}
# Détecter les pics d'activité
$spikes = $timeWindows | Where-Object { $_.Count -gt 50 } | Sort-Object -Descending Count
Write-Host "⚡ $($spikes.Count) pics d'activité détectés"
2. Analyse de User-Agent : détecter les outils d'attaque
Certains Event IDs (4648, 4771) contiennent des informations sur le processus ou le client utilisé.
# Extraction de patterns suspects dans les User-Agents / Process Names
$suspiciousTools = @('python', 'curl', 'hydra', 'nmap', 'metasploit', 'sqlmap', 'burp')
$toolDetection = $parsed | Where-Object {
$msg = $_.Message
$suspiciousTools | Where-Object { $msg -like "*$_*" }
}
if ($toolDetection) {
Write-Host "🔧 Outils d'attaque détectés : $($toolDetection.Count) événements"
}
3. Corrélation avec d'autres sources
- Logs VPN : Les attaquants testent souvent plusieurs vecteurs (VPN + RDP)
- Logs Web : Corréler avec les logs Apache/IIS pour identifier les scans web → brute-force
- Threat Intelligence : Importer des feeds MISP/STIX pour comparer les IPs
4. Machine Learning : prédire les attaques
Avec des historiques de logs suffisants, il est possible d'entraîner un modèle de détection d'anomalies.
# Export pour analyse ML (Python/scikit-learn)
$mlDataset = $parsed | Select-Object `
@{N='Hour';E={$_.Timestamp.Hour}},
@{N='DayOfWeek';E={$_.Timestamp.DayOfWeek}},
@{N='AttemptsPerIP';E={($parsed | Where-Object {$_.SourceIP -eq $_.SourceIP}).Count}},
@{N='UniqueAccounts';E={(($parsed | Where-Object {$_.SourceIP -eq $_.SourceIP}).Account | Sort-Object -Unique).Count}},
@{N='IsAttack';E={if ($_.ThreatType -ne 'Low Priority') {1} else {0}}}
$mlDataset | Export-Csv C:\SOC\ml_training_data.csv -NoTypeInformation
🎓 Conclusion : PowerShell, couteau suisse du SOC
En 200 lignes de PowerShell, vous avez construit un pipeline d'analyse complet qui rivalise avec des outils commerciaux. La clé n'est pas l'outil, mais la compréhension des mécanismes d'attaque.
Ce que vous avez appris :
- ✅ Identifier les bons Event IDs selon le type d'attaque
- ✅ Décoder les Sub Status pour éliminer le bruit
- ✅ Parser des données non structurées avec des regex
- ✅ Détecter les signatures d'attaque (Spray, Brute-force, Stuffing)
- ✅ Enrichir avec des sources OSINT externes
- ✅ Automatiser la remédiation avec des playbooks
Différence entre analyste junior et senior :
| Aspect | Junior | Senior |
|---|---|---|
| Approche | Cherche l'Event ID 4625 uniquement | Corrèle 4625, 4648, 4771, 4776 + logs applicatifs |
| Filtrage | Exporte tout en CSV | Filtre au niveau du moteur Windows |
| Détection | Compte les échecs bruts | Analyse les patterns (ratio comptes/échecs) |
| Contexte | Se limite à l'IP | Enrichit avec géoloc, réputation, infrastructure |
| Action | Crée un ticket JIRA | Automatise la remédiation selon playbook |
Prochaines étapes :
- 🔄 Automatiser l'exécution quotidienne (Task Scheduler)
- 📊 Intégrer dans un SIEM (Elastic, Splunk)
- 🤖 Ajouter du Machine Learning pour la détection d'anomalies
- 🌐 Corréler avec les logs réseau (firewall, proxy)
- 📱 Intégrer des alertes Teams/Slack en temps réel
📚 Ressources complémentaires
💬 Message final
Ce guide n'est pas un script à copier-coller, mais une méthodologie d'investigation. Adaptez les seuils à votre environnement, enrichissez avec vos propres sources, et surtout : comprenez ce que vous cherchez avant de lancer un outil.
Le meilleur analyste SOC n'est pas celui qui connaît le plus d'outils, mais celui qui comprend le mieux les tactiques des attaquants.