Audit Avancé
Microsoft 365

Par Ayi NEDJIMI Publié le 24 septembre 2025 5 min de lecture

Maîtrisez la corrélation des journaux Azure AD, logs Exchange et alertes Defender pour une analyse forensique approfondie

📖 Guide Complet

1 Introduction à l'Audit Avancé Microsoft 365

L'audit avancé de Microsoft 365 va bien au-delà de la simple consultation des journaux d'événements. Il s'agit d'une discipline forensique qui nécessite une compréhension approfondie de l'architecture des logs, des techniques de corrélation avancées, et de l'utilisation d'outils spécialisés pour détecter les menaces sophistiquées et analyser les incidents de sécurité.

🎯 Objectifs de l'Audit Avancé

  • Détection proactive des menaces avancées et des comportements anormaux
  • Investigation forensique complète des incidents de sécurité
  • Conformité réglementaire et reporting aux autorités
  • Optimisation des contrôles de sécurité existants
  • Intelligence des menaces et amélioration continue

Défis de l'Audit M365

Microsoft 365 génère des téraoctets de données d'audit quotidiennement à travers ses multiples services. La complexité réside dans la corrélation de ces données dispersées pour reconstituer une chronologie précise des événements et identifier les patterns d'attaque sophistiqués.

Volume Massif

Millions d'événements par jour nécessitent des techniques de filtrage et d'agrégation sophistiquées

🔗

Corrélation Complexe

Les événements sont dispersés à travers différents services avec des formats hétérogènes

⏱️

Temps Réel

Nécessité de détecter et réagir rapidement aux menaces en cours

🔍 Méthodologie d'Audit Avancé

1. Collecte Exhaustive

Activation de tous les logs d'audit disponibles, configuration de la rétention optimale

2. Normalisation

Standardisation des formats de données pour faciliter la corrélation

3. Enrichissement

Ajout de contexte géographique, threat intelligence et informations d'asset

4. Corrélation

Application d'algorithmes avancés pour identifier les patterns et anomalies

5. Investigation

Analyse forensique approfondie et reconstruction de la timeline d'attaque

2 Architecture des Logs Microsoft 365

🏗️ Vue d'Ensemble de l'Architecture

L'architecture de logging de Microsoft 365 est construite sur plusieurs couches interconnectées, chacune capturant différents aspects de l'activité utilisateur et système. Comprendre cette architecture est essentiel pour un audit efficace.

Couches de Logging

Couche Application

Exchange Online, SharePoint, Teams, OneDrive - Logs d'activité utilisateur spécifiques à chaque service

Couche Identité

Azure AD Sign-in et Audit Logs - Authentification, autorisation, modifications d'annuaire

Couche Sécurité

Microsoft Defender - Alertes de sécurité, détections de menaces, incidents

Couche Infrastructure

Azure Activity Logs - Modifications de configuration, déploiements, accès API

Flux de Données

Événements générés par les services M365
Agrégation dans Unified Audit Log
Enrichissement et normalisation
Export vers SIEM/Storage externe
Analyse et corrélation avancée

# Architecture PowerShell pour la collecte multi-sources

function Initialize-M365AuditArchitecture {
    [CmdletBinding()]
    param(
        [switch]$EnableAllLogs,
        [int]$RetentionDays = 365
    )

    # Configuration des connexions multiples
    $connections = @{
        "ExchangeOnline" = @{ Module = "ExchangeOnlineManagement"; Scope = "https://outlook.office365.com" }
        "MicrosoftGraph" = @{ Module = "Microsoft.Graph"; Scopes = @("AuditLog.Read.All", "Directory.Read.All") }
        "SecurityCompliance" = @{ Module = "ExchangeOnlineManagement"; Scope = "https://ps.compliance.protection.outlook.com" }
        "AzureAD" = @{ Module = "AzureAD"; Scope = "https://graph.microsoft.com" }
    }

    # Activation des logs d'audit pour chaque service
    if ($EnableAllLogs) {
        Write-Host "🔧 Configuration des logs d'audit..." -ForegroundColor Cyan

        # Exchange Online Audit Logging
        Set-OrganizationConfig -AuditDisabled:$false
        Set-AdminAuditLogConfig -AdminAuditLogEnabled:$true -AdminAuditLogCmdlets "*" -AdminAuditLogParameters "*"

        # SharePoint Online Audit
        Set-SPOTenant -EnableAIPIntegration:$true

        # Microsoft Teams Audit
        Set-CsTeamsAuditConfiguration -AuditInformationRecordingEnabled:$true

        # Azure AD Premium P1/P2 features
        Update-MgDirectoryAuditLogRetention -Days $RetentionDays
    }

    # Vérification de la configuration
    $auditStatus = @{
        ExchangeAudit = (Get-OrganizationConfig).AuditDisabled -eq $false
        AdminAudit = (Get-AdminAuditLogConfig).AdminAuditLogEnabled
        UnifiedAuditLog = (Get-AdminAuditLogConfig).UnifiedAuditLogIngestionEnabled
        AzureADLogs = $true  # Toujours activé avec P1+
    }

    return $auditStatus
}

