Enquête sur le journal d'audit unifié : les champs clés BEC
Lire le journal d'audit unifié dans un BEC : le JSON AuditData, les opérations à filtrer, et comment SessionId et UniqueTokenId relient actions et connexions.
En bref. Dans un export de l'UAL, les colonnes CSV ne sont qu'un index ; la preuve est dans le JSON AuditData. Pour un BEC, filtrez sur une courte liste d'opérations (New-InboxRule, Set-InboxRule, UpdateInboxRules, Set-Mailbox, MailItemsAccessed, Send, SoftDelete/HardDelete, SearchQueryInitiatedExchange, FileDownloaded, Consent to application., User registered security info), puis lisez les champs propres à chaque charge de travail. Le pivot qui transforme le soupçon en attribution, ce sont AppAccessContext.AADSessionId et UniqueTokenId, qui correspondent au Session ID et au Unique token identifier de la connexion Entra.
Le journal d'audit unifié enregistre l'activité des utilisateurs et des administrateurs d'Exchange Online, SharePoint, OneDrive, Entra ID, Teams et d'autres services, au même endroit. Cette étendue fait aussi sa difficulté : un seul export du tenant peut compter des centaines de milliers de lignes, dont quelques dizaines seulement concernent le BEC. Voici le guide de terrain que j'aurais aimé avoir la première fois.
Anatomie d'une ligne d'export
Un export du portail Purview a pour colonnes RecordId, CreationDate, RecordType, Operation, UserId, AuditData, AssociatedAdminUnits, AssociatedAdminUnitsNames. Un export PowerShell Search-UnifiedAuditLog | Export-Csv a des colonnes voisines (RecordType, CreationDate, UserIds, Operations, AuditData, ResultIndex, ResultCount, Identity…). Dans les deux cas, AuditData est une chaîne JSON contenant l'enregistrement complet.
Champs AuditData courants :
| Champ | Signification | Remarques |
|---|---|---|
CreationTime | Heure de l'événement, UTC | Souvent sans Z final |
Id | Identifiant de l'enregistrement | Sert à dédoublonner des exports qui se recouvrent |
Operation | Ce qui s'est passé | La casse et le point final varient (Consent to application.) |
Workload | Exchange, SharePoint, OneDrive, AzureActiveDirectory… | |
UserId | Qui l'a fait | UPN, ou identité système |
ClientIP / ClientIPAddress / ActorIpAddress | IP source | Peut inclure un port ou des crochets ([2001:db8::1]:443) |
ResultStatus | Succeeded, True, Success… | Incohérent d'une charge de travail à l'autre |
AppAccessContext | AADSessionId, UniqueTokenId, IssuedAtTime | Le lien avec la connexion |
L'UAL ne contient aucune géolocalisation. Pays et réseau s'obtiennent en rapprochant l'IP des journaux de connexion Entra, ou par une recherche externe.
Les opérations qui comptent dans un BEC
| Opération | Charge de travail | Pourquoi c'est important | Champs à lire |
|---|---|---|---|
New-InboxRule, Set-InboxRule, Enable-InboxRule | Exchange | Règles créées via PowerShell ou Outlook sur le web | Parameters : Name, ForwardTo, RedirectTo, DeleteMessage, MoveToFolder, SubjectOrBodyContainsWords, From |
UpdateInboxRules | Exchange | Règles créées depuis le client Outlook de bureau | OperationProperties : RuleName, RuleActions, RuleCondition |
Set-Mailbox | Exchange | Transfert de boîte (SMTP), changements d'audit | ForwardingSmtpAddress, ForwardingAddress, DeliverToMailboxAndForward, AuditEnabled |
Add-MailboxPermission, Add-RecipientPermission | Exchange | Délégation pour persister | User, AccessRights |
MailItemsAccessed | Exchange | Quels messages ont été lus ou synchronisés | OperationProperties.MailAccessType (Bind/Sync), Folders, OperationCount, ClientInfoString |
Send, SendAs, SendOnBehalf | Exchange | Courrier envoyé depuis la boîte | Item.Subject, Item.InternetMessageId |
SoftDelete, HardDelete, MoveToDeletedItems | Exchange | Effacement des traces | AffectedItems, Folder |
SearchQueryInitiatedExchange | Exchange | Ce que l'attaquant a cherché | QueryText (journalisation à activer) |
FileDownloaded, FileSyncDownloadedFull | SharePoint / OneDrive | Vol de données | SourceFileName, SiteUrl, UserAgent |
UserLoggedIn, UserLoginFailed | AzureActiveDirectory | Connexions répliquées dans l'UAL | ExtendedProperties, DeviceProperties.SessionId |
Consent to application., Add delegated permission grant. | AzureActiveDirectory | Consentement illicite | ModifiedProperties (ConsentAction.Permissions, ConsentContext.IsAdminConsent) |
User registered security info, Update user. | AzureActiveDirectory | Méthode MFA de l'attaquant | ModifiedProperties (StrongAuthentication…) |
Set-AdminAuditLogConfig, Set-MailboxAuditBypassAssociation | Exchange | Altération de l'audit | UnifiedAuditLogIngestionEnabled, AuditBypassEnabled |
La page Microsoft des activités du journal d'audit est la référence complète. Deux pièges : les noms d'opérations issus d'Entra ID se terminent souvent par un point, et Parameters est un tableau de paires {Name, Value}, pas un objet, si bien qu'un chemin JSON naïf passe à côté.
Pourquoi les règles apparaissent sous deux formes
Une règle de boîte de réception créée dans Outlook sur le web ou en PowerShell est journalisée comme New-InboxRule, avec des Parameters lisibles. Une règle créée dans le client Outlook de bureau est journalisée comme UpdateInboxRules, avec des OperationProperties comme RuleActions et RuleCondition, moins structurées. Cherchez les deux. L'article règles de boîte de réception malveillantes et transferts détaille les paramètres à lire.
Le pivot par session
Microsoft insère un identifiant de session (sid) et un identifiant unique de jeton (uti) dans les jetons qu'il émet, et les expose dans les journaux sous le nom d'identifiants liables. D'après Microsoft Learn :
| Revendication | Journal de connexion Entra | Audit Exchange Online | Audit SharePoint / Teams |
|---|---|---|---|
sid | Session ID | SessionId / AppAccessContext.AADSessionId | AppAccessContext.AADSessionId |
uti | Unique token identifier | AppAccessContext.UniqueTokenId | AppAccessContext.UniqueTokenId |
iat | Date | AppAccessContext.IssuedAtTime | AppAccessContext.IssuedAtTime |
La méthode :
- Dans les journaux de connexion Entra, repérez la connexion suspecte et copiez son Session ID (pour un rejeu, la session vue depuis deux réseaux).
- Dans l'export de l'UAL, gardez tous les enregistrements dont
AADSessionIdouSessionIdest égal à cette valeur. - Ajoutez les enregistrements dont le
UniqueTokenIdcorrespond à un jeton émis vers l'IP de l'attaquant. - Ajoutez les enregistrements provenant de l'IP de l'attaquant pour tout ce que les deux premiers filtres ont manqué.
Microsoft précise que les identifiants liables manquent sur certaines entrées agrégées et sur les enregistrements issus de processus d'arrière-plan : l'étape 4 n'est donc pas facultative. Autre subtilité : avec l'hameçonnage AiTM, la session volée est celle que la victime a ouverte, donc l'identifiant seul ne sépare pas l'attaquant de la victime. Ce qui les sépare, c'est le réseau d'où vient chaque action (AiTM et rejeu de jeton).
Pièges courants
- Exports tronqués. Exactement 50 000 lignes signifie le plafond de l'export Standard, pas la fin des données.
- Doublons. Des recherches qui se recouvrent dupliquent des enregistrements ; dédoublonnez sur
Id. - Dégâts du tableur. Excel reformate les dates et peut couper ou tronquer les longues cellules JSON. Analysez le CSV par programme.
- Fuseaux horaires.
CreationDateetCreationTimesont en UTC ; Outlook affiche l'heure locale. Indiquez l'UTC dans le rapport. - Enregistrements en retard. Ils apparaissent généralement 60 à 90 minutes après l'événement ; un export réalisé juste après le confinement peut manquer les dernières actions.
- Événements absents.
SearchQueryInitiated*est désactivé par défaut ;MailItemsAccesseddépend de la licence et de la configuration de l'audit des boîtes (rétention et lacunes).
Passer à l'échelle
Pour quelques milliers de lignes, PowerShell et ConvertFrom-Json suffisent. Pour un export de tout le tenant, analyser AuditData sur chaque ligne, faire la jointure avec les connexions par IP et par session et regrouper par compte, c'est exactement ce qu'automatise M365 Forensics : l'outil lit les deux couches du CSV, normalise les noms d'opérations (Add service principal. = Add service principal), retire les ports des IP, extrait AADSessionId/UniqueTokenId, emprunte pays et ASN aux connexions de la même IP, et lève un constat critique « Actions effectuées depuis la session ou l'IP de l'attaquant » quand des actions de l'UAL portent les identifiants d'une connexion suspecte. Le pas-à-pas montre comment lire le résultat.
Questions fréquentes
Où se trouve le détail d'un enregistrement du journal d'audit unifié ?
Dans la colonne AuditData de l'export. C'est un objet JSON dont les champs dépendent de la charge de travail : Parameters pour les cmdlets d'administration Exchange, OperationProperties et Folders pour MailItemsAccessed, ModifiedProperties pour les événements Entra ID, SourceFileName et SiteUrl pour SharePoint.
Peut-on relier un enregistrement du journal d'audit unifié à une connexion Entra ID ?
Souvent, oui. Les enregistrements Exchange, SharePoint et Teams portent AppAccessContext.AADSessionId et UniqueTokenId, qui correspondent au Session ID et au Unique token identifier de la connexion Entra ayant émis le jeton. Certains enregistrements agrégés ou d'arrière-plan ne les contiennent pas.
Pour aller plus loin
- Microsoft Learn : Rechercher dans le journal d'audit, Identifiants liables
- Guide d'enquête BEC Microsoft 365
- Glossaire : MailItemsAccessed, règle de boîte de réception