Aller au contenu

Forensique du message trace Exchange online

Dans les enquêtes sur la compromission de messagerie d’entreprise (BEC) et le phishing ciblé, comprendre la trajectoire précise d’un courriel à travers les passerelles de messagerie est primordial. Le Message Trace d’Exchange Online constitue le moteur de télémétrie de transport de référence dans Microsoft 365. Il consigne chaque message ingéré via SMTP, analysé par Exchange Online Protection (EOP), évalué par les règles de flux (Transport Rules), remis dans les boîtes aux lettres ou relayé vers des serveurs externes.

Cependant, les analystes DFIR commettent régulièrement des erreurs d’interprétation sur ce que le Message Trace prouve réellement. Le Message Trace est un journal de transport : il enregistre les métadonnées de routage et d’enveloppe, et non le contenu des boîtes aux lettres. De surcroît, il obéit à une architecture temporelle bimodale stricte (0-10 jours en temps réel vs 10-90 jours en recherche historique) qui conditionne la vitesse et le format de restitution des preuves.


1. Architecture du pipeline de transport & télémétrie EOP

Section intitulée « 1. Architecture du pipeline de transport & télémétrie EOP »

Lorsqu’un courriel transite par Microsoft 365, il traverse le Pipeline de Transport Exchange Online, générant des événements à chaque changement d’état :