📊 Capacités et Limitations par Source

Unified Audit Log

Avantages
  • • Vue centralisée de tous les services M365
  • • Corrélation automatique des événements
  • • API standardisée pour l'extraction
  • • Recherche unifiée avec filtres avancés
Limitations
  • • Rétention limitée (90 jours par défaut)
  • • Latence dans l'indexation (jusqu'à 24h)
  • • Throttling des requêtes API
  • • Certains événements non capturés

Azure AD Logs

Avantages
  • • Granularité élevée des événements d'identité
  • • Informations contextuelles riches
  • • Intégration native avec Conditional Access
  • • Détection de risque intégrée
Limitations
  • • Logs Sign-in : 30 jours (Premium P1/P2)
  • • Logs Audit : 30 jours (Premium P1/P2)
  • • Volume important à traiter
  • • Corrélation manuelle requise

💡 Recommandation Architecture

Pour un audit avancé, implémentez une architecture hybride combinant l'Unified Audit Log pour la vue globale, les logs Azure AD pour l'analyse d'identité, et un SIEM externe pour la rétention long terme et la corrélation avancée.

3 Sources de Données et Types de Logs

📧 Exchange Online - Messagerie et Calendrier

Types d'Événements Critiques

Accès aux Boîtes Emails
  • MailboxLogin - Connexions à la messagerie
  • MailItemsAccessed - Accès aux éléments de messagerie
  • Send - Envoi d'emails
  • SearchQueryInitiatedExchange - Recherches dans la messagerie
Configuration et Administration
  • Set-Mailbox - Modifications de boîtes emails
  • New-InboxRule - Création de règles de boîte
  • Set-TransportRule - Règles de transport
  • Add-MailboxPermission - Permissions de messagerie

Script d'Analyse Exchange

