> 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/anomalies.md).

# Anomalies

## A-LAPS-Non-Installé

#### 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** (solution de mot de passe d’administrateur local) 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

L’AD Scan recherche des indices montrant 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 sur site), l’AD Scan ne peut pas le détecter. L’analyse ne consulte que votre Active Directory local.
* **LAPS a été partiellement installé :** La configuration de LAPS a peut-être été commencée mais pas terminée.

#### Comment diagnostiquer

```powershell
# Vérifier 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 renvoie aucun résultat, LAPS n’est pas installé.

#### Comment corriger

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

1. Ouvrir `gpmc.msc` (Gestion de la stratégie de groupe)
2. Modifiez ou créez un GPO lié aux UO de vos 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 Legacy LAPS depuis Microsoft et exécutez l’extension du schéma :

```powershell
Update-LapsADSchema
```

> **Remarque :** Si vous gérez les mots de passe des administrateurs 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-Ordinateurs-Joints

#### 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 le suivant : lorsque LAPS est installé, le mot de passe de l’administrateur local est stocké sur ce même objet ordinateur. Si le créateur conserve les autorisations appropriées, il peut **lire le mot de passe LAPS**, même s’il n’est pas administrateur. Cela signifie qu’un utilisateur standard qui a un jour joint un PC au domaine pourrait récupérer le mot de passe de l’administrateur local de cette machine.

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

Pour chaque ordinateur activé avec LAPS déployé, l’AD Scan 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’accorder 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` (ce qui permet de lire le mot de passe LAPS), `WriteDacl` (ce qui permet de modifier les autorisations), `WriteOwner` (ce 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 : **changer 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 l’AD Scan vérifie aussi les autorisations résiduelles (appelées ACE, ou Access Control Entries) 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
# Lister les ordinateurs où le créateur a encore des 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]@{
        Ordinateur       = $comp.Name
        CréateurEstPropriétaire = $isOwner
        DroitsÀRisque    = ($riskyAces | ForEach-Object { $_.ActiveDirectoryRights }) -join ", "
      }
    }
  } | Format-Table -AutoSize
```

#### Comment corriger

Vous devez faire **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) : suppression de [$($ace.ActiveDirectoryRights)] pour $($ace.IdentityReference)"
  }

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

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

## A-AucunePolitiqueDeService

#### 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 de grande valeur : ils disposent souvent de privilèges élevés et leurs mots de passe changent rarement.

Une **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. L’AD Scan s’attend à ce que vos comptes de service soient couverts par une PSO imposant des mots de passe d’au moins **20 caractères**, ce qui les rend beaucoup plus difficiles à craquer.

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

L’AD Scan recherche au moins une politique 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 d’analyse n’a pas l’autorisation de lire la PSO.** Les politiques 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 l’analyse s’exécute avec un compte moins privilégié, elle 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
# Lister toutes les stratégies de mot de passe à granularité fine et leurs paramètres
Get-ADFineGrainedPasswordPolicy -Filter * |
  Select-Object Name, MinPasswordLength, @{N="AppliquéeÀ"; 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 d’exécuter la commande avec un compte Domain Admin.

#### Comment corriger

**Si la PSO existe mais que l’analyse ne peut pas la voir :** Exécutez l’AD Scan avec un compte Domain Admin.

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

```powershell
# Créer une politique 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

# L’attribuer à 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 ne force pas immédiatement les changements de mot de passe. Les mots de passe existants continueront de fonctionner jusqu’à leur expiration ou jusqu’à leur réinitialisation manuelle. À partir de ce moment, la nouvelle longueur minimale de 20 caractères s’appliquera.

## A-AuditDC

#### Ce que cela signifie

**Les politiques d’audit** déterminent quels événements sont consignés sur vos contrôleurs de domaine. Sans une journalisation appropriée, des attaques comme le vol d’identifiants, des changements de groupe non autorisés ou un abus de réplication (DCSync) peuvent se produire sans laisser de trace dans les journaux.

L’AD Scan vérifie que vos contrôleurs de domaine sont configurés pour enregistrer les événements de sécurité les plus importants.

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