graph TD
subgraph "Ingress Externe"
EXT_MTA[MTA Émetteur Externe]
end
subgraph "Front-End EOP (Exchange Online Protection)"
FE_RECV[Réception Front-End & Handshake TLS<br/>OriginalClientIpAddress Consignée]
FE_AUTH[Évaluation SPF / DKIM / DMARC<br/>Génération Authentication-Results]
FE_FILTER[Filtrage Anti-Spam & Anti-Phishing<br/>Attribution Verdicts SCL, BCL]
end
subgraph "Catégorisation & Routage"
ROUT_EVAL[Règles de Transport & Connecteurs<br/>Mentions légales, Chiffrement, Redirections]
ROUT_EXP[Expansion des Listes de Distribution]
end
subgraph "Distribution Boîte / Relais Sortant"
DELIV_STORE[Distribution Store Driver<br/>Statut : Deliver -> Boîte Utilisateur]
DELIV_EXT[Connecteur d'Envoi Sortant<br/>Statut : Send -> MX Externe]
DELIV_QUAR[Mise en Quarantaine EOP<br/>Statut : Quarantine]
end
EXT_MTA -->|TCP 25| FE_RECV
FE_RECV --> FE_AUTH
FE_AUTH --> FE_FILTER
FE_FILTER --> ROUT_EVAL
ROUT_EVAL --> ROUT_EXP
ROUT_EXP --> DELIV_STORE
ROUT_EXP --> DELIV_EXT
FE_FILTER -->|Verdict Malveillant| DELIV_QUAR

2. Recherche temps réel vs recherche historique (0-10j vs 10-90j)

Section intitulée « 2. Recherche temps réel vs recherche historique (0-10j vs 10-90j) »

Microsoft 365 divise le Message Trace en deux régimes d’interrogation distincts selon l’ancienneté des messages :

ParamètreRecherche Temps Réel (0 à 10 jours)Recherche Historique (10 à 90 jours)
Fenêtre de disponibilitéÉvénements intervenus au cours des 10 derniers jours.Événements survenus entre 10 et 90 jours en arrière.
Mode d’exécutionSynchrone, interactif, réponse en quelques secondes.Asynchrone par lots, exécuté sur les serveurs d’arrière-plan Microsoft.
Mécanisme d’extractionGet-MessageTrace & Get-MessageTraceDetailStart-HistoricalSearch -> Téléchargement CSV via URL SAS Azure Blob.
Plafond d’enregistrements5 000 éléments par requête (avec pagination PowerShell).Jusqu’à 100 000 enregistrements par fichier CSV généré.
Niveau de détailPropriétés de synthèse + détails étape par étape sur demande.Données brutes de transport complètes, évaluation étendue des règles.
Délai d’obtentionImmédiat (1 à 5 secondes).15 minutes à plusieurs heures selon la taille et l’activité du tenant.

3. Le pivot forensique fondamental : NetworkMessageId vs MessageId

Section intitulée « 3. Le pivot forensique fondamental : NetworkMessageId vs MessageId »

En investigation de messagerie, distinguer ces deux identifiants est crucial :

  1. MessageId (RFC 5322) :
    • Généré par le client de messagerie ou le serveur émetteur (ex : <12345.abc@mail.expediteur.com>).
    • Vulnérable à la falsification : un attaquant peut forger, dupliquer ou omettre cet en-tête. Plusieurs courriels distincts peuvent partager le même Message-ID.
  2. NetworkMessageId :
    • GUID unique généré par l’infrastructure de transport de Microsoft 365 dès la réception SMTP du paquet.
    • Immuable : conservé à travers toutes les étapes de routage, expansions de listes et analyses de sécurité au sein du tenant.
    • Pivot central d’investigation : permet de relier le Message Trace aux événements de l’UAL (MailItemsAccessed), aux alertes Defender for Office 365 (EmailEvents) et aux recherches eDiscovery.

Chaque transition d’état au cours du routage génère un événement spécifique dans Get-MessageTraceDetail :

Statut d’événementAction techniqueInterprétation forensique
ReceiveMessage accepté par les frontaux EOP via SMTP.Consigne la véritable adresse IP d’origine (OriginalClientIpAddress).
SubmitMessage soumis par le service de soumission de boîte aux lettres.Indique une émission interne (utilisateur ou script authentifié).
DeliverRemise réussie dans le magasin de la boîte aux lettres du destinataire.Prouve la livraison du message (ne prouve pas sa lecture).
SendMessage transmis hors du tenant via un connecteur SMTP sortant.Capital en investigation BEC pour prouver l’envoi de fausses factures vers l’extérieur.
FailÉchec de remise permanent (génération d’un rapport de non-remise NDR 5xx).Révèle des tentatives de reconnaissance sur des adresses invalides.
DropMessage supprimé silencieusement sans génération de NDR.Déclenché par des règles DLP ou des filtres anti-malware sévères.
DeferReport temporaire de remise (code 4xx du serveur distant).Traduit un ralentissement réseau ou un mécanisme de greylisting.
RedirectMessage redirigé vers une adresse de destination alternative.Indicateur de persistance clé : provoqué par des règles de flux ou de boîte.
ExpandDécomposition d’une liste de distribution vers ses membres individuels.Permet d’évaluer le rayon d’impact d’un mail envoyé à une liste générique.
QuarantineIsolement du message dans la quarantaine EOP.Le message a été neutralisé avant d’atteindre la boîte de l’utilisateur.

5. Procédures d’extraction PowerShell opérationnelles

Section intitulée « 5. Procédures d’extraction PowerShell opérationnelles »
Fenêtre de terminal
Connect-ExchangeOnline -UserPrincipalName analyste-dfir@defense-corp.org
# Définition des bornes UTC sur les 3 derniers jours
$startDate = (Get-Date).AddDays(-3).ToUniversalTime()
$endDate = (Get-Date).ToUniversalTime()
# 1. Recherche de tous les messages provenant d'un domaine hostile
$traces = Get-MessageTrace `
-SenderAddress "*@adversary-phish.com" `
-StartDate $startDate `
-EndDate $endDate `
-ResultSize 5000
# 2. Extraction du cheminement détaillé étape par étape
$rapportForensique = foreach ($msg in $traces) {
$details = Get-MessageTraceDetail `
-MessageTraceId $msg.MessageTraceId `
-RecipientAddress $msg.RecipientAddress
[PSCustomObject]@{
DateReception = $msg.Received
NetworkMessageId = $msg.NetworkMessageId
Expediteur = $msg.SenderAddress
Destinataire = $msg.RecipientAddress
Objet = $msg.Subject
Statut = $msg.Status
IP_Source = $msg.FromIP
TailleKo = [Math]::Round($msg.Size / 1024, 2)
Cheminement = ($details | ForEach-Object { "$($_.Event): $($_.Detail)" }) -join " -> "
}
}
$rapportForensique | Format-Table -AutoSize

Reconstitution du rayon d’impact d’une campagne de phishing

Section intitulée « Reconstitution du rayon d’impact d’une campagne de phishing »

Lorsqu’un utilisateur signale un mail de phishing, l’analyste doit identifier immédiatement l’ensemble des collaborateurs ciblés par la même vague :

Fenêtre de terminal
# Pivotement sur le NetworkMessageId extrait des en-têtes du mail signalé
$reportedNetMsgId = "8a32f10b-412e-4b92-8012-bc91a45920a1"
$allImpacted = Get-MessageTrace `
-NetworkMessageId $reportedNetMsgId `
-StartDate (Get-Date).AddDays(-10) `
-EndDate (Get-Date)
# Ventilation par statut de livraison (délivrés vs mis en quarantaine)
$allImpacted | Group-Object Status | Select-Object Name, Count

En scénario BEC, les attaquants utilisent la boîte compromise pour diffuser de faux ordres de virement à des partenaires ou des clients externes :

// Détection des pics d'envois externes inhabituels via Defender XDR (EmailEvents)
EmailEvents
| where Timestamp > ago(30d)
| where SenderFromAddress == "cfo@defense-corp.org"
| where DeliveryLocation == "External" or InternetMessageId has "outbound"
| summarize
NombreDestinataires = dcount(RecipientEmailAddress),
ExemplesDestinataires = make_set(RecipientEmailAddress, 10),
TotalEmails = count()
by bin(Timestamp, 1d)
| order by Timestamp desc

7. Pièges d’investigation & limites du message trace

Section intitulée « 7. Pièges d’investigation & limites du message trace »