Un attaquant qui prend pied dans un réseau Windows laisse des traces, presque toujours dans les mêmes quinze événements. Il crée des comptes, demande des tickets Kerberos, lance des processus, installe des services, et, pour finir, efface le journal. Voici lesquels, ce qui doit alerter, les pièges, et un script de détection que nous avons testé sur des événements de démonstration.
Ce qu’il faut retenir
- Quinze événements couvrent l’essentiel : accès (4624, 4625, 4648, 4672), exécution (4688, 4104), persistance (4697, 4698, 4720, 4728 et 4732), vol d’identifiants (4768, 4769, 4662, 4776) et effacement des traces (1102).
- Ils ne sont pas tous enregistrés par défaut. Chacun dépend d’une sous-catégorie de la stratégie d’audit avancée ; la ligne de commande des processus (4688) et le contenu des scripts PowerShell (4104) demandent en plus un réglage spécifique.
- Un événement seul ne prouve rien ; c’est l’enchaînement qui alerte : un compte créé puis ajouté à Domain Admins quelques minutes plus tard, des échecs sur dix comptes différents depuis une même adresse, cinq tickets de service en RC4 ou plus en quelques minutes.
- Le journal de la machine attaquée n’est pas une preuve fiable : l’événement 1102 existe précisément parce qu’on peut l’effacer. Il faut centraliser les journaux hors de la machine.
Avant de chercher : activer l’audit
Chaque page de la documentation Microsoft indique la sous-catégorie d’audit dont dépend l’événement. Si elle n’est pas activée sur la machine concernée, l’événement n’est pas écrit.
| Sous-catégorie d’audit | Événements |
|---|---|
| Audit Logon | 4624, 4625, 4648 |
| Audit Special Logon | 4672 |
| Audit Process Creation | 4688 |
| Audit Security System Extension | 4697 |
| Audit Other Object Access Events | 4698 |
| Audit User Account Management | 4720 |
| Audit Security Group Management | 4728, 4732 |
| Audit Kerberos Authentication Service | 4768 |
| Audit Kerberos Service Ticket Operations | 4769 |
| Audit Directory Service Access | 4662 (sur les contrôleurs de domaine) |
| Audit Credential Validation | 4776 |
| Other Events | 1102 |
Deux réglages supplémentaires sont nécessaires. Pour l’événement 4688, la ligne de commande est vide par défaut : Microsoft indique d’activer la stratégie de groupe « Administrative Templates\System\Audit Process Creation\Include command line in process creation events ». Pour l’événement 4104, il faut activer la journalisation des blocs de script PowerShell (« Turn on PowerShell Script Block Logging » dans la stratégie de groupe) ; Microsoft recommande d’y associer la journalisation protégée, car le contenu des scripts peut être sensible. Pour Windows PowerShell 5.1, l’événement est écrit dans le journal Microsoft-Windows-PowerShell/Operational.
Vous pouvez vérifier et régler l’audit en ligne de commande avec auditpol (nous n’avons pas de domaine Windows dans notre banc d’essai : ces deux commandes n’ont pas été exécutées pour cet article, vérifiez le nom exact des sous-catégories dans votre langue) :
auditpol /get /category:*
auditpol /set /subcategory:"Process Creation" /success:enable
La carte des quinze événements

