> For the complete documentation index, see [llms.txt](https://docs.stoik.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stoik.io/cyber-best-practices/fr/guides-de-remediation-des-vulnerabilites/ad-scan-vulnerability-remediation-guide.md).

# Guide de remédiation du Scan Externe Active Directory

Chaque section de vulnérabilité comprend :

* **Ce que cela signifie :** une explication simple du risque
* **Ce que le scan vérifie :** les conditions spécifiques qui déclenchent l'alerte
* **Pourquoi l'alerte peut persister :** les corrections partielles courantes qui ne suffisent pas
* **Comment diagnostiquer :** Commandes PowerShell pour identifier les objets concernés
* **Comment corriger :** remédiation étape par étape

> **Prérequis :** Toutes les commandes PowerShell nécessitent le `module ActiveDirectory` et doivent être exécutées en tant qu'administrateur du domaine sur un contrôleur de domaine.
>
> ```powershell
> Import-Module ActiveDirectory
> ```

## A-LAPS-Not-Installed

#### Ce que cela signifie

Chaque ordinateur Windows possède un **compte Administrateur local intégré**. Par défaut, ce compte utilise souvent le même mot de passe sur toutes les machines, ou un mot de passe qui ne change jamais. Si un attaquant compromet une machine, il peut réutiliser ce mot de passe pour accéder à toutes les autres.

**LAPS** (Local Administrator Password Solution) résout ce problème en définissant automatiquement un mot de passe unique, généré aléatoirement, sur chaque ordinateur et en le stockant de manière sécurisée dans Active Directory. Seuls les administrateurs autorisés peuvent le récupérer.

#### Ce que l’analyse vérifie

Le scan AD recherche des preuves que LAPS a été configuré dans votre Active Directory. Plus précisément, il vérifie si les champs de données LAPS nécessaires existent dans votre configuration AD. S'ils n'existent pas, cela signifie que LAPS n'a jamais été installé.

#### Pourquoi l'alerte peut persister

* **LAPS géré uniquement via Intune :** Si vous utilisez Microsoft Intune pour gérer les mots de passe LAPS dans le cloud (sans configurer l'AD local), le scan AD ne peut pas le détecter. Le scan ne recherche que votre Active Directory local.
* **LAPS a été partiellement installé :** La configuration LAPS a peut-être été commencée mais pas terminée.

#### Comment diagnostiquer

```powershell
# Vérifiez si LAPS est configuré dans votre Active Directory
Get-ADObject -SearchBase (Get-ADRootDSE).SchemaNamingContext `
  -Filter "name -like 'ms-Mcs-AdmPwd' -or name -eq 'ms-LAPS-Password'" |
  Select-Object Name, whenCreated
```

Si cela ne retourne aucun résultat, LAPS n'est pas installé.

#### Comment corriger

**Pour Windows Server 2019 et versions ultérieures (recommandé) :** Le LAPS moderne est intégré à Windows. Activez-le via la stratégie de groupe :

1. Ouvrez `gpmc.msc` (Gestion des stratégies de groupe)
2. Modifiez ou créez un GPO lié à vos OU d'ordinateurs
3. Accédez à : `Configuration ordinateur > Modèles d'administration > Système > LAPS`
4. Configurez les paramètres LAPS (activation, complexité du mot de passe, etc.)

**Pour les environnements plus anciens :** Téléchargez le LAPS hérité de Microsoft et exécutez l'extension du schéma :

```powershell
Update-LapsADSchema
```

> **Remarque :** Si vous gérez les mots de passe administrateur locaux via un autre outil (CyberArk, LAPS uniquement via Intune, etc.), contactez le support Stoïk pour documenter cela comme une exception acceptée.

## A-LAPS-Joined-Computers

#### Ce que cela signifie

Lorsqu'une personne ajoute ("joint") un ordinateur au domaine Active Directory, cette personne devient le **créateur** de l'objet ordinateur dans AD. Par défaut, le créateur obtient des autorisations spéciales sur cet objet.

Le problème est que, lorsque LAPS est installé, le mot de passe de l'administrateur local est stocké dans ce même objet ordinateur. Si le créateur dispose encore des autorisations appropriées, il peut **lire le mot de passe LAPS**, même s'il n'est pas administrateur. Cela signifie qu'un utilisateur ordinaire qui a un jour joint un PC au domaine pourrait récupérer le mot de passe administrateur local de cette machine.

#### Ce que l’analyse vérifie

Pour chaque ordinateur activé avec LAPS déployé, le scan AD vérifie **deux choses**:

1. **La personne qui a joint l'ordinateur est-elle toujours le "propriétaire" de l'objet ordinateur ?** Les propriétaires peuvent s'attribuer n'importe quelle autorisation, y compris la lecture du mot de passe LAPS.
2. **Le créateur a-t-il encore des autorisations explicites** sur l'objet ordinateur, telles que `Tous les droits étendus` (qui permettent de lire le mot de passe LAPS), `WriteDacl` (qui permet de modifier les autorisations), `WriteOwner` (qui permet de reprendre la propriété), ou `GenericWrite`?

L'alerte se déclenche si **l'une ou l'autre** condition est vraie.

#### Pourquoi l'alerte peut persister

C'est la source de confusion la plus courante : **modifier le propriétaire n'est que la moitié de la correction.**

Beaucoup d'administrateurs changent le propriétaire en "Domain Admins" et s'attendent à ce que l'alerte disparaisse. Mais le scan AD vérifie également la présence d'autorisations résiduelles (appelées ACE, ou entrées de contrôle d'accès) qui ont été accordées au créateur d'origine. Ces autorisations restent en place même après le changement de propriétaire et doivent être supprimées séparément.

#### Comment diagnostiquer

```powershell
# Listez les ordinateurs où le créateur dispose encore d'autorisations à risque
Get-ADComputer -Filter "Enabled -eq `$true" `
  -Properties "mS-DS-CreatorSID", "nTSecurityDescriptor" |
  Where-Object { $_."mS-DS-CreatorSID" -ne $null } |
  ForEach-Object {
    $comp = $_
    $acl = $comp.nTSecurityDescriptor
    $creatorSid = $comp."mS-DS-CreatorSID"
    $owner = $acl.GetOwner([System.Security.Principal.SecurityIdentifier])

    $isOwner = ($owner.Value -eq $creatorSid.Value)

    $riskyAces = $acl.Access | Where-Object {
      -not $_.IsInherited -and
      $_.IdentityReference.Value -eq $creatorSid.Value -and
      ($_.ActiveDirectoryRights -match 'WriteDacl|WriteOwner|GenericWrite|ExtendedRight')
    }

    if ($isOwner -or $riskyAces) {
      [PSCustomObject]@{
        Computer       = $comp.Name
        CreatorIsOwner = $isOwner
        RiskyRights    = ($riskyAces | ForEach-Object { $_.ActiveDirectoryRights }) -join ", "
      }
    }
  } | Format-Table -AutoSize
```

#### Comment corriger

Vous devez **les deux** pour chaque ordinateur concerné :

1. **Changer le propriétaire** en Domain Admins
2. **Supprimer les autorisations explicites du créateur**

Le script suivant fait les deux automatiquement :

```powershell
#Requires -Modules ActiveDirectory

$affectedComputers = Get-ADComputer -Filter "Enabled -eq `$true" `
  -Properties "mS-DS-CreatorSID", "nTSecurityDescriptor" |
  Where-Object { $_."mS-DS-CreatorSID" -ne $null }

foreach ($comp in $affectedComputers) {
  $path = "AD:$($comp.DistinguishedName)"
  $acl = Get-Acl -Path $path
  $creatorSid = $comp."mS-DS-CreatorSID"
  $modified = $false

  # Étape 1 : changer le propriétaire en Domain Admins
  $domainAdmins = New-Object System.Security.Principal.NTAccount("$env:USERDOMAIN", "Domain Admins")
  $acl.SetOwner($domainAdmins)
  $modified = $true

  # Étape 2 : supprimer les autorisations explicites accordées au créateur (et les SID orphelins)
  $toRemove = @($acl.Access | Where-Object {
    -not $_.IsInherited -and
    ($_.IdentityReference.Value -eq $creatorSid.Value -or
     $_.IdentityReference.Value -match '^S-1-5-21-')  # SID orphelins (comptes supprimés)
  })

  foreach ($ace in $toRemove) {
    $acl.RemoveAccessRuleSpecific($ace)
    Write-Host "$($comp.Name) : supprimé [$($ace.ActiveDirectoryRights)] pour $($ace.IdentityReference)"
  }

  if ($modified) {
    Set-Acl -Path $path -AclObject $acl
    Write-Host "$($comp.Name) : corrigé" -ForegroundColor Green
  }
}
```

> **Astuce :** Exécutez d'abord la commande de diagnostic pour examiner la liste des ordinateurs concernés avant d'appliquer la correction.

## A-NoServicePolicy

#### Ce que cela signifie

**Comptes de service** sont des comptes utilisés par les applications et les services (par exemple, SQL Server, des agents de sauvegarde) pour s'authentifier dans Active Directory. Contrairement aux comptes utilisateur classiques, les comptes de service sont des cibles à forte valeur : ils disposent souvent d'autorisations élevées et leurs mots de passe sont rarement modifiés.

Un **stratégie de mot de passe à granularité fine (PSO)** est une règle de mot de passe spéciale que vous pouvez appliquer à des groupes de comptes spécifiques. Le scan AD s'attend à ce que vos comptes de service soient couverts par une PSO exigeant des mots de passe d'au moins **20 caractères**, ce qui les rend beaucoup plus difficiles à casser.

#### Ce que l’analyse vérifie

Le scan AD recherche au moins une stratégie de mot de passe (GPO ou PSO) qui impose une longueur minimale de mot de passe de **20 caractères ou plus**.

#### Pourquoi l'alerte peut persister

1. **Le compte de scan n'a pas l'autorisation de lire la PSO.** Les stratégies de mot de passe sont stockées dans une zone protégée d'AD que seuls les Domain Admins peuvent lire par défaut. Si le scan s'exécute avec un compte moins privilégié, il ne peut tout simplement pas voir la PSO, même si elle existe.
2. **La PSO existe, mais la longueur minimale est inférieure à 20** (par exemple 12 ou 15 caractères).
3. **La PSO existe, mais n'est attribuée à aucun groupe ni utilisateur.**

#### Comment diagnostiquer

```powershell
# Listez toutes les stratégies de mot de passe à granularité fine et leurs paramètres
Get-ADFineGrainedPasswordPolicy -Filter * |
  Select-Object Name, MinPasswordLength, @{N="AppliedTo"; E={$_.AppliesTo -join ", "}}, Precedence
```

Si cela ne renvoie rien, soit aucune PSO n'existe, soit le compte qui exécute la commande n'a pas les autorisations pour la voir. Essayez avec un compte d'administrateur du domaine.

#### Comment corriger

**Si la PSO existe mais que le scan ne peut pas la voir :** Exécutez le scan AD avec un compte d'administrateur du domaine.

**Si aucune PSO n'existe :** Créez-en une et attribuez-la à vos comptes de service :

```powershell
# Créez une stratégie de mot de passe pour les comptes de service
New-ADFineGrainedPasswordPolicy -Name "Service Accounts - Strong Password" `
  -Precedence 10 `
  -MinPasswordLength 20 `
  -MaxPasswordAge "90.00:00:00" `
  -MinPasswordAge "1.00:00:00" `
  -PasswordHistoryCount 24 `
  -ComplexityEnabled $true `
  -ReversibleEncryptionEnabled $false `
  -LockoutDuration "00:30:00" `
  -LockoutObservationWindow "00:30:00" `
  -LockoutThreshold 5

# Attribuez-la à un groupe de sécurité contenant vos comptes de service
Add-ADFineGrainedPasswordPolicySubject `
  -Identity "Service Accounts - Strong Password" `
  -Subjects "SG_ServiceAccounts"
```

> **Remarque :** La création d'une PSO n'impose pas immédiatement des changements de mot de passe. Les mots de passe existants continueront de fonctionner jusqu'à leur expiration ou jusqu'à une réinitialisation manuelle. À ce moment-là, la nouvelle limite minimale de 20 caractères s'appliquera.

## A-AuditDC

#### Ce que cela signifie

**Politiques d'audit** déterminent quels événements sont journalisés sur vos contrôleurs de domaine. Sans audit approprié, des attaques comme le vol d'identifiants, les modifications de groupe non autorisées ou l'abus de réplication (DCSync) peuvent se produire sans laisser de trace dans les journaux.

Le scan AD vérifie que vos contrôleurs de domaine sont configurés pour journaliser les événements de sécurité les plus importants.

#### Ce que l’analyse vérifie

Le scan recherche **13 sous-catégories d'audit spécifiques** qui devraient être activées via la stratégie de groupe sur tous les contrôleurs de domaine :

| Catégorie                                       | Ce qu'elle journalise                                                        |
| ----------------------------------------------- | ---------------------------------------------------------------------------- |
| Service d'authentification Kerberos             | Tentatives de connexion via Kerberos                                         |
| Opérations sur les tickets de service Kerberos  | Demandes de tickets de service (détecte le Kerberoasting)                    |
| Gestion des comptes ordinateur                  | Connexions/modifications d'ordinateurs dans AD                               |
| Gestion des groupes de sécurité                 | Modifications de l'appartenance aux groupes                                  |
| Gestion des comptes utilisateur                 | Création, suppression et réinitialisation des mots de passe des utilisateurs |
| Activité DPAPI                                  | Utilisation de l'API de protection des données (accès aux identifiants)      |
| Création de processus                           | Nouveaux processus démarrés (détecte les outils malveillants)                |
| Ouverture/fermeture de session                  | Connexions locales et distantes                                              |
| Ouverture de session spéciale                   | Connexions avec privilèges élevés                                            |
| Modification de la stratégie d'authentification | Modifications des paramètres d'authentification                              |
| Utilisation de privilèges sensibles             | Utilisation d'autorisations sensibles                                        |
| Extension du système de sécurité                | Modifications du sous-système de sécurité                                    |

#### Pourquoi l'alerte peut persister

1. **Les paramètres appliqués via `auditpol` directement sur le contrôleur de domaine** ne sont pas détectés. Le scan AD lit les fichiers de stratégie de groupe, pas la configuration locale du DC. Vous devez utiliser un GPO.
2. **GPO conflictuels :** Un GPO active le paramètre, mais un autre GPO avec une priorité plus élevée le désactive.
3. **GPO non lié à l'OU des contrôleurs de domaine :** Le GPO existe mais est lié à une autre OU.

#### Comment diagnostiquer

```powershell
# Vérifiez la stratégie d'audit effective sur un contrôleur de domaine
auditpol /get /category:*
```

Si les paramètres locaux semblent corrects mais que l'alerte persiste, vérifiez que les paramètres proviennent d'un GPO (et non d'un remplacement local) :

```powershell
# Vérifiez quels GPO sont liés à l'OU des contrôleurs de domaine
Get-GPInheritance -Target "OU=Domain Controllers,$($(Get-ADDomain).DistinguishedName)"
```

#### Comment corriger

1. Ouvrez `gpmc.msc` (Console de gestion des stratégies de groupe)
2. Créez ou modifiez un GPO lié à `OU=Contrôleurs de domaine`
3. Accédez à : `Configuration ordinateur > Stratégies > Paramètres Windows > Paramètres de sécurité > Configuration de la stratégie d'audit avancée > Stratégies d'audit`
4. Activez **Succès et échec** pour toutes les sous-catégories listées ci-dessus
5. Exécutez `gpupdate /force` sur tous les contrôleurs de domaine

Vérifiez la correction :

```powershell
auditpol /get /category:"Account Logon"
auditpol /get /category:"Account Management"
auditpol /get /category:"Logon/Logoff"
```

## A-BadSuccessor

#### Ce que cela signifie

Windows Server 2025 a introduit un nouveau type de compte de service appelé **dMSA** (Delegated Managed Service Account). Une faille de sécurité a été découverte : un utilisateur standard disposant de certaines autorisations sur un dossier Active Directory (appelé unité d'organisation, ou OU) pouvait créer un dMSA et l'utiliser pour obtenir un accès administrateur complet au domaine.

Cette attaque n'est possible que lorsque :

* vous disposez d'au moins un **Windows Server 2025** contrôleur de domaine
* Un **clé racine KDS** existe (requis pour les comptes de service gérés)
* un utilisateur non administrateur a le droit de créer des objets dans une OU

#### Ce que l’analyse vérifie

Le scan AD recherche les utilisateurs ou groupes non privilégiés qui ont des autorisations pour créer ou contrôler des objets dMSA dans n'importe quelle OU, telles que `CreateChild`, `GenericAll`, `WriteDacl`, ou `WriteOwner`.

#### Pourquoi l'alerte peut persister

* La correction doit être appliquée sur **chaque** OU concernée, pas seulement une.
* Les autorisations héritées des OU parentes s'appliquent toujours aux OU enfants.
* Les groupes d'administration personnalisés peuvent ne pas être reconnus comme « privilégiés » par le scan.

#### Comment diagnostiquer

```powershell
# Vérifiez les prérequis
Get-KdsRootKey  # La KDS Root Key doit exister pour que l'attaque soit possible

Get-ADDomainController -Filter * |
  Where-Object { $_.OperatingSystem -like "*2025*" } |
  Select-Object Name, OperatingSystem  # Au moins un DC Win2025

# Trouvez les OU avec des délégations à risque
Get-ADOrganizationalUnit -Filter * -Properties nTSecurityDescriptor |
  ForEach-Object {
    $ou = $_
    $ou.nTSecurityDescriptor.Access |
      Where-Object {
        -not $_.IsInherited -and
        $_.ActiveDirectoryRights -match 'GenericAll|CreateChild|WriteDacl|WriteOwner'
      } | ForEach-Object {
        [PSCustomObject]@{
          OU        = $ou.Name
          Principal = $_.IdentityReference
          Rights    = $_.ActiveDirectoryRights
        }
      }
  } | Format-Table -AutoSize
```

#### Comment corriger

Pour chaque OU signalée, supprimez les autorisations à risque des utilisateurs non administrateurs :

```powershell
$ouDN = "OU=Servers,DC=yourdomain,DC=com"  # Remplacez par votre OU
$path = "AD:$ouDN"
$acl = Get-Acl -Path $path

# Supprimez les droits à risque pour un groupe spécifique
$identity = New-Object System.Security.Principal.NTAccount("YOURDOMAIN", "HelpDeskTeam")
$toRemove = $acl.Access | Where-Object {
  $_.IdentityReference -eq $identity -and
  $_.ActiveDirectoryRights -match 'CreateChild|GenericAll'
}

foreach ($ace in $toRemove) {
  $acl.RemoveAccessRuleSpecific($ace)
}
Set-Acl -Path $path -AclObject $acl
```

## A-AdminSDHolder

#### Ce que cela signifie

Lorsqu'un utilisateur est ajouté à un groupe privilégié dans Active Directory (comme Domain Admins), le système marque automatiquement son compte avec un indicateur appelé `adminCount = 1`. Cet indicateur fait partie d'un mécanisme de protection intégré.

Le problème est : **lorsque vous retirez cet utilisateur du groupe d'administration, l'indicateur n'est PAS effacé automatiquement.** Il reste présent indéfiniment, sauf si vous le supprimez explicitement.

Le scan AD signale les comptes qui ont conservé ce `adminCount` marqueur, mais qui ne sont plus de véritables administrateurs. Cela peut indiquer :

* Un utilisateur qui a été temporairement nommé administrateur et dont le nettoyage n'a pas été complet
* Un risque potentiel pour la sécurité : ces comptes peuvent encore disposer de privilèges élevés dans certaines zones

#### Ce que l’analyse vérifie

Le scan trouve des comptes utilisateur activés où `adminCount = 1` mais le compte n'est actuellement membre d'aucun groupe privilégié.

#### Comment diagnostiquer

```powershell
# Constituez une liste de tous les utilisateurs actuellement privilégiés
$privilegedMembers = @()
@("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators",
  "Account Operators", "Server Operators", "Backup Operators", "Print Operators"
) | ForEach-Object {
  try { $privilegedMembers += (Get-ADGroupMember $_ -Recursive).DistinguishedName } catch {}
}

# Trouvez les comptes avec le marqueur adminCount résiduel
Get-ADUser -LDAPFilter "(&(admincount=1)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" `
  -Properties adminCount |
  Where-Object { $_.DistinguishedName -notin $privilegedMembers } |
  Select-Object SamAccountName, Name
```

#### Comment corriger

Après avoir confirmé que ces comptes ne devraient plus être administrateurs, effacez l'indicateur :

```powershell
# Effacez adminCount pour un utilisateur unique
Set-ADUser -Identity "username" -Clear adminCount

# Ou effacez-le pour tous les utilisateurs non privilégiés d'un coup
Get-ADUser -LDAPFilter "(&(admincount=1)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" |
  Where-Object { $_.DistinguishedName -notin $privilegedMembers } |
  ForEach-Object {
    Set-ADUser -Identity $_ -Clear adminCount
    Write-Host "adminCount effacé pour $($_.SamAccountName)"
  }
```

## P-Kerberoasting

#### Ce que cela signifie

Dans Active Directory, certains comptes sont enregistrés pour exécuter des services tels qu'un SQL Server ou une application web. Ces comptes ont un **Nom principal de service (SPN)**, qui est essentiellement une étiquette qui dit « ce compte exécute un service réseau. »

Le risque de sécurité est : **tout utilisateur authentifié** dans le domaine peut demander un ticket Kerberos pour n’importe quel compte doté d’un SPN. Ce ticket est chiffré avec le mot de passe du compte, et l’attaquant peut ensuite tenter de le craquer hors ligne, sans déclencher la moindre alerte.

Cela s’appelle une **Kerberoasting** attaque. C’est particulièrement dangereux lorsque le compte avec le SPN est aussi un **Administrateur de domaine**, car craquer ce mot de passe signifie un contrôle total du domaine.

#### Ce que l’analyse vérifie

L’AD Scan signale les comptes qui remplissent **les trois** conditions :

1. Le compte est membre d’un **groupe privilégié** (Administrateurs de domaine, Administrateurs d’entreprise, etc.)
2. Le compte possède un **Nom principal de service (SPN)**
3. Le **mot de passe n’a pas été changé depuis plus de 40 jours** (laissant plus de temps aux attaquants pour le craquer)

#### Pourquoi l'alerte peut persister

Vous devez corriger **les trois** conditions. Correctifs incomplets courants :

* **Mot de passe changé mais SPN conservé :** L’alerte disparaît temporairement, mais revient après 40 jours.
* **SPN supprimé, mais le compte est toujours dans les Administrateurs de domaine :** l’alerte disparaît, mais le risque sous-jacent demeure.

#### Comment diagnostiquer

```powershell
$privilegedGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators")
$threshold = (Get-Date).AddDays(-40)

foreach ($group in $privilegedGroups) {
  Get-ADGroupMember -Identity $group -Recursive |
    Where-Object { $_.objectClass -eq "user" } |
    ForEach-Object { Get-ADUser $_ -Properties ServicePrincipalName, PasswordLastSet } |
    Where-Object { $_.ServicePrincipalName.Count -gt 0 -and $_.PasswordLastSet -lt $threshold } |
    Select-Object SamAccountName,
      @{N="Âge du mot de passe (jours)"; E={[math]::Round(((Get-Date) - $_.PasswordLastSet).TotalDays)}},
      @{N="SPN"; E={$_.ServicePrincipalName -join "; "}}
}
```

#### Comment corriger

**La meilleure option : retirer le compte des groupes privilégiés.** Les comptes de service ont rarement besoin d’être des Administrateurs de domaine. Créez un compte dédié, non privilégié, avec uniquement les autorisations dont le service a réellement besoin :

```powershell
Remove-ADGroupMember -Identity "Domain Admins" -Members "svc_account" -Confirm:$false
```

**Si vous ne pouvez pas le retirer du groupe d’administration :** Au minimum, réinitialisez régulièrement le mot de passe (tous les 30 jours ou moins) :

```powershell
Set-ADAccountPassword -Identity "svc_account" `
  -NewPassword (ConvertTo-SecureString "YourNewStr0ngP@ssw0rd!" -AsPlainText -Force) -Reset
```

**Meilleure solution à long terme :** Passez à un **compte de service géré de groupe (gMSA)**, qui fait automatiquement tourner son mot de passe tous les 30 jours :

```powershell
New-ADServiceAccount -Name "gMSA_SQLService" `
  -DNSHostName "gmsa_sqlservice.yourdomain.com" `
  -PrincipalsAllowedToRetrieveManagedPassword "SQLServersGroup"
```

## P-AdminLogin

#### Ce que cela signifie

Chaque domaine Active Directory possède un **compte Administrateur intégré** qui est créé automatiquement lors de la création du domaine. Ce compte a le contrôle total de l’ensemble du domaine et ne peut pas être verrouillé.

En raison de sa puissance et de sa prévisibilité (les attaquants savent qu’il existe toujours), il doit être réservé aux **urgences uniquement**, par exemple pour la reprise après sinistre. L’administration quotidienne doit utiliser des comptes d’administration personnels (p. ex., `adm_john`) afin que les actions puissent être attribuées à des personnes.

#### Ce que l’analyse vérifie

L’AD Scan vérifie si le compte Administrateur intégré s’est connecté à un contrôleur de domaine dans les **35 derniers jours**. Si c’est le cas, l’alerte se déclenche, indiquant que le compte est utilisé pour des tâches courantes au lieu d’être conservé pour les urgences.

#### Pourquoi l'alerte peut persister

* **Renommer le compte n’aide pas.** Le scan identifie l’Administrateur intégré par son identifiant interne (RID-500), et non par son nom.
* **Changer le mot de passe n’aide pas.** Le scan vérifie l’activité de connexion, pas l’âge du mot de passe.
* **Les scripts automatisés ou tâches planifiées** s’exécutant sous le compte Administrateur intégré continueront de déclencher l’alerte.
* **Il suffit d’attendre.** Après avoir cessé d’utiliser le compte, l’alerte disparaît automatiquement au bout de 35 jours.

#### Comment diagnostiquer

```powershell
# Vérifier quand l’Administrateur intégré s’est connecté pour la dernière fois sur chaque contrôleur de domaine
$domainSID = (Get-ADDomain).DomainSID
$adminSID = "$domainSID-500"

Get-ADDomainController -Filter * | ForEach-Object {
  $dc = $_
  $admin = Get-ADUser -Identity $adminSID -Server $dc.HostName -Properties LastLogon
  $lastLogon = [DateTime]::FromFileTime($admin.LastLogon)
  $daysAgo = [math]::Round(((Get-Date) - $lastLogon).TotalDays, 1)

  [PSCustomObject]@{
    DC        = $dc.HostName
    LastLogon = $lastLogon
    DaysAgo   = $daysAgo
    Status    = if ($daysAgo -le 35) { "ALERTE - Utilisé récemment" } else { "OK" }
  }
} | Format-Table -AutoSize
```

Vérifiez également s’il existe des tâches planifiées pouvant utiliser l’Administrateur intégré :

```powershell
Get-ADDomainController -Filter * | ForEach-Object {
  Invoke-Command -ComputerName $_.HostName -ScriptBlock {
    Get-ScheduledTask | Where-Object {
      $_.Principal.UserId -match "Administrator"
    } | Select-Object TaskName, @{N="Exécuté en tant que"; E={$_.Principal.UserId}}
  }
}
```

#### Comment corriger

1. **Créez des comptes d’administration personnels** pour chaque administrateur (p. ex., `adm_john`, `adm_jane`)
2. **Mettez à jour toutes les tâches planifiées** pour qu’elles utilisent un compte de service dédié au lieu de l’Administrateur intégré
3. **Cessez de vous connecter** avec l’Administrateur intégré pour les tâches courantes
4. L’alerte disparaîtra automatiquement **35 jours** après la dernière connexion

## P-AdminNum

#### Ce que cela signifie

Plus votre domaine comporte de comptes dotés de privilèges administrateur, plus la surface d’attaque est grande. Chaque compte d’admin est un point d’entrée potentiel pour un attaquant. Beaucoup d’organisations finissent par accumuler trop de comptes d’administration au fil du temps : accès temporaire jamais révoqué, comptes de service ajoutés aux Administrateurs de domaine par commodité, etc.

#### Ce que l’analyse vérifie

L’AD Scan compte le nombre total de **utilisateurs uniques** dans tous les groupes privilégiés (Administrateurs de domaine, Administrateurs d’entreprise, Administrateurs, Opérateurs de compte, Opérateurs de serveur, Opérateurs de sauvegarde, etc.). Si le même utilisateur appartient à plusieurs groupes, il n’est compté qu’une seule fois.

L’alerte se déclenche si :

* Plus de **10%** des utilisateurs actifs sont privilégiés, OU
* Plus de **50** des comptes privilégiés existent

> Cette vérification est ignorée pour les petites organisations ayant moins de 100 utilisateurs actifs.

#### Comment diagnostiquer

```powershell
$privilegedGroups = @(
  "Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators",
  "Account Operators", "Server Operators", "Backup Operators", "Print Operators"
)

$uniqueMembers = @{}
foreach ($group in $privilegedGroups) {
  try {
    Get-ADGroupMember -Identity $group -Recursive |
      Where-Object { $_.objectClass -eq "user" } |
      ForEach-Object { $uniqueMembers[$_.DistinguishedName] = $_.SamAccountName }
  } catch {}
}

$activeUsers = (Get-ADUser -Filter "Enabled -eq `$true" | Measure-Object).Count
$pct = [math]::Round(($uniqueMembers.Count / $activeUsers) * 100, 1)

Write-Host "Comptes privilégiés : $($uniqueMembers.Count)"
Write-Host "Utilisateurs actifs : $activeUsers"
Write-Host "Ratio : $pct% (alerte si >10 % ou >50 comptes)"
Write-Host ""
$uniqueMembers.Values | Sort-Object | ForEach-Object { Write-Host "  - $_" }
```

#### Comment corriger

Examinez la liste et supprimez les comptes qui n’ont pas réellement besoin d’un accès administrateur :

```powershell
Remove-ADGroupMember -Identity "Domain Admins" -Members "username" -Confirm:$false
```

Bonnes pratiques :

* Utilisez **des comptes d’administration séparés** (`adm_john`) distincts des comptes utilisés au quotidien
* **Retirez les comptes de service** des groupes d’administration, en leur accordant uniquement les autorisations spécifiques dont ils ont besoin
* **Examinez l’appartenance aux groupes privilégiés** régulièrement

## P-ProtectedUsers

#### Ce que cela signifie

Le **Protected Users** est un groupe de sécurité spécial introduit dans Windows Server 2012 R2. Les membres de ce groupe bénéficient de protections supplémentaires :

* Ils peuvent **s’authentifier uniquement avec Kerberos** (le protocole le plus sûr), et non avec l’ancien protocole NTLM
* Leurs **identifiants ne sont pas mis en cache** sur les machines où ils se connectent : un attaquant qui compromet un poste de travail ne peut pas voler leurs identifiants depuis la mémoire
* **La délégation est désactivée :** leur compte ne peut pas être usurpé par des services

Ces protections sont cruciales pour les comptes d’administrateur, qui sont les cibles principales de la plupart des attaques.

#### Ce que l’analyse vérifie

L’AD Scan vérifie que tous les **comptes d’administration activés** (membres des Administrateurs de domaine, Administrateurs d’entreprise, etc.) sont également membres du **Protected Users** groupe.

#### Pourquoi l'alerte peut persister

* **Les utilisateurs ajoutés via des groupes imbriqués** peuvent ne pas être détectés. Ajoutez les utilisateurs **directement** au groupe Utilisateurs protégés.
* **Les retards de réplication** entre les contrôleurs de domaine peuvent provoquer des incohérences temporaires.
* **Les comptes de service gérés (gMSA)** sont exclus de cette vérification : ils n’ont pas besoin d’être dans Utilisateurs protégés.

#### Comment diagnostiquer

```powershell
$protectedUsers = (Get-ADGroupMember -Identity "Protected Users").DistinguishedName
$privilegedGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators")

$notProtected = foreach ($group in $privilegedGroups) {
  Get-ADGroupMember -Identity $group -Recursive |
    Where-Object { $_.objectClass -eq "user" } |
    ForEach-Object { Get-ADUser $_ -Properties Enabled } |
    Where-Object { $_.Enabled -and $_.DistinguishedName -notin $protectedUsers }
}

$notProtected | Select-Object -Unique SamAccountName, Name | Format-Table -AutoSize
```

#### Comment corriger

```powershell
Add-ADGroupMember -Identity "Protected Users" -Members "adm_john", "adm_jane"
```

> **Important :** Ajouter des comptes à Utilisateurs protégés impose **une authentification Kerberos uniquement**. Certaines applications héritées nécessitant NTLM peuvent cesser de fonctionner pour ces comptes. **Testez d’abord avec un seul compte** avant d’ajouter tous les administrateurs.
>
> Bonne pratique : les comptes d’administration doivent être utilisés **uniquement pour des tâches d’administration** (et non pour les e-mails, la navigation Web ou l’exécution d’applications métier), donc la compatibilité NTLM est rarement un problème.

## S-OldNtlm

#### Ce que cela signifie

Windows prend en charge plusieurs protocoles d’authentification, des plus anciens et non sécurisés (LM, NTLMv1) aux plus modernes et sécurisés (NTLMv2, Kerberos). Les anciens protocoles présentent des vulnérabilités connues que les attaquants peuvent exploiter pour intercepter et craquer des mots de passe sur le réseau.

Le **Le niveau d’authentification LAN Manager** détermine quels protocoles sont autorisés. Il doit être défini sur **le niveau 5**, c’est-à-dire « n’accepter que NTLMv2, refuser tous les anciens protocoles. »

#### Ce que l’analyse vérifie

L’AD Scan lit les objets de stratégie de groupe (GPO) pour vérifier que le `LmCompatibilityLevel` paramètre est défini sur **5**. Si aucune GPO ne définit ce paramètre, Windows utilise par défaut le **niveau 3**, qui accepte encore certains protocoles plus faibles.

| Niveau | Ce qu’il autorise                                  | Sécurisé ? |
| ------ | -------------------------------------------------- | ---------- |
| 0-2    | LM et/ou NTLMv1                                    | Non        |
| 3      | NTLMv2 (mais ne refuse pas les anciens protocoles) | Non        |
| **5**  | **NTLMv2 uniquement, refuser LM et NTLMv1**        | **Oui**    |

#### Pourquoi l'alerte peut persister

1. **Vous avez modifié directement le registre** au lieu d’utiliser une GPO. L’AD Scan lit les fichiers GPO, pas les paramètres du registre local. Même si le contrôleur de domaine a la bonne valeur dans le registre, l’alerte persiste si elle n’a pas été définie via la stratégie de groupe.
2. **GPO conflictuels :** Une GPO définit le niveau 5, mais une autre GPO l’écrase avec un niveau plus bas.
3. **Aucune GPO du tout :** Sans aucune GPO, la valeur par défaut est le niveau 3 (non sécurisé).

#### Comment diagnostiquer

```powershell
# Vérifier le paramètre effectif sur chaque contrôleur de domaine
Get-ADDomainController -Filter * | ForEach-Object {
  $level = Invoke-Command -ComputerName $_.HostName -ScriptBlock {
    (Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" `
      -Name LmCompatibilityLevel -ErrorAction SilentlyContinue).LmCompatibilityLevel
  }
  Write-Host "$($_.HostName): LmCompatibilityLevel = $level"
}

# Vérifier quelles GPO définissent ce paramètre
Import-Module GroupPolicy
Get-GPO -All | ForEach-Object {
  [xml]$r = Get-GPOReport -Guid $_.Id -ReportType Xml
  if ($r.InnerXml -match "LmCompatibilityLevel") {
    Write-Host "GPO : $($_.DisplayName)"
  }
}
```

#### Comment corriger

**Via la console de gestion des stratégies de groupe (recommandé) :**

1. Ouvrez `gpmc.msc`
2. Modifiez la GPO liée à `OU=Contrôleurs de domaine`
3. Accédez à : `Configuration ordinateur > Stratégies > Paramètres Windows > Paramètres de sécurité > Stratégies locales > Options de sécurité`
4. Définissez **"Sécurité réseau : niveau d’authentification LAN Manager"** sur `Envoyer uniquement la réponse NTLMv2. Refuser LM et NTLM`
5. Définissez **"Sécurité réseau : ne pas stocker la valeur de hachage LAN Manager lors du prochain changement de mot de passe"** sur `Activé`
6. Exécutez `gpupdate /force` sur tous les contrôleurs de domaine

**Via PowerShell :**

```powershell
$gpoName = "DC - Enforce NTLMv2"
$gpo = Get-GPO -Name $gpoName -ErrorAction SilentlyContinue
if (-not $gpo) { $gpo = New-GPO -Name $gpoName }

Set-GPRegistryValue -Name $gpoName `
  -Key "HKLM\System\CurrentControlSet\Control\Lsa" `
  -ValueName "LmCompatibilityLevel" -Type DWord -Value 5

Set-GPRegistryValue -Name $gpoName `
  -Key "HKLM\System\CurrentControlSet\Control\Lsa" `
  -ValueName "NoLMHash" -Type DWord -Value 1

New-GPLink -Name $gpoName `
  -Target "OU=Domain Controllers,$($(Get-ADDomain).DistinguishedName)" `
  -LinkEnabled Yes
```

## S-AesNotEnabled

#### Ce que cela signifie

Lorsque vous vous authentifiez dans Active Directory, votre mot de passe est utilisé pour chiffrer les communications à l’aide d’un algorithme spécifique. Les algorithmes plus anciens (**DES**, **RC4**) sont faibles et peuvent être craqués relativement facilement. Les algorithmes modernes (**AES-128**, **AES-256**) sont beaucoup plus robustes.

La prise en charge d’AES a été introduite avec Windows Server 2008. Cependant, les comptes qui existaient avant la mise à niveau, ou les comptes avec des configurations particulières, peuvent encore utiliser l’ancien chiffrement plus faible.

#### Ce que l’analyse vérifie

Un compte est signalé dans deux situations :

1. **Le mot de passe du compte a été défini avant la mise à niveau de votre domaine vers Server 2008.** Comme les clés de chiffrement AES ne sont générées que lorsqu’un mot de passe est défini sur un contrôleur de domaine récent, ces anciens mots de passe ne disposent que de clés RC4/DES faibles.
2. **Le compte possède un Service Principal Name (SPN)** et ses paramètres de chiffrement n’incluent pas AES (les `msDS-SupportedEncryptionTypes` indicateurs AES sont absents de l’attribut msDS-SupportedEncryptionTypes).

#### Comment diagnostiquer

```powershell
# Trouver les comptes de service sans prise en charge d’AES
Get-ADUser -Filter 'ServicePrincipalName -like "*"' `
  -Properties ServicePrincipalName, "msDS-SupportedEncryptionTypes", PasswordLastSet |
  Where-Object { ([int]$_."msDS-SupportedEncryptionTypes" -band 24) -eq 0 } |
  Select-Object SamAccountName,
    @{N="TypesDeChiffrement"; E={$_."msDS-SupportedEncryptionTypes"}},
    DernièreDéfinitionDuMotDePasse

# Idem pour les comptes ordinateurs
Get-ADComputer -Filter 'ServicePrincipalName -like "*"' `
  -Properties "msDS-SupportedEncryptionTypes" |
  Where-Object { ([int]$_."msDS-SupportedEncryptionTypes" -band 24) -eq 0 } |
  Select-Object Name, @{N="TypesDeChiffrement"; E={$_."msDS-SupportedEncryptionTypes"}}
```

#### Comment corriger

**Pour les comptes avec d’anciens mots de passe :** Réinitialisez simplement le mot de passe. Cela génère de nouvelles clés AES :

```powershell
Set-ADAccountPassword -Identity "svc_account" `
  -NewPassword (ConvertTo-SecureString "YourNewStr0ngP@ssw0rd!" -AsPlainText -Force) -Reset
```

**Pour les comptes dont les paramètres de chiffrement AES sont absents :** Activez AES dans les types de chiffrement du compte :

```powershell
# Activer AES pour un compte spécifique (24 = AES-128 + AES-256)
Set-ADUser -Identity "svc_account" -Replace @{"msDS-SupportedEncryptionTypes" = 24}

# Pour un compte ordinateur
Set-ADComputer -Identity "server01" -Replace @{"msDS-SupportedEncryptionTypes" = 24}

# Correction en masse pour tous les comptes de service sans AES
Get-ADUser -Filter 'ServicePrincipalName -like "*"' `
  -Properties "msDS-SupportedEncryptionTypes" |
  Where-Object { ([int]$_."msDS-SupportedEncryptionTypes" -band 24) -eq 0 } |
  ForEach-Object {
    Set-ADUser $_ -Replace @{"msDS-SupportedEncryptionTypes" = 24}
    Write-Host "AES activé pour $($_.SamAccountName)"
  }
```

> **Remarque :** L’activation d’AES n’est pas destructive : l’authentification existante continue de fonctionner. Toutefois, testez avec les services critiques avant de l’appliquer en masse.

## A-NoGPOLLMNR

#### Ce que cela signifie

**LLMNR** (Link-Local Multicast Name Resolution) est un protocole que Windows utilise pour trouver d’autres ordinateurs sur le réseau lorsque DNS n’a pas la réponse. Il fonctionne en diffusant une question à toutes les machines voisines : « Quelqu’un sait-il où `servername` se trouve servername ? »

Le problème est qu’un attaquant sur le même réseau peut **répondre à ces diffusions en se faisant passer pour le serveur cible**, trompant ainsi la victime et la poussant à envoyer ses identifiants à l’attaquant. Cela s’appelle une **poisoning LLMNR** et c’est l’une des techniques les plus courantes lors des attaques sur le réseau interne.

LLMNR est un protocole hérité dont les réseaux modernes n’ont pas besoin (DNS gère tout). Il doit être désactivé via la stratégie de groupe.

#### Ce que l’analyse vérifie

L’AD Scan recherche une **GPO activée et liée** qui désactive LLMNR en définissant la valeur de registre `EnableMulticast` à `0`.

#### Pourquoi l'alerte peut persister

1. **La GPO existe mais n’est pas liée** à aucune OU.
2. **La GPO est désactivée**, même si elle est liée.
3. **LLMNR a été désactivé manuellement** (via le registre ou `netsh`) mais pas via la stratégie de groupe. L’AD Scan lit les fichiers GPO, pas les paramètres de la machine locale.

#### Comment diagnostiquer

```powershell
Import-Module GroupPolicy
Get-GPO -All | ForEach-Object {
  [xml]$r = Get-GPOReport -Guid $_.Id -ReportType Xml
  if ($r.InnerXml -match "EnableMulticast") {
    Write-Host "GPO '$($_.DisplayName)' - État : $($_.GpoStatus) - Contient le paramètre LLMNR"
  }
}
```

#### Comment corriger

```powershell
$gpoName = "Disable LLMNR"
$gpo = Get-GPO -Name $gpoName -ErrorAction SilentlyContinue
if (-not $gpo) { $gpo = New-GPO -Name $gpoName }

Set-GPRegistryValue -Name $gpoName `
  -Key "HKLM\Software\Policies\Microsoft\Windows NT\DNSClient" `
  -ValueName "EnableMulticast" -Type DWord -Value 0

# Lier à la racine du domaine afin qu’elle s’applique à tous les ordinateurs
New-GPLink -Name $gpoName `
  -Target (Get-ADDomain).DistinguishedName `
  -LinkEnabled Yes
```

Après avoir lié la GPO, exécutez `gpupdate /force` sur les machines ou attendez le prochain cycle d’actualisation de la stratégie de groupe (généralement 90 minutes).

## Foire aux questions

#### L’alerte s’affiche toujours après avoir appliqué la correction. Pourquoi ?

L’AD Scan ne s’exécute pas périodiquement. Après avoir appliqué une correction, vous devez **relancer le script** pour que l’alerte disparaisse. Si l’alerte persiste après une nouvelle analyse, la correction était probablement partielle. Reportez-vous à la section "Why the alert may persist" de la vulnérabilité concernée. Assurez-vous de lire les détails de la vulnérabilité dans votre rapport ; ils contiennent souvent des informations sur les actifs impactés.

#### Ai-je besoin des droits Domain Admin pour lancer l’analyse ?

Certaines vulnérabilités (p. ex., A-NoServicePolicy) nécessitent des privilèges élevés pour lire certains objets AD. L’exécution de l’analyse avec un **compte Domain Admin** garantit que tous les objets sont visibles et évite les fausses alertes causées par des autorisations insuffisantes. Si ce n’est pas possible, vous pouvez toujours exécuter le script en tant que simple utilisateur du domaine, même si certaines vulnérabilités peuvent apparaître en raison d’une visibilité insuffisante sur les objets AD.

#### J’ai corrigé une vulnérabilité, mais une nouvelle est apparue. Est-ce normal ?

Oui. Certaines corrections peuvent révéler d’autres problèmes. Par exemple, l’installation de LAPS (corrigeant A-LAPS-Not-Installed) peut déclencher A-LAPS-Joined-Computers si les objets ordinateur disposent de permissions inappropriées. C’est normal : traitez chaque alerte dans l’ordre de gravité.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.stoik.io/cyber-best-practices/fr/guides-de-remediation-des-vulnerabilites/ad-scan-vulnerability-remediation-guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
