1 Introduction aux Attaques d'Identité dans Microsoft 365
Les identités constituent le nouveau périmètre de sécurité dans l'ère du cloud. Avec Microsoft 365 et Azure AD (désormais Microsoft Entra ID), les organisations font face à des défis complexes de sécurisation des identités qui dépassent largement les approches traditionnelles de sécurité périmétrique.
Les attaques par compromission d'identités représentent aujourd'hui plus de 70% des incidents de sécurité majeurs. Les attaquants exploitent les faiblesses dans la gestion des identités, les configurations par défaut insuffisantes, et les comportements des utilisateurs pour établir une persistance et étendre leur accès au sein de l'environnement Microsoft 365.
🚨 Statistiques Alarmantes
- • 81% des violations impliquent des identités compromises ou faibles
- • Temps moyen de détection : 287 jours pour une identité compromise
- • Coût moyen : 4,45 millions de dollars par incident impliquant des identités
- • 95% des organisations n'ont pas de visibilité complète sur leurs identités privilégiées
Le Paysage des Menaces Identitaires
Microsoft 365 et Azure AD présentent une surface d'attaque unique qui combine les vulnérabilités des environnements on-premises et cloud. Les attaquants exploitent cette complexité pour :
🎯 Établir une Persistance
Création de backdoors via des applications OAuth malicieuses, des certificats, ou des comptes de service cachés.
🔄 Mouvement Latéral
Exploitation des relations d'approbation et des permissions héritées pour accéder à d'autres services.
💎 Élévation de Privilèges
Exploitation des rôles administratifs mal configurés et des workflows d'approbation automatiques.
📤 Exfiltration de Données
Accès aux boîtes emails, SharePoint, OneDrive et autres services stockant des données sensibles.
2 Techniques d'Attaque Courantes sur les Identités
🔑 Password Spraying et Credential Stuffing
Le password spraying consiste à tester des mots de passe courants contre de nombreux comptes pour éviter les verrouillages de compte. Cette technique est particulièrement efficace contre les environnements Microsoft 365 mal configurés.
Indicateurs de Compromission :
- • Multiples tentatives de connexion échouées depuis des IP différentes
- • Modèles de connexion anormaux (heures inhabituelles, géolocalisation)
- • Authentifications réussies après plusieurs échecs pour le même utilisateur
- • Augmentation du trafic vers les endpoints d'authentification
# Détection via Microsoft Graph PowerShell
Connect-MgGraph -Scopes "AuditLog.Read.All"
# Recherche des tentatives de connexion suspectes
$suspiciousSignIns = Get-MgAuditLogSignIn -Filter "status/errorCode ne 0" `
| Where-Object { $_.CreatedDateTime -gt (Get-Date).AddHours(-24) } `
| Group-Object UserPrincipalName `
| Where-Object { $_.Count -gt 10 }
$suspiciousSignIns | ForEach-Object {
Write-Output "Utilisateur suspect: $($_.Name) - $($_.Count) tentatives échouées"
}
🔐 Abus d'Applications OAuth et Consent Grant Attacks
Les attaquants créent des applications OAuth malicieuses qui demandent des permissions étendues. Une fois approuvées par les utilisateurs ou administrateurs, ces applications peuvent accéder aux données sans surveillance continue.
Applications OAuth Suspectes :
Permissions Dangereuses
- • Mail.ReadWrite
- • Files.ReadWrite.All
- • Directory.AccessAsUser.All
- • Application.ReadWrite.All
Signaux d'Alerte
- • Nom d'application générique
- • Pas de policy URL
- • Publisher non vérifié
- • Permissions excessives
# Audit des applications OAuth suspectes
# Lister toutes les applications avec leurs permissions
$apps = Get-MgApplication -All
$servicePrincipals = Get-MgServicePrincipal -All
foreach ($app in $apps) {
$sp = $servicePrincipals | Where-Object {$_.AppId -eq $app.AppId}
if ($sp) {
$permissions = Get-MgServicePrincipalOauth2PermissionGrant -ServicePrincipalId $sp.Id
# Filtrer les permissions dangereuses
$dangerousPerms = $permissions | Where-Object {
$_.Scope -match "Mail.ReadWrite|Files.ReadWrite.All|Directory.AccessAsUser.All"
}
if ($dangerousPerms) {
Write-Warning "Application suspecte: $($app.DisplayName)"
Write-Output "Permissions: $($dangerousPerms.Scope)"
}
}
}
🏆 Attaques Golden SAML
L'attaque Golden SAML permet aux attaquants qui ont compromis le certificat de signature SAML de forger des tokens d'authentification pour n'importe quel utilisateur, y compris les administrateurs.
🔥 Impact Critique
Cette attaque permet un accès persistant et furtif à l'environnement M365, souvent indétectable par les outils de monitoring traditionnels.
Détection des Attaques Golden SAML :
- • Authentifications SAML depuis des emplacements géographiques incohérents
- • Tokens SAML avec des durées de vie anormalement longues
- • Authentifications réussies sans trace dans les logs on-premises
- • Modifications non autorisées des certificats SAML
🔄 Attaques par Rejeu de Token
Les attaquants interceptent et réutilisent des tokens d'authentification valides pour maintenir l'accès même après le changement de mot de passe de la victime.
Durée de Vie
Les tokens peuvent être valides plusieurs heures
Multi-Device
Utilisation simultanée sur plusieurs appareils
Furtif
Difficile à détecter sans corrélation avancée
3 Stratégies de Détection et Monitoring Proactif
🎯 Approche Basée sur les Comportements
Baseline Comportementale
- • Heures de Connexion : Profils temporels habituels des utilisateurs
- • Géolocalisation : Emplacements de connexion typiques
- • Appareils : Devices habituellement utilisés
- • Applications : Services M365 régulièrement consultés
Anomalies Critiques
- • Voyage Impossible : Connexions depuis des pays distants en peu de temps
- • Volume Anormal : Téléchargements massifs ou activité excessive
- • Nouveaux Appareils : Connexions depuis des devices inconnus
- • Permissions Exceptionnelles : Accès à des ressources inhabituelles
📊 Métriques de Sécurité Clés
# Script de monitoring des métriques de sécurité
function Get-SecurityMetrics {
param([int]$DaysBack = 7)
$startDate = (Get-Date).AddDays(-$DaysBack)
# Connexions suspectes
$suspiciousSignIns = Get-MgAuditLogSignIn -Filter "createdDateTime ge $($startDate.ToString('yyyy-MM-ddTHH:mm:ssZ'))" `
| Where-Object { $_.RiskLevel -ne "none" -or $_.RiskState -ne "none" }
# Applications OAuth récemment approuvées
$recentApps = Get-MgAuditLogDirectoryAudit -Filter "createdDateTime ge $($startDate.ToString('yyyy-MM-ddTHH:mm:ssZ'))" `
| Where-Object { $_.Category -eq "ApplicationManagement" -and $_.Result -eq "success" }
# Métriques de sécurité
$metrics = @{
SuspiciousSignIns = $suspiciousSignIns.Count
NewApplications = $recentApps.Count
UniqueUsersAtRisk = ($suspiciousSignIns | Select-Object -Unique UserPrincipalName).Count
AverageRiskScore = ($suspiciousSignIns | Measure-Object -Property RiskLevelAggregated -Average).Average
}
return $metrics
}
4 Outils de Détection Natifs Microsoft 365
🛡️ Microsoft Defender for Identity
Defender for Identity surveille et analyse les activités des utilisateurs et entités (UEBA) pour détecter les attaques avancées, les identités compromises et les menaces internes malveillantes.
Capacités de Détection
- • Attaques Pass-the-Hash/Pass-the-Ticket
- • Reconnaissance Active Directory
- • Élévation de privilèges
- • Mouvement latéral
- • Persistance de domaine
Configuration Optimale
- • Capteurs sur tous les DC
- • Intégration avec Defender XDR
- • Seuils d'alerte personnalisés
- • Corrélation avec Azure AD
- • Playbooks de réponse automatisés
🔒 Azure AD Identity Protection
Solution native d'Azure AD qui utilise l'apprentissage automatique pour détecter et traiter les risques liés aux identités en temps réel.
Risques Utilisateur
- • Credentials divulgués
- • Activité inhabituelle
- • Propriétés de connexion atypiques
- • Menace détectée par Microsoft
Risques de Connexion
- • Adresse IP anonyme
- • Voyage impossible
- • Emplacements atypiques
- • Adresse IP suspecte
Actions Automatiques
- • Blocage automatique
- • Demande MFA
- • Changement de mot de passe
- • Notification d'alerte
# Configuration des politiques de risque
# Politique de risque utilisateur
$userRiskPolicy = @{
displayName = "High User Risk Policy"
isEnabled = $true
conditions = @{
userRiskLevels = @("high")
applications = @{
includeApplications = @("All")
}
users = @{
includeUsers = @("All")
excludeUsers = @("admin@contoso.com")
}
}
controls = @{
access = @{
isEnabled = $true
requirePasswordChange = $true
}
}
}
# Créer la politique
New-MgIdentityConditionalAccessPolicy -BodyParameter $userRiskPolicy
👁️ Microsoft Sentinel - SIEM Cloud
Sentinel fournit des capacités SIEM et SOAR cloud-natives avec des règles de détection pré-configurées pour les menaces identitaires M365.
Connecteurs de Données
- • Azure Active Directory (Sign-ins, Audit)
- • Microsoft 365 (Exchange, SharePoint, Teams)
- • Azure Activity (Subscription-level)
- • Security Events (Windows)
- • Microsoft Defender XDR
Règles de Détection
- • Brute Force Attacks
- • Impossible Travel
- • Privilege Escalation
- • Suspicious OAuth Apps
- • Data Exfiltration
💡 Bonnes Pratiques Sentinel
- • Configurer la rétention des données selon les besoins de conformité
- • Utiliser les workbooks pour créer des dashboards personnalisés
- • Automatiser la réponse avec des playbooks Logic Apps
- • Corréler les événements entre différentes sources de données
5 Scripts PowerShell de Détection Avancée
🔍 Détection d'Attaques Password Spraying
function Detect-PasswordSpraying {
[CmdletBinding()]
param(
[int]$TimeWindowHours = 1,
[int]$FailedAttemptsThreshold = 5,
[int]$UniqueUsersThreshold = 10
)
Write-Host "🔍 Détection d'attaques Password Spraying..." -ForegroundColor Cyan
# Connexion à Microsoft Graph
Connect-MgGraph -Scopes "AuditLog.Read.All", "Directory.Read.All"
$startTime = (Get-Date).AddHours(-$TimeWindowHours)
$endTime = Get-Date
# Récupérer les tentatives de connexion échouées
$failedSignIns = Get-MgAuditLogSignIn -Filter "createdDateTime ge $($startTime.ToString('yyyy-MM-ddTHH:mm:ssZ')) and status/errorCode ne 0" -All
# Analyser par adresse IP source
$ipAnalysis = $failedSignIns | Group-Object { $_.IpAddress } | ForEach-Object {
$ipAddress = $_.Name
$attempts = $_.Group
$uniqueUsers = ($attempts | Select-Object -Unique UserPrincipalName).Count
$totalAttempts = $attempts.Count
$countries = ($attempts | Select-Object -Unique @{Name="Country"; Expression={$_.Location.CountryOrRegion}}).Country
[PSCustomObject]@{
IpAddress = $ipAddress
TotalAttempts = $totalAttempts
UniqueUsers = $uniqueUsers
Countries = ($countries | Where-Object {$_ -ne $null}) -join ", "
IsSuspicious = ($uniqueUsers -ge $UniqueUsersThreshold -and $totalAttempts -ge $FailedAttemptsThreshold)
Users = ($attempts.UserPrincipalName | Select-Object -Unique) -join ", "
}
}
# Filtrer les IPs suspectes
$suspiciousIPs = $ipAnalysis | Where-Object { $_.IsSuspicious }
if ($suspiciousIPs) {
Write-Host "🚨 $(($suspiciousIPs).Count) adresses IP suspectes détectées!" -ForegroundColor Red
foreach ($ip in $suspiciousIPs) {
Write-Host "`n📍 IP: $($ip.IpAddress)" -ForegroundColor Yellow
Write-Host " Tentatives: $($ip.TotalAttempts)" -ForegroundColor White
Write-Host " Utilisateurs uniques: $($ip.UniqueUsers)" -ForegroundColor White
Write-Host " Pays: $($ip.Countries)" -ForegroundColor White
Write-Host " Utilisateurs ciblés: $($ip.Users)" -ForegroundColor Gray
}
# Génération de rapport détaillé
$reportPath = "PasswordSprayingReport_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$suspiciousIPs | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8
Write-Host "`n📄 Rapport sauvegardé: $reportPath" -ForegroundColor Green
# Recommandations automatiques
Write-Host "`n💡 Recommandations:" -ForegroundColor Cyan
Write-Host " 1. Bloquer les IPs suspectes dans Conditional Access" -ForegroundColor White
Write-Host " 2. Forcer le reset MFA pour les utilisateurs ciblés" -ForegroundColor White
Write-Host " 3. Activer le verrouillage intelligent Azure AD" -ForegroundColor White
Write-Host " 4. Implémenter des politiques de mots de passe renforcées" -ForegroundColor White
} else {
Write-Host "✅ Aucune activité de Password Spraying détectée." -ForegroundColor Green
}
return $suspiciousIPs
}
🔐 Audit des Applications OAuth Suspectes
function Audit-SuspiciousOAuthApps {
[CmdletBinding()]
param(
[int]$DaysBack = 30,
[switch]$ExportResults
)
Write-Host "🔐 Audit des applications OAuth suspectes..." -ForegroundColor Cyan
# Connexion avec permissions étendues
Connect-MgGraph -Scopes "Application.Read.All", "Directory.Read.All", "AuditLog.Read.All"
# Permissions considérées comme dangereuses
$dangerousPermissions = @(
"Mail.ReadWrite", "Mail.ReadWrite.Shared", "Mail.Send",
"Files.ReadWrite.All", "Sites.ReadWrite.All",
"Directory.ReadWrite.All", "Directory.AccessAsUser.All",
"User.ReadWrite.All", "Group.ReadWrite.All",
"Application.ReadWrite.All", "AppRoleAssignment.ReadWrite.All"
)
# Récupérer toutes les applications
Write-Host "📋 Récupération des applications..." -ForegroundColor Yellow
$applications = Get-MgApplication -All
$servicePrincipals = Get-MgServicePrincipal -All
$suspiciousApps = @()
foreach ($app in $applications) {
$sp = $servicePrincipals | Where-Object { $_.AppId -eq $app.AppId }
if ($sp) {
# Analyser les permissions OAuth2
$oauth2Permissions = Get-MgServicePrincipalOauth2PermissionGrant -ServicePrincipalId $sp.Id -ErrorAction SilentlyContinue
# Analyser les permissions d'application
$appRoles = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id -ErrorAction SilentlyContinue
$suspicionLevel = 0
$reasons = @()
# Vérifier les permissions dangereuses
foreach ($perm in $oauth2Permissions) {
$scopes = $perm.Scope -split ' '
foreach ($scope in $scopes) {
if ($scope -in $dangerousPermissions) {
$suspicionLevel += 2
$reasons += "Permission dangereuse: $scope"
}
}
}
# Vérifier les caractéristiques suspectes
if ([string]::IsNullOrEmpty($app.PublisherDomain) -or $app.PublisherDomain -eq "Unknown") {
$suspicionLevel += 1
$reasons += "Domaine éditeur inconnu"
}
if ([string]::IsNullOrEmpty($app.PrivacyStatementUrl)) {
$suspicionLevel += 1
$reasons += "Pas de politique de confidentialité"
}
if ($app.DisplayName -match "^(App|Application|Test|Demo)$") {
$suspicionLevel += 1
$reasons += "Nom générique suspect"
}
# Applications récemment créées avec beaucoup de permissions
if ($app.CreatedDateTime -gt (Get-Date).AddDays(-$DaysBack) -and $oauth2Permissions.Count -gt 5) {
$suspicionLevel += 2
$reasons += "Application récente avec nombreuses permissions"
}
if ($suspicionLevel -ge 3) {
$suspiciousApps += [PSCustomObject]@{
DisplayName = $app.DisplayName
AppId = $app.AppId
PublisherDomain = $app.PublisherDomain
CreatedDateTime = $app.CreatedDateTime
SuspicionLevel = $suspicionLevel
Reasons = $reasons -join "; "
OAuth2Permissions = ($oauth2Permissions.Scope -join "; ")
AppRoles = ($appRoles.AppRoleId -join "; ")
Users = ($oauth2Permissions | ForEach-Object { Get-MgUser -UserId $_.PrincipalId -ErrorAction SilentlyContinue | Select-Object -ExpandProperty UserPrincipalName }) -join "; "
}
}
}
}
# Affichage des résultats
if ($suspiciousApps) {
Write-Host "🚨 $($suspiciousApps.Count) applications suspectes détectées!" -ForegroundColor Red
foreach ($app in ($suspiciousApps | Sort-Object SuspicionLevel -Descending)) {
Write-Host "`n🔍 Application: $($app.DisplayName)" -ForegroundColor Yellow
Write-Host " App ID: $($app.AppId)" -ForegroundColor White
Write-Host " Niveau de suspicion: $($app.SuspicionLevel)/10" -ForegroundColor $(if($app.SuspicionLevel -ge 7){"Red"}elseif($app.SuspicionLevel -ge 5){"Yellow"}else{"White"})
Write-Host " Raisons: $($app.Reasons)" -ForegroundColor Gray
Write-Host " Créée le: $($app.CreatedDateTime)" -ForegroundColor Gray
Write-Host " Permissions: $($app.OAuth2Permissions)" -ForegroundColor Gray
}
if ($ExportResults) {
$reportPath = "SuspiciousOAuthApps_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$suspiciousApps | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8
Write-Host "`n📄 Rapport exporté: $reportPath" -ForegroundColor Green
}
# Recommandations
Write-Host "`n💡 Actions recommandées:" -ForegroundColor Cyan
Write-Host " 1. Révoquer l'accès des applications hautement suspectes" -ForegroundColor White
Write-Host " 2. Implémenter une politique de consentement administrateur" -ForegroundColor White
Write-Host " 3. Auditer régulièrement les permissions OAuth" -ForegroundColor White
Write-Host " 4. Former les utilisateurs sur les risques du consentement" -ForegroundColor White
} else {
Write-Host "✅ Aucune application OAuth suspecte détectée." -ForegroundColor Green
}
return $suspiciousApps
}
👑 Monitoring des Identités Privilégiées
function Monitor-PrivilegedIdentities {
[CmdletBinding()]
param(
[int]$MonitoringPeriodHours = 24,
[switch]$AlertOnAnomalies
)
Write-Host "👑 Monitoring des identités privilégiées..." -ForegroundColor Cyan
Connect-MgGraph -Scopes "Directory.Read.All", "AuditLog.Read.All", "RoleManagement.Read.All"
# Rôles privilégiés à surveiller
$privilegedRoles = @(
"Global Administrator",
"Privileged Role Administrator",
"User Administrator",
"Exchange Administrator",
"SharePoint Administrator",
"Security Administrator",
"Conditional Access Administrator"
)
$startTime = (Get-Date).AddHours(-$MonitoringPeriodHours)
# Récupérer les rôles et leurs membres
$roleMembers = @()
foreach ($roleName in $privilegedRoles) {
$role = Get-MgDirectoryRole -Filter "displayName eq '$roleName'"
if ($role) {
$members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id
foreach ($member in $members) {
$user = Get-MgUser -UserId $member.Id -ErrorAction SilentlyContinue
if ($user) {
$roleMembers += [PSCustomObject]@{
RoleName = $roleName
UserPrincipalName = $user.UserPrincipalName
DisplayName = $user.DisplayName
UserId = $user.Id
AccountEnabled = $user.AccountEnabled
LastSignIn = $user.SignInActivity.LastSignInDateTime
}
}
}
}
}
Write-Host "📊 $($roleMembers.Count) identités privilégiées trouvées" -ForegroundColor Yellow
# Analyser l'activité de connexion récente
$privilegedActivity = @()
foreach ($member in $roleMembers) {
$signIns = Get-MgAuditLogSignIn -Filter "userId eq '$($member.UserId)' and createdDateTime ge $($startTime.ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All
# Analyser les anomalies
$anomalies = @()
$locations = $signIns | Select-Object -Unique @{Name="Country"; Expression={$_.Location.CountryOrRegion}}
$ipAddresses = $signIns | Select-Object -Unique IpAddress
# Détection de voyage impossible
if ($locations.Count -gt 2) {
$anomalies += "Connexions depuis $($locations.Count) pays différents"
}
# Détection d'IPs multiples
if ($ipAddresses.Count -gt 5) {
$anomalies += "Connexions depuis $($ipAddresses.Count) adresses IP différentes"
}
# Connexions en dehors des heures de bureau
$afterHours = $signIns | Where-Object {
$hour = (Get-Date $_.CreatedDateTime).Hour
$hour -lt 8 -or $hour -gt 18
}
if ($afterHours.Count -gt 0) {
$anomalies += "$($afterHours.Count) connexions en dehors des heures de bureau"
}
# Connexions échouées récentes
$failedSignIns = $signIns | Where-Object { $_.Status.ErrorCode -ne 0 }
$privilegedActivity += [PSCustomObject]@{
UserPrincipalName = $member.UserPrincipalName
RoleName = $member.RoleName
TotalSignIns = $signIns.Count
FailedSignIns = $failedSignIns.Count
UniqueCountries = $locations.Count
UniqueIPs = $ipAddresses.Count
AfterHoursSignIns = $afterHours.Count
Anomalies = if($anomalies) { $anomalies -join "; " } else { "Aucune" }
IsAnomalous = $anomalies.Count -gt 0
LastSignIn = if($signIns) { ($signIns | Sort-Object CreatedDateTime -Descending | Select-Object -First 1).CreatedDateTime } else { "Aucune connexion récente" }
}
}
# Afficher les résultats
$anomalousUsers = $privilegedActivity | Where-Object { $_.IsAnomalous }
if ($anomalousUsers) {
Write-Host "🚨 $($anomalousUsers.Count) identités privilégiées avec comportement anormal!" -ForegroundColor Red
foreach ($user in $anomalousUsers) {
Write-Host "`n⚠️ Utilisateur: $($user.UserPrincipalName)" -ForegroundColor Yellow
Write-Host " Rôle: $($user.RoleName)" -ForegroundColor White
Write-Host " Connexions: $($user.TotalSignIns) (dont $($user.FailedSignIns) échouées)" -ForegroundColor White
Write-Host " Anomalies: $($user.Anomalies)" -ForegroundColor Red
Write-Host " Dernière connexion: $($user.LastSignIn)" -ForegroundColor Gray
}
if ($AlertOnAnomalies) {
Write-Host "`n🚨 Génération d'alertes pour les comportements anormaux..." -ForegroundColor Red
# Ici, vous pourriez intégrer l'envoi d'alertes par email, Teams, ou webhook
}
} else {
Write-Host "✅ Aucun comportement anormal détecté pour les identités privilégiées." -ForegroundColor Green
}
# Rapport complet
$reportPath = "PrivilegedIdentitiesReport_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$privilegedActivity | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8
Write-Host "`n📄 Rapport complet sauvegardé: $reportPath" -ForegroundColor Green
return $privilegedActivity
}
6 Analyse des Logs et Corrélation d'Événements
📊 Sources de Logs Critiques
Azure AD Sign-in Logs
Événements Critiques
- • Connexions depuis des IP suspectes
- • Authentification multi-facteur contournée
- • Impossible travel détecté
- • Nouveaux appareils ou navigateurs
- • Connexions en dehors des heures habituelles
Azure AD Audit Logs
Activités Sensibles
- • Modification des rôles administratifs
- • Création/suppression d'utilisateurs
- • Changements de politiques de sécurité
- • Enregistrement d'applications OAuth
- • Modifications des paramètres MFA
# Script de corrélation d'événements avancée
function Correlate-SecurityEvents {
[CmdletBinding()]
param(
[int]$TimeWindowMinutes = 30,
[int]$SuspicionThreshold = 5
)
# Récupération des événements de connexion et d'audit
$startTime = (Get-Date).AddMinutes(-$TimeWindowMinutes)
$signInLogs = Get-MgAuditLogSignIn -Filter "createdDateTime ge $($startTime.ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All
$auditLogs = Get-MgAuditLogDirectoryAudit -Filter "createdDateTime ge $($startTime.ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All
# Corrélation par utilisateur et fenêtre temporelle
$correlatedEvents = @{}
foreach ($signIn in $signInLogs) {
$userId = $signIn.UserId
$timeStamp = $signIn.CreatedDateTime
if (-not $correlatedEvents[$userId]) {
$correlatedEvents[$userId] = @{
SignInEvents = @()
AuditEvents = @()
SuspicionScore = 0
}
}
$correlatedEvents[$userId].SignInEvents += $signIn
# Calcul du score de suspicion pour les connexions
if ($signIn.RiskLevel -ne "none") { $correlatedEvents[$userId].SuspicionScore += 3 }
if ($signIn.Status.ErrorCode -ne 0) { $correlatedEvents[$userId].SuspicionScore += 1 }
if ($signIn.DeviceDetail.IsCompliant -eq $false) { $correlatedEvents[$userId].SuspicionScore += 2 }
# Rechercher les événements d'audit dans la fenêtre temporelle
$relatedAuditEvents = $auditLogs | Where-Object {
($_.InitiatedBy.User.Id -eq $userId -or $_.TargetResources.Id -contains $userId) -and
[Math]::Abs(((Get-Date $_.ActivityDateTime) - (Get-Date $timeStamp)).TotalMinutes) -le 10
}
foreach ($audit in $relatedAuditEvents) {
$correlatedEvents[$userId].AuditEvents += $audit
# Augmentation du score pour certaines activités
switch ($audit.Category) {
"RoleManagement" { $correlatedEvents[$userId].SuspicionScore += 4 }
"ApplicationManagement" { $correlatedEvents[$userId].SuspicionScore += 3 }
"UserManagement" { $correlatedEvents[$userId].SuspicionScore += 2 }
"Policy" { $correlatedEvents[$userId].SuspicionScore += 2 }
}
}
}
# Filtrer et afficher les utilisateurs suspects
$suspiciousUsers = $correlatedEvents.GetEnumerator() | Where-Object { $_.Value.SuspicionScore -ge $SuspicionThreshold }
Write-Host "🔍 Analyse de corrélation terminée" -ForegroundColor Cyan
Write-Host "📊 $($correlatedEvents.Count) utilisateurs analysés" -ForegroundColor Yellow
Write-Host "🚨 $($suspiciousUsers.Count) utilisateurs suspects identifiés" -ForegroundColor Red
return $suspiciousUsers
}
🎯 Patterns d'Attaque Typiques
Séquence d'Attaque par Compromission
Indicateurs Temporels
Phase Initiale (0-15 min)
- • Multiple failed logins
- • Successful authentication
- • New device registration
Établissement (15-60 min)
- • OAuth app creation
- • Permission grants
- • MFA method changes
Exploitation (1h+)
- • Mass data access
- • Privilege escalation
- • Lateral movement
7 Azure AD Identity Protection - Configuration Avancée
🤖 Intelligence Artificielle et Machine Learning
Azure AD Identity Protection utilise l'intelligence artificielle et les signaux de Microsoft pour évaluer les risques en temps réel. La solution analyse plus de 6,5 trillions de signaux par jour pour détecter les menaces sophistiquées.
Détection Comportementale
- • Analyse des patterns de connexion
- • Détection d'anomalies temporelles
- • Reconnaissance de dispositifs habituels
- • Corrélation géographique
Threat Intelligence
- • Base de données des IP malveillantes
- • Signatures d'attaques connues
- • Corrélation avec Microsoft Defender
- • IOCs globaux partagés
Réponse Automatique
- • Blocage temps réel
- • Escalade MFA automatique
- • Quarantaine préventive
- • Notification immédiate
⚙️ Configuration des Politiques de Risque
Politique de Risque Utilisateur
# Configuration avancée de la politique de risque utilisateur
$userRiskPolicy = @{
displayName = "High User Risk - Force Password Reset"
isEnabled = $true
state = "enabled"
conditions = @{
userRiskLevels = @("high")
applications = @{
includeApplications = @("All")
excludeApplications = @()
}
users = @{
includeUsers = @("All")
excludeUsers = @("admin@contoso.com", "breakglass@contoso.com")
includeGroups = @()
excludeGroups = @("Emergency-Access-Group")
}
platforms = @{
includePlatforms = @("all")
}
locations = @{
includeLocations = @("All")
excludeLocations = @("Trusted-Corporate-Network")
}
}
grantControls = @{
operator = "OR"
builtInControls = @("passwordChange", "mfa")
customAuthenticationFactors = @()
termsOfUse = @()
}
sessionControls = @{
applicationEnforcedRestrictions = @{
isEnabled = $false
}
persistentBrowser = @{
isEnabled = $false
}
signInFrequency = @{
isEnabled = $true
type = "hours"
value = 1
}
}
}
Politique de Risque de Connexion
# Configuration de la politique de risque de connexion
$signInRiskPolicy = @{
displayName = "Medium+ Sign-in Risk - Require MFA"
isEnabled = $true
state = "enabled"
conditions = @{
signInRiskLevels = @("medium", "high")
applications = @{
includeApplications = @("All")
}
users = @{
includeUsers = @("All")
excludeUsers = @("breakglass@contoso.com")
}
clientAppTypes = @("all")
deviceStates = @{
includeStates = @("all")
excludeStates = @("compliant", "hybridAzureADJoined")
}
}
grantControls = @{
operator = "OR"
builtInControls = @("mfa")
}
sessionControls = @{
signInFrequency = @{
isEnabled = $true
type = "hours"
value = 4
}
cloudAppSecurity = @{
isEnabled = $true
cloudAppSecurityType = "monitorOnly"
}
}
}
# Création des politiques
New-MgIdentityConditionalAccessPolicy -BodyParameter $userRiskPolicy
New-MgIdentityConditionalAccessPolicy -BodyParameter $signInRiskPolicy
📈 Monitoring et Tuning des Politiques
Métriques Clés à Surveiller
-
•
Taux de Faux Positifs :Pourcentage d'alertes légitimes classées comme risquées
-
•
Temps de Détection :Délai entre l'incident et la détection automatique
-
•
Taux de Remédiation :Pourcentage d'incidents résolus automatiquement
-
•
Impact Utilisateur :Nombre d'interruptions légitimes causées
Optimisation Continue
Ajustement des Seuils
Révision mensuelle des niveaux de risque selon les faux positifs observés
Exclusions Intelligentes
Ajout d'exceptions basées sur les patterns légitimes identifiés
Feedback Loop
Intégration des retours utilisateurs dans l'amélioration des modèles
🔒 Protégez Vos Identités Microsoft 365
Ne laissez pas les attaquants exploiter vos identités. Nos experts analysent votre environnement M365 et implémentent des solutions de détection avancée pour protéger vos données critiques.
8 Mesures de Prévention et Durcissement
🔐 Authentification Forte
- • Déploiement MFA pour tous les utilisateurs
- • Authentification sans mot de passe (FIDO2, Windows Hello)
- • Conditional Access granulaire par rôle
- • Verrouillage intelligent Azure AD
🛡️ Gouvernance des Identités
- • Principe du moindre privilège strict
- • Revue régulière des permissions administratives
- • Comptes de service dédiés et surveillés
- • Rotation automatique des secrets
9 Réponse aux Incidents d'Identité
🚨 Playbook de Réponse
Phase 1 : Containment (0-30 min)
Isolation immédiate du compte compromis, révocation des tokens actifs, blocage des IP suspectes
Phase 2 : Investigation (30 min - 2h)
Analyse forensique des logs, identification de l'étendue de la compromission, timeline des activités
Phase 3 : Éradication (2-24h)
Suppression des artifacts malicieux, renforcement des contrôles, mise à jour des règles de détection
10 Conformité et Gouvernance
📋 RGPD
Traçabilité des accès aux données personnelles, droit à l'oubli, notification de violation
🏢 ISO 27001
Gestion des risques identitaires, contrôles d'accès, surveillance continue
🏥 HDS
Authentification forte pour données de santé, audit des accès, chiffrement
11 Cas d'Études et Exemples Pratiques
🏢 Cas d'Étude : Attaque Sophistiquée sur une Multinationale
Contexte
- • 50,000 utilisateurs Microsoft 365
- • Environnement hybride AD/Azure AD
- • Multiples filiales géographiques
- • Applications métiers critiques
Vecteur d'Attaque
- • Spear-phishing ciblant les RH
- • Vol de credentials administrateur
- • Création d'applications OAuth malicieuses
- • Exfiltration de données pendant 3 mois
Enseignements
La détection tardive (89 jours) aurait pu être évitée avec un monitoring proactif des applications OAuth et une corrélation avancée des événements de connexion.
12 Conclusion et Recommandations
La sécurisation des identités dans Microsoft 365 nécessite une approche multicouche combinant prévention, détection et réponse. Les organisations qui réussissent sont celles qui implémentent une stratégie Zero Trust complète avec un monitoring continu des comportements utilisateurs.
🎯 Priorités Immédiates
- 1. Activation d'Azure AD Identity Protection
- 2. Déploiement MFA obligatoire
- 3. Configuration Conditional Access
- 4. Audit des applications OAuth
- 5. Monitoring des identités privilégiées
📈 Roadmap Long Terme
- • Implémentation Zero Trust complète
- • Intégration SIEM/SOAR avancée
- • Automatisation des réponses
- • Formation continue des équipes
- • Tests d'intrusion réguliers
🚀 Passez à l'Action
La sécurité des identités ne peut plus être considérée comme optionnelle. Chaque jour de retard augmente votre exposition aux menaces sophistiquées qui ciblent Microsoft 365.