L’analyse 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 enregistre                                                      |
| ----------------------------------------------- | -------------------------------------------------------------------------- |
| Service d’authentification Kerberos             | Tentatives de connexion via Kerberos                                       |
| Opérations sur les tickets de service Kerberos  | Requêtes de tickets de service (détecte le Kerberoasting)                  |
| Gestion des comptes d’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, 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 lancés (détecte les outils malveillants)                |
| Ouverture/fermeture de session                  | Connexions interactives et à distance                                      |
| Ouverture de session spéciale                   | Ouvertures de session 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. **Paramètres appliqués via `auditpol` directement sur le contrôleur de domaine** ne sont pas détectés. L’AD Scan lit les fichiers de stratégie de groupe, pas la configuration locale du contrôleur de domaine. Vous devez utiliser un GPO.
2. **GPO en conflit :** Un GPO active le paramètre, mais un autre GPO de priorité plus élevée le désactive.
3. **GPO non lié à l’unité d’organisation Domain Controllers :** Le GPO existe mais est lié à une autre UO.

#### Comment diagnostiquer

```powershell
# Vérifier 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’une substitution locale) :

```powershell
# Vérifier quels GPO sont liés à l’unité d’organisation Domain Controllers
Get-GPInheritance -Target "OU=Domain Controllers,$($(Get-ADDomain).DistinguishedName)"
```

#### Comment corriger

1. Ouvrir `gpmc.msc` (Console de gestion des stratégies de groupe)
2. Créez ou modifiez un GPO lié à `OU=Domain Controllers`
3. Accédez à : `Configuration ordinateur > Stratégies > Paramètres Windows > Paramètres de sécurité > Configuration avancée de la stratégie d’audit > Stratégies d’audit`
4. Activer **Réussite 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-MauvaisSuccesseur

#### 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
* Une **la clé racine KDS** (requise pour les comptes de service gérés)
* un utilisateur non administrateur a le droit de créer des objets dans une UO

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

L’AD Scan recherche les utilisateurs ou groupes non privilégiés qui ont l’autorisation de créer ou de contrôler des objets dMSA dans n’importe quelle UO, tels que `CreateChild`, `GenericAll`, `WriteDacl`, ou `WriteOwner`.

#### Pourquoi l’alerte peut persister

* La correction doit être appliquée à **toutes** les UO concernées, pas seulement à une.
* Les autorisations héritées des UO parentes s’appliquent toujours aux UO enfants.
* Les groupes d’administration personnalisés peuvent ne pas être reconnus comme « privilégiés » par l’analyse.

#### Comment diagnostiquer

```powershell
# Vérifier les prérequis
Get-KdsRootKey  # La clé racine KDS doit exister pour que l’attaque soit possible

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

# Trouver les UO avec des délégations risquées
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]@{
          UO        = $ou.Name
          Principal = $_.IdentityReference
          Droits    = $_.ActiveDirectoryRights
        }
      }
  } | Format-Table -AutoSize
```

#### Comment corriger

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

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

# Supprimer 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 le suivant : **lorsque vous retirez cet utilisateur du groupe admin, l’indicateur n’est PAS automatiquement supprimé.** Il reste indéfiniment, sauf si vous le supprimez explicitement.

L’AD Scan signale les comptes qui conservent ce `adminCount` résiduel mais ne sont plus de véritables administrateurs. Cela peut indiquer :

* Un utilisateur qui a été temporairement administrateur et dont le nettoyage a été incomplet
* 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

L’analyse trouve des comptes utilisateur activés pour lesquels `adminCount = 1` mais le compte n’est actuellement membre d’aucun groupe privilégié.

#### Comment diagnostiquer

```powershell
# Construire une liste de tous les utilisateurs privilégiés actuels
$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 {}
}

# Trouver les comptes avec l’indicateur 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 doivent plus être administrateurs, supprimez l’indicateur :

```powershell
# Supprimer adminCount pour un seul utilisateur
Set-ADUser -Identity "username" -Clear adminCount

# Ou le supprimer en une fois pour tous les utilisateurs non privilégiés
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 supprimé pour $($_.SamAccountName)"
  }
```

## A-AucunGPOLLMNR

#### 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 à proximité : « Quelqu’un sait où se trouve `servername` ? »

Le problème est le suivant : 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 pour qu’elle envoie ses identifiants à l’attaquant. C’est ce qu’on appelle une **attaque par empoisonnement LLMNR** et c’est l’une des techniques les plus couramment utilisées lors des attaques internes sur le réseau.

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 un **GPO activé et lié** qui désactive LLMNR en définissant la valeur du registre `EnableMulticast` à `0`.

#### Pourquoi l’alerte peut persister

1. **Le GPO existe mais n’est pas lié** à aucune UO.
2. **Le GPO est désactivé**, même s’il est lié.
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 locaux de la machine.

#### 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 = "Désactiver 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

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

Après avoir lié le 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).


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