# Analyse avancée des logs Exchange Online
function Analyze-ExchangeAuditLogs {
    param(
        [int]$DaysBack = 7,
        [string[]]$SuspiciousOperations = @("MailItemsAccessed", "Send", "SearchQueryInitiatedExchange")
    )

    $startDate = (Get-Date).AddDays(-$DaysBack)
    $endDate = Get-Date

    $suspiciousActivities = @()

    foreach ($operation in $SuspiciousOperations) {
        $logs = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate `
            -RecordType ExchangeItem -Operations $operation -ResultSize 5000

        foreach ($log in $logs) {
            $auditData = $log.AuditData | ConvertFrom-Json

            # Détection d'anomalies
            $anomalyScore = 0

            # Volume anormal d'accès
            if ($operation -eq "MailItemsAccessed" -and $auditData.OperationCount -gt 100) {
                $anomalyScore += 3
            }

            # Accès en dehors des heures de bureau
            $eventTime = [DateTime]$auditData.CreationTime
            if ($eventTime.Hour -lt 7 -or $eventTime.Hour -gt 19) {
                $anomalyScore += 2
            }

            # Adresse IP inhabituelle
            if ($auditData.ClientIPAddress -notmatch "^(10\.|172\.|192\.168\.)") {
                $anomalyScore += 2
            }

            if ($anomalyScore -ge 4) {
                $suspiciousActivities += [PSCustomObject]@{
                    Timestamp = $eventTime
                    User = $auditData.UserId
                    Operation = $operation
                    ClientIP = $auditData.ClientIPAddress
                    AnomalyScore = $anomalyScore
                    Details = $auditData
                }
            }
        }
    }

    return $suspiciousActivities | Sort-Object AnomalyScore -Descending
}

📁 SharePoint Online et OneDrive

Événements de Partage et Accès

  • FileAccessed - Accès aux fichiers
  • FileDownloaded - Téléchargements
  • SharingSet - Configuration de partage
  • AnonymousLinkUsed - Utilisation liens anonymes
  • FileUploaded - Uploads de fichiers
  • FolderCreated - Création de dossiers
  • FileDeleted - Suppressions
  • FileModified - Modifications

Indicateurs de Compromission

🚨 Exfiltration Massive

Téléchargements volumineux en peu de temps depuis des IPs externes

⚠️ Partage Suspect

Création de liens anonymes vers des données sensibles

📤 Upload Anormal

Uploads de fichiers exécutables ou archives volumineuses

# Détection d'exfiltration de données SharePoint

function Detect-SharePointDataExfiltration {
    param(
        [int]$TimeWindowHours = 1,
        [int]$DownloadThresholdMB = 100,
        [int]$FileCountThreshold = 50
    )

    $startDate = (Get-Date).AddHours(-$TimeWindowHours)

    # Récupération des événements de téléchargement
    $downloads = Search-UnifiedAuditLog -StartDate $startDate -EndDate (Get-Date) `
        -RecordType SharePointFileOperation -Operations "FileDownloaded" -ResultSize 5000

    # Groupement par utilisateur et analyse
    $userActivity = $downloads | ForEach-Object {
        $auditData = $_.AuditData | ConvertFrom-Json
        [PSCustomObject]@{
            User = $auditData.UserId
            Timestamp = [DateTime]$auditData.CreationTime
            FileName = $auditData.SourceFileName
            FileSize = if($auditData.SourceFileSize) { [int]$auditData.SourceFileSize } else { 0 }
            ClientIP = $auditData.ClientIP
            UserAgent = $auditData.UserAgent
        }
    } | Group-Object User

    $suspiciousUsers = @()

    foreach ($userGroup in $userActivity) {
        $downloads = $userGroup.Group
        $totalSize = ($downloads | Measure-Object -Property FileSize -Sum).Sum
        $totalFiles = $downloads.Count
        $timeSpan = (($downloads | Measure-Object -Property Timestamp -Maximum).Maximum -
                    ($downloads | Measure-Object -Property Timestamp -Minimum).Minimum).TotalMinutes

        if (($totalSize / 1MB) -gt $DownloadThresholdMB -or $totalFiles -gt $FileCountThreshold) {
            $suspiciousUsers += [PSCustomObject]@{
                User = $userGroup.Name
                TotalSizeMB = [math]::Round($totalSize / 1MB, 2)
                FileCount = $totalFiles
                TimeSpanMinutes = [math]::Round($timeSpan, 2)
                DownloadRateMBPerMin = if($timeSpan -gt 0) { [math]::Round(($totalSize / 1MB) / $timeSpan, 2) } else { 0 }
                UniqueIPs = ($downloads.ClientIP | Select-Object -Unique).Count
                Files = ($downloads.FileName | Select-Object -First 10) -join "; "
            }
        }
    }

    return $suspiciousUsers | Sort-Object TotalSizeMB -Descending
}

💬 Microsoft Teams - Collaboration

Messages et Canaux

  • MessageSent
  • MessageDeleted
  • ChannelAdded
  • MemberAdded
  • GuestUserAdded

Réunions et Appels

  • CallStarted
  • MeetingJoined
  • MeetingLeft
  • RecordingStarted
  • ScreenShareStarted

Applications

  • AppInstalled
  • BotAddedToTeam
  • ConnectorAdded
  • TabAdded
  • PolicyChanged

4 Techniques de Corrélation Avancées

🔗 Corrélation Multi-Sources

La corrélation avancée consiste à associer des événements provenant de différentes sources pour reconstituer une chronologie cohérente et détecter des patterns d'attaque sophistiqués qui seraient invisibles dans une source unique.

Clés de Corrélation

Identifiants Utilisateur
  • • UserPrincipalName (UPN)
  • • ObjectId / UserId Azure AD
  • • SID (Security Identifier)
  • • Email Address (SMTP)
Contexte Technique
  • • Adresse IP source
  • • Session ID / Correlation ID
  • • User Agent / Device Info
  • • Géolocalisation

Fenêtres Temporelles

Corrélation Immédiate

±5 minutes - Événements de la même session utilisateur

Corrélation Contextuelle

±30 minutes - Activités liées (login → action)

Corrélation Comportementale

±24 heures - Patterns d'activité anormaux

# Framework de corrélation multi-sources

class M365LogCorrelator {
    [hashtable]$EventSources
    [hashtable]$CorrelationRules
    [int]$TimeWindowMinutes

    M365LogCorrelator([int]$timeWindow = 30) {
        $this.TimeWindowMinutes = $timeWindow
        $this.EventSources = @{}
        $this.InitializeCorrelationRules()
    }

    [void] InitializeCorrelationRules() {
        $this.CorrelationRules = @{
            "SuspiciousLogin" = @{
                PrimaryEvent = @{
                    Source = "AzureAD"
                    EventType = "SignIn"
                    Conditions = @("RiskLevel -ne 'none'", "Status.ErrorCode -eq 0")
                }
                CorrelatedEvents = @(
                    @{
                        Source = "Exchange"
                        EventType = "MailboxLogin"
                        TimeWindow = 10
                        Conditions = @("same IP", "same user")
                    },
                    @{
                        Source = "SharePoint"
                        EventType = "FileDownloaded"
                        TimeWindow = 60
                        Conditions = @("same user", "volume > 100MB")
                    }
                )
            }
            "DataExfiltration" = @{
                PrimaryEvent = @{
                    Source = "SharePoint"
                    EventType = "FileDownloaded"
                    Conditions = @("FileSize -gt 10MB")
                }
                CorrelatedEvents = @(
                    @{
                        Source = "Exchange"
                        EventType = "Send"
                        TimeWindow = 30
                        Conditions = @("same user", "external recipient")
                    }
                )
            }
        }
    }

    [PSObject[]] CorrelateEvents([hashtable]$events, [string]$ruleName) {
        $rule = $this.CorrelationRules[$ruleName]
        $correlatedIncidents = @()

        # Récupérer les événements primaires
        $primaryEvents = $events[$rule.PrimaryEvent.Source] | Where-Object {
            $this.EvaluateConditions($_, $rule.PrimaryEvent.Conditions)
        }

        foreach ($primaryEvent in $primaryEvents) {
            $incident = [PSCustomObject]@{
                PrimaryEvent = $primaryEvent
                CorrelatedEvents = @()
                RiskScore = 1
                Timeline = @($primaryEvent)
            }

            # Rechercher les événements corrélés
            foreach ($correlationRule in $rule.CorrelatedEvents) {
                $timeStart = $primaryEvent.Timestamp.AddMinutes(-$correlationRule.TimeWindow)
                $timeEnd = $primaryEvent.Timestamp.AddMinutes($correlationRule.TimeWindow)

                $correlatedEvents = $events[$correlationRule.Source] | Where-Object {
                    $_.Timestamp -ge $timeStart -and $_.Timestamp -le $timeEnd -and
                    $this.EvaluateCorrelationConditions($_, $primaryEvent, $correlationRule.Conditions)
                }

                if ($correlatedEvents) {
                    $incident.CorrelatedEvents += $correlatedEvents
                    $incident.RiskScore += $correlatedEvents.Count
                    $incident.Timeline += $correlatedEvents
                }
            }

            # Trier la timeline
            $incident.Timeline = $incident.Timeline | Sort-Object Timestamp

            if ($incident.CorrelatedEvents.Count -gt 0) {
                $correlatedIncidents += $incident
            }
        }

        return $correlatedIncidents | Sort-Object RiskScore -Descending
    }

    [bool] EvaluateConditions([PSObject]$event, [string[]]$conditions) {
        foreach ($condition in $conditions) {
            if (-not (Invoke-Expression "`$event.$condition")) {
                return $false
            }
        }
        return $true
    }

    [bool] EvaluateCorrelationConditions([PSObject]$event, [PSObject]$primaryEvent, [string[]]$conditions) {
        foreach ($condition in $conditions) {
            switch ($condition) {
                "same IP" { if ($event.ClientIP -ne $primaryEvent.ClientIP) { return $false } }
                "same user" { if ($event.UserId -ne $primaryEvent.UserId) { return $false } }
                "external recipient" { if ($event.Recipients -notmatch "@(?!contoso\.com)") { return $false } }
                "volume > 100MB" { if (($event.FileSize / 1MB) -le 100) { return $false } }
            }
        }
        return $true
    }
}

📈 Techniques d'Analyse Comportementale

Baseline Comportementale

Établir une baseline du comportement normal pour détecter les déviations significatives.

function Build-UserBehaviorBaseline {
    param(
        [string]$UserPrincipalName,
        [int]$BaselineDays = 30
    )

    $endDate = (Get-Date).AddDays(-1)
    $startDate = $endDate.AddDays(-$BaselineDays)

    # Collecte des données historiques
    $signIns = Get-MgAuditLogSignIn -Filter "userPrincipalName eq '$UserPrincipalName' and createdDateTime ge $($startDate.ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All

    # Analyse des patterns
    $baseline = @{
        TypicalHours = $signIns | Group-Object { (Get-Date $_.CreatedDateTime).Hour } | Sort-Object Count -Descending | Select-Object -First 8 -ExpandProperty Name
        TypicalLocations = $signIns | Where-Object { $_.Location.CountryOrRegion } | Group-Object { $_.Location.CountryOrRegion } | Sort-Object Count -Descending | Select-Object -First 3 -ExpandProperty Name
        TypicalIPs = $signIns | Group-Object IpAddress | Sort-Object Count -Descending | Select-Object -First 10 -ExpandProperty Name
        TypicalDevices = $signIns | Where-Object { $_.DeviceDetail.DeviceId } | Group-Object { $_.DeviceDetail.DeviceId } | Sort-Object Count -Descending | Select-Object -First 5 -ExpandProperty Name
        AverageSessionsPerDay = ($signIns | Group-Object { (Get-Date $_.CreatedDateTime).Date } | Measure-Object -Property Count -Average).Average
        WeekendActivity = ($signIns | Where-Object { (Get-Date $_.CreatedDateTime).DayOfWeek -in @("Saturday", "Sunday") }).Count / $BaselineDays * 7
    }

    return $baseline
}

Détection d'Anomalies

Comparer l'activité actuelle avec la baseline pour identifier les comportements suspects.

Anomalies Temporelles

Connexions en dehors des heures habituelles, activité week-end inhabituelle

Anomalies Géographiques

Connexions depuis de nouveaux pays, voyage impossible

Anomalies Techniques

Nouveaux appareils, navigateurs différents, méthodes d'authentification

Anomalies Volumétriques

Augmentation significative d'activité, accès massif aux données

🔍 Audit Forensique Microsoft 365

Vous soupçonnez un incident de sécurité ? Nos experts forensiques analysent vos logs M365 avec des techniques avancées de corrélation pour reconstituer la chronologie complète des événements.

5 Unified Audit Log - Analyse Approfondie

Configuration Avancée UAL

# Configuration optimale de l'Unified Audit Log
Set-OrganizationConfig -AuditDisabled:$false
Enable-OrganizationCustomization
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled:$true

6 Intégration Microsoft Defender XDR

🛡️ Defender for Office 365

Protection avancée contre le phishing, malwares et liens malicieux avec analyse comportementale intégrée.

🔍 Defender for Identity

Détection des attaques sur les identités hybrides avec corrélation on-premises et cloud.

7 Requêtes KQL pour Threat Hunting

// Recherche d'activités suspectes multi-services
OfficeActivity
| where TimeGenerated > ago(24h)
| where Operation in ("FileDownloaded", "MailItemsAccessed", "Send")
| summarize EventCount = count(), UniqueFiles = dcount(OfficeObjectId) by UserId, ClientIP
| where EventCount > 100 or UniqueFiles > 50

12 Conclusion et Bonnes Pratiques

🎯 Points Clés

  • Corrélation multi-sources essentielle
  • Automatisation des analyses répétitives
  • Baseline comportementale pour la détection
  • Rétention long terme pour les investigations
  • Formation continue des équipes SOC

📈 Évolution

  • Intelligence artificielle pour l'analyse
  • Corrélation temps réel avec SOAR
  • Threat intelligence contextualisée
  • Automatisation de la réponse
  • Dashboards exécutifs en temps réel