Détecter les Attaques
par Compromission d'Identités

Par Ayi NEDJIMI Publié le 15 septembre 2025 15 min de lecture

Guide expert pour identifier, analyser et contrer les attaques ciblant les identités dans Microsoft 365 et Azure AD

📚 Lire le guide

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

24h
Temps de Détection
Objectif maximum
99.5%
Couverture Logs
Événements surveillés
<5%
Faux Positifs
Taux acceptable
15min
Temps de Réponse
Incidents critiques

# 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

1 Reconnaissance : Énumération d'utilisateurs via Exchange Web Services
2 Attaque : Password spraying contre les comptes identifiés
3 Accès initial : Connexion réussie depuis une IP inhabituelle
4 Persistance : Création d'une application OAuth malicieuse
5 Élévation : Tentative d'ajout de privilèges administratifs
6 Exfiltration : Accès massif aux boîtes emails et SharePoint

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. 1. Activation d'Azure AD Identity Protection
  2. 2. Déploiement MFA obligatoire
  3. 3. Configuration Conditional Access
  4. 4. Audit des applications OAuth
  5. 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.