Accès : qui se connecte, comment, avec quels droits
| ID | Ce que l’événement dit | Ce qui doit alerter | ATT&CK |
|---|---|---|---|
| 4624 | Ouverture de session réussie. Le champ « Logon Type » distingue 3 (réseau), 9 (NewCredentials), 10 (RemoteInteractive, c’est-à-dire le Bureau à distance) | Type 10 depuis une adresse externe ou vers un contrôleur de domaine ou un serveur de sauvegarde ; comptes administrateurs hors des heures habituelles | T1021.001, T1021.002 |
| 4625 | Échec d’ouverture de session | Un même IP en échec sur beaucoup de comptes différents (pulvérisation) ; Microsoft recommande de surveiller tous les 4625 sur les comptes locaux et de service, qui ne devraient pas échouer | T1110 |
| 4648 | Ouverture de session avec des identifiants explicites (un compte en utilise un autre) | Utilisation d’un compte à privilèges depuis un poste où il ne devrait pas apparaître ; utilisation hors des heures de travail (recommandations de Microsoft) | – |
| 4672 | Privilèges spéciaux attribués à une nouvelle session | Sujet autre que SYSTEM, NETWORK SERVICE, LOCAL SERVICE et les administrateurs attendus ; privilège SeDebugPrivilege hors des comptes qui en ont besoin (recommandations de Microsoft) | – |
Exécution : ce qui tourne sur la machine
| ID | Ce que l’événement dit | Ce qui doit alerter | ATT&CK |
|---|---|---|---|
| 4688 | Un nouveau processus a été créé, avec sa ligne de commande si le réglage est activé | Exécutables hors de System32 et de Program Files ; outils d’énumération (whoami, net user) ; commandes de destruction des sauvegardes (vssadmin delete shadows, wmic shadowcopy delete, bcdedit), citées par la CISA | T1059 |
| 4104 | Contenu d’un bloc de script PowerShell, dans le journal PowerShell/Operational | Scripts encodés ou obscurcis, téléchargement puis exécution de code distant, appels à des outils d’attaque connus | T1059.001 |
Persistance : ce qui reste après le départ de l’attaquant
| ID | Ce que l’événement dit | Ce qui doit alerter | ATT&CK |
|---|---|---|---|
| 4697 | Un service a été installé (le journal Système contient l’événement 7045 pour la même action) | Fichier de service hors de %windir% et Program Files ; service qui s’exécute sous un compte utilisateur ; installation inattendue sur un serveur sensible (recommandations de Microsoft) | T1543.003 |
| 4698 | Une tâche planifiée a été créée | Toute création sur un serveur critique ; tâche à la racine de la bibliothèque ; contenu XML avec <LogonType>Password</LogonType> (le mot de passe est alors stocké en clair dans le gestionnaire d’informations d’identification, selon Microsoft) | T1053.005 |
| 4720 | Un compte utilisateur a été créé | Création hors du processus habituel ; nom qui imite un compte existant à un caractère près ; créateur qui n’est pas un compte du support | T1136 |
| 4732 / 4728 | Un membre a été ajouté à un groupe de sécurité local (4732) ou global (4728) | Tout ajout à Domain Admins, Enterprise Admins, Administrateurs : alerte immédiate, jour et nuit | T1098 |
Identifiants : Kerberos, réplication et NTLM
| ID | Ce que l’événement dit | Ce qui doit alerter | ATT&CK |
|---|---|---|---|
| 4768 | Un ticket d’authentification Kerberos (TGT) a été demandé | Type de pré-authentification 0 (« Logon without Pre-Authentication ») : compte configuré sans pré-authentification, cible du AS-REP roasting ; adresse cliente hors des plages internes (Microsoft) | T1558.004 |
| 4769 | Un ticket de service Kerberos a été demandé | Type de chiffrement 0x17 (RC4-HMAC) alors que 0x11 et 0x12 (AES) sont les valeurs attendues ; beaucoup de services demandés par un même compte en peu de temps | T1558.003 |
| 4662 | Une opération a été effectuée sur un objet de l’annuaire | Propriétés portant les GUID de droits de réplication 1131f6aa-… et 1131f6ad-… utilisés par un compte qui n’est pas un contrôleur de domaine | T1003.006 |
| 4776 | Le contrôleur a tenté de valider des identifiants (authentification NTLM) | Le même poste source qui valide de nombreux comptes différents ; comptes inactifs ou à ne jamais utiliser (recommandations de Microsoft) | – |
Effacement : la trace qui dit qu’on a voulu en effacer d’autres
| ID | Ce que l’événement dit | Ce qui doit alerter | ATT&CK |
|---|---|---|---|
| 1102 | Le journal d’audit a été effacé | Microsoft : « en principe, vous ne devriez pas voir cet événement » ; il faut enquêter sur chaque occurrence | T1685.005 (ancien T1070.001, que MITRE redirige) |
MITRE cite parmi les usages observés de cette technique la commande wevtutil cl security chez APT28 et BlackCat. Un attaquant qui efface le journal produit lui-même l’événement 1102 : s’il est transmis à un serveur central avant l’effacement, l’alerte existe.
Quelques détails qui font la différence
- 4769 en RC4. La documentation indique que RC4 (0x17) est la suite par défaut des systèmes antérieurs à Windows Vista et Server 2008, et qu’il faut surveiller les types autres que 0x11 et 0x12. Attention aux faux positifs : un compte de service ancien peut légitimement rester en RC4. MITRE rapproche aussi le Kerberoasting d’un nombre inhabituel de tickets demandés en peu de temps.
- 4662 et la réplication. Les contrôleurs de domaine se répliquent légitimement entre eux : la règle porte sur les comptes qui ne sont pas des comptes machine. Cet événement n’est produit que si une liste de contrôle d’accès d’audit (SACL) est posée sur l’objet du domaine, en plus de la sous-catégorie d’audit.
- 4624 et 4625 sont très bavards. Ne cherchez pas l’anomalie dans chaque ligne : agrégez par adresse, par compte et par type de session.
- 4672 apparaît à chaque ouverture de session administrateur : utile pour dresser la liste de qui a des privilèges spéciaux, pas comme alerte brute.
Un script de détection, testé
Le script suivant (Python, bibliothèque standard uniquement) lit un export XML du journal Security (wevtutil qe Security /f:xml > sec.xml) et applique six règles : Kerberoasting, pulvérisation de mots de passe, ajout à un groupe privilégié, compte créé puis élevé en moins de 15 minutes, effacement du journal et DCSync.
#!/usr/bin/env python3
"""Chasse dans des événements Windows exportés en XML (wevtutil qe Security /f:xml > sec.xml)."""
import sys, re, xml.etree.ElementTree as ET
from collections import defaultdict
from datetime import datetime, timedelta
PRIV = {"Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators", "Administrateurs",
"Admins du domaine", "Administrateurs de l'entreprise"}
DCSYNC = ("1131f6aa-9c07-11d1-f79f-00c04fc2dcd2", "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2")
def events(path):
raw = re.sub(r"<\?xml[^>]*\?>", "", open(path, encoding="utf-8-sig").read())
root = ET.fromstring("<Events>" + raw + "</Events>")
for ev in root:
d = {}
for el in ev.iter():
tag = el.tag.split("}")[-1]
if tag == "EventID": d["id"] = int(el.text)
elif tag == "TimeCreated": d["t"] = datetime.fromisoformat(el.get("SystemTime").rstrip("Z")[:26])
elif tag == "Data" and el.get("Name"): d[el.get("Name")] = (el.text or "").strip()
elif len(el) == 0 and el.text and tag not in ("EventID", "Data"): d.setdefault(tag, el.text.strip())
if "id" in d and "t" in d:
yield d
def window(items, key, n, minutes, distinct):
"""Retourne les clés pour lesquelles >= n valeurs distinctes apparaissent dans une fenêtre glissante."""
by = defaultdict(list)
for e in items:
by[key(e)].append(e)
for k, lst in by.items():
lst.sort(key=lambda e: e["t"])
for i, first in enumerate(lst):
seen = {distinct(e) for e in lst[i:] if e["t"] - first["t"] <= timedelta(minutes=minutes)}
if len(seen) >= n:
yield k, first["t"], sorted(seen)
break
def hunt(evs, spn_min=5, spray_min=10):
out = []
ev = list(evs)
tgs = [e for e in ev if e["id"] == 4769 and e.get("TicketEncryptionType") == "0x17" and e.get("Status") == "0x0"
and not e.get("ServiceName", "").endswith("$") and e.get("ServiceName", "").lower() != "krbtgt"]
for (user, ip), t, svc in window(tgs, lambda e: (e["TargetUserName"], e["IpAddress"]), spn_min, 10, lambda e: e["ServiceName"]):
out.append((t, "KERBEROASTING", f"{user} depuis {ip} : tickets RC4 pour {len(svc)} services ({', '.join(svc[:4])}...)"))
fails = [e for e in ev if e["id"] == 4625 and e.get("TargetUserName")]
for ip, t, users in window(fails, lambda e: e["IpAddress"], spray_min, 10, lambda e: e["TargetUserName"]):
out.append((t, "PULVERISATION", f"{ip} : échecs sur {len(users)} comptes différents en 10 min"))
adds = [e for e in ev if e["id"] in (4728, 4732, 4756)]
for e in adds:
if e.get("TargetUserName") in PRIV:
out.append((e["t"], "GROUPE_PRIVILEGIE", f"{e['MemberName']} ajouté à {e['TargetUserName']} par {e['SubjectUserName']}"))
created = {e["TargetSid"]: e for e in ev if e["id"] == 4720}
for e in adds:
c = created.get(e.get("MemberSid"))
if c and timedelta(0) <= e["t"] - c["t"] <= timedelta(minutes=15):
out.append((e["t"], "COMPTE_CREE_PUIS_ELEVE", f"{c['TargetUserName']} créé par {c['SubjectUserName']}, ajouté à {e['TargetUserName']} {int((e['t']-c['t']).total_seconds())} s plus tard"))
for e in ev:
if e["id"] == 1102:
out.append((e["t"], "JOURNAL_EFFACE", f"journal Security effacé par {e.get('SubjectUserName', '?')}"))
if e["id"] == 4662 and not e.get("SubjectUserName", "").endswith("$") and any(g in e.get("Properties", "").lower() for g in DCSYNC):
out.append((e["t"], "DCSYNC", f"droits de réplication utilisés par {e['SubjectUserName']}"))
return sorted(out)
if __name__ == "__main__":
for t, rule, msg in hunt(events(sys.argv[1])):
print(f"{t:%Y-%m-%d %H:%M:%S} {rule:<24} {msg}")
Nous l’avons testé sur 28 événements de démonstration que nous avons fabriqués en respectant les noms de champs des exemples XML de Microsoft Learn. Ce ne sont pas des événements issus d’une vraie intrusion : le test vérifie la logique des règles, pas leur taux de faux positifs dans votre réseau. Résultat :
2026-09-29 02:00:00 KERBEROASTING jdupont@CONTOSO.LOCAL depuis ::ffff:10.0.5.23 : tickets RC4 pour 6 services (CIFS/files, FTP/backup, HTTP/intranet, HTTP/wiki...)
2026-09-29 02:30:00 PULVERISATION 203.0.113.9 : échecs sur 12 comptes différents en 10 min
2026-09-29 03:04:00 COMPTE_CREE_PUIS_ELEVE administratr créé par svc-backup, ajouté à Domain Admins 240 s plus tard
2026-09-29 03:04:00 GROUPE_PRIVILEGIE CN=administratr,CN=Users,DC=contoso,DC=local ajouté à Domain Admins par svc-backup
2026-09-29 05:00:00 JOURNAL_EFFACE journal Security effacé par administratr
2026-09-29 05:05:00 DCSYNC droits de réplication utilisés par administratr
Les cas normaux mêlés aux données de test ne déclenchent rien : trois échecs de connexion d’un utilisateur, un ticket AES, l’ajout d’un compte à un groupe non privilégié, et la réplication effectuée par un compte machine de contrôleur de domaine. Le scénario « compte créé puis ajouté à Domain Admins » reprend celui de l’intrusion Lynx décrite dans notre article sur les rançongiciels. Les noms de groupes privilégiés du script sont ceux d’une installation anglaise et française : adaptez-les à votre annuaire.
Les pièges à éviter
- Auditer sur la machine seulement. Sans centralisation, un attaquant qui efface le journal efface aussi la preuve. Transmettez les événements à un collecteur avant tout.
- Tout activer sans réfléchir au volume. Le journal Security tourne vite sur un contrôleur de domaine ; dimensionnez la taille et la rétention, sinon les événements utiles sont écrasés en quelques heures.
- Oublier la ligne de commande dans 4688. Sans elle, l’événement dit qu’un processus a démarré, pas ce qu’il a fait.
- Chercher les outils par leur nom. Un exécutable renommé passe entre les mailles : privilégiez les comportements (création de compte, réplication, RC4 en rafale).
- Ne pas horodater de façon cohérente. Des horloges qui dérivent rendent les corrélations sur quelques minutes impossibles.
- Traiter les alertes seulement en journée. Voir notre article sur les rançongiciels : l’essentiel des déploiements a lieu hors des heures ouvrées.
Huit questions pour votre parc
- Les douze sous-catégories du tableau sont-elles activées sur les contrôleurs de domaine et les serveurs sensibles ?
- La ligne de commande des processus est-elle enregistrée (4688) ?
- La journalisation des blocs de script PowerShell est-elle active, avec protection des événements ?
- Les journaux quittent-ils la machine avant qu’un attaquant puisse les effacer ?
- Qui est alerté, à toute heure, d’un ajout à Domain Admins ?
- Savez-vous lister les comptes de service encore en RC4 ?
- Une SACL d’audit protège-t-elle l’objet du domaine pour détecter la réplication (4662) ?
- Avez-vous rejoué une attaque de test (compte créé puis élevé) pour vérifier que l’alerte se déclenche ?
En résumé
Quinze événements ne remplacent pas un outil de détection, mais ils suffisent à voir l’essentiel d’une intrusion Windows : les comptes créés, les groupes modifiés, les tickets Kerberos demandés en rafale, les services et tâches installés, la réplication de l’annuaire et l’effacement du journal. Le travail n’est pas de les connaître, mais de les activer, de les sortir de la machine et de décider qui les lit la nuit.
Transparence : cet article a été rédigé avec l’aide d’un assistant Claude. Les descriptions d’événements et les recommandations attribuées à Microsoft proviennent de leur documentation (pages consultées en septembre 2026) ; les correspondances ATT&CK ont été vérifiées sur attack.mitre.org. Le script a été exécuté sur des données synthétiques, les commandes auditpol ne l’ont pas été. Le classement par phase est le choix de l’auteur.
À lire aussi
- Rançongiciels : ce qui se passe avant le chiffrement : les gestes qui laissent ces traces, dans deux intrusions réelles.
- Active Directory : les chemins les plus courts vers Domain Admin : Kerberoasting, délégations, certificats : les chemins que ces événements trahissent.
Sources
- Microsoft Learn, événements de sécurité : 4624, 4625, 4648, 4672, 4688, 4697, 4698, 4720, 4732, 4768, 4769, 4662, 4776, 1102
- Microsoft Learn, « about_Logging_Windows » (PowerShell 7) : learn.microsoft.com ; « about_Logging » (Windows PowerShell 5.1) : learn.microsoft.com
- Microsoft Learn, droits étendus « DS-Replication-Get-Changes » et « DS-Replication-Get-Changes-All » : learn.microsoft.com
- Microsoft Learn, Defender for Identity, collecte d’événements (7045) : learn.microsoft.com
- MITRE ATT&CK : T1003.006, T1021.001, T1021.002, T1053.005, T1059, T1059.001, T1098, T1110, T1136, T1543.003, T1558.003, T1558.004, T1685.005
- CISA, « #StopRansomware Guide » (commandes de destruction des sauvegardes) : cisa.gov