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
# 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 fichiersFileDownloaded
- TéléchargementsSharingSet
- Configuration de partageAnonymousLinkUsed
- Utilisation liens anonymesFileUploaded
- Uploads de fichiersFolderCreated
- Création de dossiersFileDeleted
- SuppressionsFileModified
- 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