Analyse des journaux d'audit Microsoft entra
Tandis que les journaux de connexion enregistrent les franchissements du périmètre d’authentification, les journaux d’audit d’annuaire Microsoft Entra ID (Directory Audit Logs) consignent la manière dont l’annuaire lui-même est modifié. Lors d’une cyberattaque dans le cloud, un pirate ne se contente presque jamais d’utiliser passivement des identifiants volés : il altère les objets de l’annuaire pour installer sa persistance, élever ses privilèges, contourner les politiques de sécurité et exfiltrer des ressources stratégiques.
Les journaux d’audit d’Entra ID enregistrent chaque mutation administrative, programmatique et de cycle de vie : création d’utilisateurs, modifications de groupes, attributions de rôles d’annuaire, activations Privileged Identity Management (PIM), consentements accordés à des applications OAuth, injections de certificats ou de secrets sur des principaux de service et modifications des politiques de sécurité.
Cette fiche fournit une analyse forensique complète des journaux d’audit Entra, de leur schéma JSON, des événements critiques d’attaque et des requêtes de détection en environnement de production.
Les journaux d’audit d’Entra ID fonctionnent comme un registre immuable consignant l’ensemble des transitions d’état sur les objets du plan de contrôle :
graph TD subgraph "Moteur de mutation de l'annuaire Entra ID" ADMIN[Action Admin / Script / Élévation PIM] APP[Application automatisée / Principal de service]
ADMIN -->|Exécution de la modification| CORE[Magasin central Entra Directory] APP -->|Exécution de la modification| CORE
CORE -->|Génération de l'événement d'audit| PIPELINE[Pipeline d'ingestion d'audit]
PIPELINE --> AUDIT_LOG["Journaux d'Audit d'Annuaire<br/>(AuditLogs dans Sentinel / Graph API)"]
AUDIT_LOG --> CAT1[Cycle de vie Utilisateurs & Groupes] AUDIT_LOG --> CAT2[Gestion des Rôles & Activations PIM] AUDIT_LOG --> CAT3[Enregistrement d'Apps & Injection de Secrets] AUDIT_LOG --> CAT4[Octroi de Consentements OAuth] AUDIT_LOG --> CAT5[Accès Conditionnel & Politiques de Sécurité] endCatégories fondamentales
Section intitulée « Catégories fondamentales »- UserManagement & GroupManagement : création et désactivation de comptes, réinitialisation de mots de passe, modifications des membres de groupes de sécurité ou de groupes assignables à des rôles.
- RoleManagement : attributions directes et éligibilités de rôles hautement privilégiés (
Global Administrator), révocations et approbations PIM. - ApplicationManagement : enregistrement d’applications, création de principaux de service et ajout de secrets clients ou certificats (vecteur privilégié de persistance).
- ConsentManagement : octrois de consentements utilisateur et administrateur pour des autorisations déléguées ou applicatives (
OAuth2PermissionGrant). - Policy : création, modification ou suppression de politiques d’accès conditionnel, d’emplacements nommés ou de méthodes d’authentification.
Pourquoi c’est important en DFIR
Section intitulée « Pourquoi c’est important en DFIR »Les journaux d’audit d’annuaire constituent la source de preuve formelle permettant de reconstituer les manœuvres post-compromission d’un adversaire :
- Détection des backdoors applicatives : les attaquants injectent fréquemment un secret ou un certificat sur une application d’entreprise légitime existante pour disposer d’un accès API persistant et silencieux qui survit aux réinitialisations de mots de passe.
- Reconstitution de l’élévation de privilèges : identification précise du moment où un compte compromis a été ajouté à un groupe d’administration ou a activé un rôle PIM avec un faux motif de ticket.
- Mise en évidence des attaques par consentement illicite (illicit consent grant) : repérage des cas où un utilisateur ou un administrateur a consenti des privilèges excessifs (
Mail.ReadWrite,Files.ReadWrite.All) à une application multi-tenant malveillante. - Détection de l’évasion de défenses (altération de politiques) : preuve formelle qu’un attaquant a modifié une règle d’accès conditionnel pour exclure son adresse IP ou désactiver l’obligation de MFA.
- Surveillance des méthodes d’authentification frauduleuses : détection de l’ajout d’une clé FIDO2 ou d’une application d’authentification secondaire sur le compte d’une victime pour garantir un accès pérenne.
Dissection du schéma JSON : les champs clés
Section intitulée « Dissection du schéma JSON : les champs clés »Lors de l’interrogation via Microsoft Graph API (/auditLogs/directoryAudits) ou Azure Log Analytics (AuditLogs), les champs suivants forment la structure de preuve indispensable :
| Champ (Graph API) | Champ (Log Analytics) | Signification forensique et interprétation |
|---|---|---|
id | CorrelationId / Id | GUID unique de l’événement. À corréler avec les logs de connexion pour identifier la session administrative à l’origine de l’action. |
activityDateTime | TimeGenerated | Horodatage UTC précis de la validation de la modification dans l’annuaire. |
activityDisplayName | OperationName | Nom explicite de l’opération (ex. “Add member to role”, “Update application - Certificates and secrets management”). |
category | Category | Domaine opérationnel : RoleManagement, ApplicationManagement, UserManagement, Policy. |
loggedByService | LoggedByService | Sous-système à l’origine de l’événement : Core Directory, PIM, Self-service Password Reset. |
initiatedBy | InitiatedBy | Identité de l’acteur. Soit un Utilisateur (userPrincipalName, ipAddress, id), soit une Application (appId, displayName). |
targetResources | TargetResources | Tableau des objets modifiés. Contient id, displayName, type (“User”, “Role”, “Application”) et modifiedProperties. |
modifiedProperties | Tableau JSON interne dans TargetResources | Le joyau de la preuve forensique. Détaille displayName, oldValue et newValue pour chaque propriété modifiée. |
additionalDetails | AdditionalDetails | Métadonnées complémentaires : User-Agent, justificatif de ticket PIM, identifiant de session. |
result | Result | Résultat de l’opération : success ou failure. |
resultReason | ResultReason | Motif du rejet en cas d’échec (ex. privilèges insuffisants, rejet d’approbation PIM). |
Opérations d’audit critiques pour le DFIR
Section intitulée « Opérations d’audit critiques pour le DFIR »L’analyste DFIR doit surveiller en priorité absolue les opérations activityDisplayName suivantes :
| Intitulé de l’opération | Catégorie | Vecteur d’attaque associé / Contexte |
|---|---|---|
Add member to role | RoleManagement | Attribution directe d’un rôle d’annuaire à haut privilège (ex. Global Admin, Privileged Auth Admin). |
Add eligible member to role | RoleManagement | Attribution d’une éligibilité PIM permettant à l’attaquant de s’élever à la demande. |
Add member to group | GroupManagement | Ajout d’un compte à un groupe synchronisé vers l’Active Directory local ou doté de rôles. |
Update application - Certificates and secrets management | ApplicationManagement | PERSISTANCE CRITIQUE : Injection d’un secret client ou d’un certificat sur une application. |
Add service principal credentials | ApplicationManagement | Ajout d’informations d’identification sur un principal de service existant pour automatisation malveillante. |
Consent to application | ConsentManagement | Octroi d’autorisations OAuth (ex. lecture de courriers ou de fichiers) à une application externe. |
Update policy / Delete policy | Policy | Modification ou suppression d’une règle d’accès conditionnel ou d’une méthode d’authentification. |
Admin registered security info | UserManagement | Un administrateur a configuré un nouveau numéro de téléphone ou une clé FIDO2 sur un compte. |
User registered security info | UserManagement | L’utilisateur ciblé a enregistré une nouvelle méthode MFA (persistance post-compromission). |
Hard delete user | UserManagement | Effacement de traces : suppression définitive d’un compte fantôme ou d’un objet compromis. |
Ce qui est possible vs ce qui n’est pas possible
Section intitulée « Ce qui est possible vs ce qui n’est pas possible »Ce qui est possible
Section intitulée « Ce qui est possible »- Reconstituer le différentiel exact des modifications : comparer
oldValueetnewValuedansmodifiedPropertiespour identifier précisément ce qui a changé (ex. quelle IP a été ajoutée à un emplacement nommé). - Identifier l’auteur formel de la modification : établir si l’action émane d’un administrateur humain (avec son IP et son compte) ou d’un principal de service via l’API Graph.
- Auditer la chaîne d’approbation PIM : retrouver les demandes d’élévation, les approbateurs et le motif de ticket saisi.
- Détecter les backdoors applicatives dormantes : mettre au jour les applications d’entreprise créées ou modifiées avec des droits API exorbitants.
Ce qui n’est pas possible
Section intitulée « Ce qui n’est pas possible »- Tracer la lecture de données utiles : les journaux d’audit indiquent qu’une application a obtenu le droit
Mail.ReadWrite; ils n’indiquent pas quels e-mails ont été lus (ceci requiert l’UAL Purview ou les Graph Activity Logs). - Récupérer l’historique sur un tenant expiré : les événements antérieurs à 7 jours sur Entra Free ou 30 jours sur P1/P2 sont définitivement effacés sans archivage Log Analytics.
- Visualiser la valeur en clair d’un secret : lorsqu’un attaquant génère un secret client, le journal consigne son nom et sa date d’expiration, mais jamais la valeur secrète elle-même.
- Détecter la reconnaissance passive : un administrateur ou un pirate énumérant les utilisateurs ou les groupes via l’interface ou PowerShell ne génère aucun log dans Directory Audits (les opérations de lecture d’annuaire ne sont pas enregistrées ici).
Méthodologie d’investigation : extraction et détection KQL
Section intitulée « Méthodologie d’investigation : extraction et détection KQL »# ==============================================================================# Hermes Codex - Extracteur des journaux d'audit d'annuaire Entra ID# Exporte les modifications d'annuaire, de rôles et d'applications# ==============================================================================
Import-Module Microsoft.Graph.Authentication, Microsoft.Graph.Reports -ErrorAction StopConnect-MgGraph -Scopes "AuditLog.Read.All", "Directory.Read.All" -NoWelcome
$DaysBack = 30$StartDate = (Get-Date).AddDays(-$DaysBack).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")$OutDir = "./Entra_DirectoryAudits_$(Get-Date -Format 'yyyyMMdd')"New-Item -ItemType Directory -Path $OutDir -Force | Out-Null
Write-Host "[*] Extraction des audits d'annuaire Entra depuis $StartDate..." -ForegroundColor Cyan
$filter = "activityDateTime ge $StartDate"$auditUri = "https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?`$filter=$filter&`$top=500"
$allAudits = [System.Collections.Generic.List[PSObject]]::new()do { $resp = Invoke-MgGraphRequest -Method GET -Uri $auditUri if ($resp.value) { $allAudits.AddRange($resp.value) } $auditUri = $resp.'@odata.nextLink' Write-Host " [+] $($allAudits.Count) enregistrements collectés..." -ForegroundColor Gray Start-Sleep -Milliseconds 150} while ($null -ne $auditUri)
$outputFile = "$OutDir/DirectoryAudits_30Jours.jsonl"$allAudits | ForEach-Object { $_ | ConvertTo-Json -Compress -Depth 10 } | Set-Content -Path $outputFile
$hash = Get-FileHash -Path $outputFile -Algorithm SHA256Write-Host "[✓] Extraction terminée : $($allAudits.Count) événements. SHA-256 : $($hash.Hash)" -ForegroundColor Green// ==============================================================================// Détection de secrets ou certificats ajoutés à une application d'entreprise// Technique MITRE ATT&CK : T1098.001 - Manipulation de compte cloud// ==============================================================================AuditLogs| where TimeGenerated >= ago(30d)| where OperationName in ( "Update application - Certificates and secrets management", "Add service principal credentials", "Add service principal", "Update application")| where Result =~ "success"| mvexpand TargetResources| extend TargetAppName = tostring(TargetResources.displayName), TargetAppId = tostring(TargetResources.id), TargetType = tostring(TargetResources.type)| mvexpand TargetResources.modifiedProperties| extend PropName = tostring(TargetResources_modifiedProperties.displayName), OldVal = tostring(TargetResources_modifiedProperties.oldValue), NewVal = tostring(TargetResources_modifiedProperties.newValue)| where PropName has_any ("KeyDescription", "CredentialData", "Certificates", "ClientSecret")| project TimeGenerated, OperationName, InitiatedBy = tostring(InitiatedBy.user.userPrincipalName), InitiatedIP = tostring(InitiatedBy.user.ipAddress), TargetAppName, TargetAppId, PropName, NewVal, CorrelationId| order by TimeGenerated desc// ==============================================================================// Détection de l'attribution de rôles d'annuaire hautement privilégiés// ==============================================================================let RolesCritiques = dynamic([ "Global Administrator", "Privileged Role Administrator", "Security Administrator", "Conditional Access Administrator", "User Administrator", "Exchange Administrator", "Application Administrator", "Cloud Application Administrator"]);
AuditLogs| where TimeGenerated >= ago(30d)| where OperationName in ("Add member to role", "Add eligible member to role")| where Result =~ "success"| mvexpand TargetResources| extend TargetRoleName = tostring(TargetResources.displayName)| mvexpand TargetResources.modifiedProperties| extend PropName = tostring(TargetResources_modifiedProperties.displayName), TargetUser = tostring(TargetResources_modifiedProperties.newValue)| where PropName == "Role.DisplayName" and TargetRoleName in (RolesCritiques)| project TimeGenerated, OperationName, RoleAssigned = TargetRoleName, AssignedTo = TargetUser, AssignedBy = tostring(InitiatedBy.user.userPrincipalName), AssignedByIP = tostring(InitiatedBy.user.ipAddress), CorrelationId| order by TimeGenerated desc// ==============================================================================// Détection de l'enregistrement de nouvelles méthodes d'authentification// ==============================================================================AuditLogs| where TimeGenerated >= ago(14d)| where Category == "UserManagement"| where OperationName in ( "User registered security info", "Admin registered security info", "User registered all required security info", "Admin updated security info")| mvexpand TargetResources| extend TargetUser = tostring(TargetResources.userPrincipalName)| mvexpand TargetResources.modifiedProperties| extend PropName = tostring(TargetResources_modifiedProperties.displayName), MethodDetails = tostring(TargetResources_modifiedProperties.newValue)| project TimeGenerated, OperationName, TargetUser, InitiatedBy = tostring(InitiatedBy.user.userPrincipalName), InitiatedIP = tostring(InitiatedBy.user.ipAddress), PropName, MethodDetails, CorrelationId| order by TimeGenerated descExemple d’investigation : la backdoor applicative furtive
Section intitulée « Exemple d’investigation : la backdoor applicative furtive »Contexte de l’incident
Section intitulée « Contexte de l’incident »Un pirate compromet les identifiants d’un technicien du support informatique disposant du rôle Cloud Application Administrator.
Reconstitution chronologique dans les journaux d’audit
Section intitulée « Reconstitution chronologique dans les journaux d’audit »- Accès initial : À 02h14 UTC, le pirate s’authentifie depuis une IP étrangère (tracée dans
m365-09). - Reconnaissance : le pirate énumère les applications d’entreprise existantes via PowerShell (aucun log d’audit généré car il s’agit d’une simple lecture).
- L’action de persistance (02h22:15 UTC) :
OperationName:Update application - Certificates and secrets management.InitiatedBy.user.userPrincipalName:admin_support@entreprise.fr.TargetResources[0].displayName:Reporting-Finances-Automate(une application métier légitime et approuvée).TargetResources[0].modifiedProperties:displayName:KeyDescription.oldValue:[].newValue:[{"KeyIdentifier":"3a8f...","DisplayName":"CertificatMaintenance2026","EndDateTime":"2028-09-16T00:00:00Z"}].
- Exploitation :
- L’application
Reporting-Finances-Automatedisposait déjà de permissions applicatives étendues (Exchange.ManageAsAppetUser.ReadWrite.All). - En ajoutant un secret à une application existante au lieu d’en créer une nouvelle, l’attaquant a évité de déclencher les alertes SOC sur la création de nouvelles applications.
- Il a ensuite basculé l’ensemble de ses requêtes via l’identité du Principal de service, échappant ainsi aux règles d’accès conditionnel ciblant les utilisateurs et survivant à la réinitialisation du mot de passe du technicien.
- L’application
Sans l’examen minutieux de modifiedProperties dans les journaux d’audit Entra, l’équipe de réponse à incident aurait réinitialisé le mot de passe du technicien en pensant l’incident clos, laissant à l’attaquant un accès administratif permanent et indétectable.
Doctrine transversale : télémétrie d’audit vs preuve formelle
Section intitulée « Doctrine transversale : télémétrie d’audit vs preuve formelle »Toute altération constatée dans les journaux d’audit doit être évaluée selon les 7 niveaux de certitude de Hermes Codex :
+-------------------------------------------------------------------------------+| LES 7 NIVEAUX DE CERTITUDE FORENSIQUE || || 1. Possible -> La plateforme supporte l'opération d'administration. || 2. Configuré -> L'audit d'annuaire est actif et diffusé vers Log Analytics.|| 3. Autorisé -> L'identité disposait des privilèges RBAC requis. || 4. Accessible -> L'identité pouvait joindre les interfaces d'administration.|| 5. Utilisé -> La mutation a été soumise et validée par l'annuaire. || 6. Observé -> L'enregistrement figure dans AuditLogs avec ses propriétés.|| 7. Prouvé -> La corrélation prouve l'action malveillante et la fraude. |+-------------------------------------------------------------------------------+Distinctions forensiques dans les journaux d’audit
Section intitulée « Distinctions forensiques dans les journaux d’audit »- Autorisé != utilisé : un compte possédait le rôle
Privileged Role Administrator(autorisé à nommer des administrateurs généraux). Cela ne prouve aucunement qu’il l’a fait tant qu’aucun événementAdd member to rolen’est observé dansAuditLogs. - Utilisé != malveillant : l’ajout d’un secret sur une application (
Add service principal credentials) est une tâche de maintenance courante en entreprise. Pour prouver qu’elle est malveillante, l’analyste doit démontrer :- Que la session à l’origine de l’action était compromise (discordance d’IP, jeton AiTM).
- Qu’aucun ticket de changement DevOps ne correspond à la date et à l’heure de l’événement.
- Que le principal de service a ensuite été utilisé depuis une infrastructure inconnue.
- Observé != prouvé : un log avec
Result = "success"prouve qu’une modification a eu lieu. Pour prouver l’intrusion complète, l’analyste doit relier cette mutation à la chaîne d’attaque globale (phishing initial -> connexion anormale -> création de backdoor -> exfiltration dans l’UAL).
Pièges et confusions fréquentes
Section intitulée « Pièges et confusions fréquentes »| Piège | Cause technique | Conséquence pour l’enquête | Action corrective |
|---|---|---|---|
| Chercher les règles de messagerie dans l’audit entra | Les règles de boîte aux lettres relèvent d’Exchange Online, pas de l’annuaire Entra. | Aucune trace de règle de transfert trouvée dans les logs d’audit d’annuaire. | Rechercher New-InboxRule ou Set-Mailbox dans l’UAL Purview (m365-13). |
| Négliger les modifications initiées par des applications | Ne filtrer que sur InitiatedBy.user en ignorant les actions menées par InitiatedBy.app. | Les actions automatisées de l’attaquant via des scripts Graph restent invisibles. | Analyser systématiquement les deux branches InitiatedBy.user et InitiatedBy.app. |
| S’arrêter à la réinitialisation du mot de passe | Oublier d’auditer l’ajout de secrets applicatifs pendant la fenêtre de compromission. | L’attaquant conserve un accès programmatique total malgré le changement de mot de passe. | Auditer systématiquement l’opération Update application - Certificates and secrets management. |
| Ignorer les objets imbriqués dans ModifiedProperties | modifiedProperties est un tableau d’objets JSON au sein de TargetResources. | Les exports CSV plats tronquent les anciennes et nouvelles valeurs. | Déplier les objets avec mvexpand en KQL ou parser le JSON en PowerShell. |
| Croire que la consultation d’annuaire est journalisée | Les journaux d’audit ne consignent que les modifications (écriture, mise à jour, suppression). | Conclure à tort à l’absence de reconnaissance interne car aucun log d’audit n’apparaît. | Activer les Microsoft graph activity logs vers Log Analytics pour tracer les requêtes en lecture. |
État de la fonctionnalité en 2026
Section intitulée « État de la fonctionnalité en 2026 »Changements récents
Section intitulée « Changements récents »- Télémétrie PIM 2.0 enrichie : les activations de rôles intègrent nativement les approbations multi-personnes, les identifiants de tickets et les méthodes d’élévation step-up.
- Régulation sur la durée de vie des secrets : entra ID applique des limites strictes sur la durée de validité des secrets applicatifs et émet des alertes d’audit proactives.
- Audits de synchronisation inter-tenants : prise en compte exhaustive des modifications de confiance B2B Direct Connect et des stratégies d’accès inter-organisations.
Fonctionnalités dépréciées
Section intitulée « Fonctionnalités dépréciées »- API azure AD graph (
graph.windows.net) : définitivement retirée. Toute collecte programmatique d’audits d’annuaire doit cibler Microsoft Graph (graph.microsoft.com/v1.0/auditLogs/directoryAudits). - Module PowerShell MSOnline (
Get-MsolAuditLog) : totalement obsolète. Remplacé parMicrosoft.Graph.Reports.
Limitations actuelles
Section intitulée « Limitations actuelles »- Absence de journalisation native des lectures : les requêtes d’énumération en lecture (
GET /users,GET /groups) ne sont pas capturées dans les logs d’audit. La détection de reconnaissance interne requiert la configuration des Microsoft Graph Activity Logs. - Masquage de la valeur en clair du secret : par mesure de sécurité, Microsoft ne consigne jamais le texte en clair du secret généré ; l’analyste n’a accès qu’à l’identifiant de clé, au nom et à l’expiration.
Points clés à retenir
Section intitulée « Points clés à retenir »- Les journaux d’audit d’annuaire tracent la persistance et l’escalade : lors de la compromission d’un compte administrateur, auditer immédiatement
ApplicationManagementetRoleManagement. - Le champ
modifiedPropertiesest la preuve reine : toujours comparer l’ancienne et la nouvelle valeur pour qualifier la modification. - Se méfier des backdoors applicatives : les pirates contournent les réinitialisations de mot de passe en injectant des secrets sur des applications d’entreprise existantes.
- Surveiller l’enregistrement des méthodes MFA : détecter l’enrôlement d’une clé FIDO2 ou d’un téléphone tiers sur le compte de la victime.
- La lecture passive ne laisse pas de trace d’audit ici : l’absence de log n’exclut pas une reconnaissance ; exploiter les Graph Activity Logs pour investiguer les lectures.