---
title: "Hardening Active Directory — Tier Model & LAPS"
domain: security
subdomain: hardening
type: snippet
tags: [hardening, active-directory, tier-model, laps, privileged-access, kerberos, paw, security]
difficulty: advanced
status: stable
updated: "2025-05-14"
---
## Modèle de tiering Microsoft

| Tier | Périmètre | Comptes | Exemples de systèmes |
|---|---|---|---|
| **Tier 0** | Contrôle de l'identité | Domain Admins, Enterprise Admins, Schema Admins | DC, PKI, ADFS, Azure AD Connect, PAM tools |
| **Tier 1** | Serveurs d'entreprise | Admins serveurs, comptes de service | Serveurs membres, SQL, Exchange, IIS |
| **Tier 2** | Postes de travail | Helpdesk, admins locaux | Postes utilisateurs, laptops |

**Règle fondamentale** : jamais d'authentification descendante. Un compte Tier 0 ne s'authentifie jamais sur un système Tier 1 ou Tier 2. Une compromission d'un poste Tier 2 ne doit pas permettre l'accès aux credentials Tier 0.

```powershell
# Créer les OUs par tier
New-ADOrganizationalUnit -Name "Tier0-Accounts" -Path "OU=Admin,DC={{DOMAIN}},DC={{TLD}}"
New-ADOrganizationalUnit -Name "Tier1-Accounts" -Path "OU=Admin,DC={{DOMAIN}},DC={{TLD}}"
New-ADOrganizationalUnit -Name "Tier2-Accounts" -Path "OU=Admin,DC={{DOMAIN}},DC={{TLD}}"

# Convention de nommage des comptes admin dédiés
# adm-t0-john  → accès Tier 0 (DC, PKI)
# adm-t1-john  → accès Tier 1 (serveurs membres)
# adm-t2-john  → accès Tier 2 (postes)
# john         → compte utilisateur standard (email, web, etc.)
```

**PAW (Privileged Access Workstation)** : poste dédié par tier, durci, sans accès Internet, utilisé exclusivement pour les tâches d'administration. Ne jamais administrer depuis le poste utilisateur standard.

<Warning>
La séparation en tiers est inefficace si les comptes Tier 0 se connectent interactivement (RDP, console) sur des systèmes Tier 1/2 — les credentials sont mis en cache LSASS et récupérables par Mimikatz. Utiliser uniquement des connexions non-interactives (WinRM, PSRemoting sans CredSSP) depuis les PAW dédiés.
</Warning>

## Comptes privilégiés

```powershell
# Désactiver le compte Administrator intégré (SID -500)
# OU le renommer si désactivation impossible (compte de récupération)
Disable-ADAccount -Identity "Administrator"

# Vérifier les membres des groupes hautement privilégiés
Get-ADGroupMember "Domain Admins" -Recursive | Select-Object Name, SamAccountName, ObjectClass
Get-ADGroupMember "Enterprise Admins" -Recursive | Select-Object Name, SamAccountName
Get-ADGroupMember "Schema Admins" -Recursive | Select-Object Name, SamAccountName
Get-ADGroupMember "Administrators" -Recursive | Select-Object Name, SamAccountName

# Comptes Tier 0 — ne doivent pas avoir de boîte mail ni accès Internet
# Vérifier qu'ils n'ont pas de SPN (vulnérabilité Kerberoasting)
Get-ADUser -Filter {AdminCount -eq 1 -and ServicePrincipalName -ne "$null"} |
  Select-Object SamAccountName, ServicePrincipalName
```

### Protected Users Security Group

```powershell
# Ajouter les comptes Tier 0 au groupe Protected Users
# Effet : désactive NTLM, RC4 Kerberos, credential caching, délégation Kerberos
Add-ADGroupMember -Identity "Protected Users" -Members "adm-t0-john","adm-t0-jane"

# Vérifier les membres
Get-ADGroupMember "Protected Users" | Select-Object Name, SamAccountName

# ATTENTION : tester en audit avant déploiement massif
# Les services qui utilisent NTLM ou RC4 vont casser
```

### Authentication Policy Silos

```powershell
# Créer un silo pour restreindre où les comptes Tier 0 peuvent s'authentifier
New-ADAuthenticationPolicySilo -Name "Tier0-Silo" `
  -Description "Restreint les comptes Tier 0 aux PAW uniquement" `
  -UserAuthenticationPolicy (
    New-ADAuthenticationPolicy -Name "Tier0-UserPolicy" `
      -UserAllowedToAuthenticateFrom "O:SYG:SYD:(XA;OICI;CR;;;WD;(@USER.ad://ext/AuthenticationSilo == `"Tier0-Silo`"))"
  )

# Assigner des comptes au silo
Grant-ADAuthenticationPolicySiloAccess -Identity "Tier0-Silo" -Account "adm-t0-john"
Set-ADUser -Identity "adm-t0-john" -AuthenticationPolicySilo "Tier0-Silo"
```

## LAPS — Local Administrator Password Solution

```powershell
# LAPS v2 natif (Windows LAPS — disponible Windows Server 2022 / Win 11 22H2+)
# Prérequis : Windows LAPS est intégré nativement, pas d'install nécessaire

# Étendre le schéma AD pour LAPS v2
Update-LapsADSchema

# Configurer les permissions — les ordinateurs peuvent écrire leur propre mot de passe
Set-LapsADComputerSelfPermission -Identity "OU=Workstations,DC={{DOMAIN}},DC={{TLD}}"
Set-LapsADComputerSelfPermission -Identity "OU=Servers,DC={{DOMAIN}},DC={{TLD}}"

# Configurer qui peut lire les mots de passe
Set-LapsADReadPasswordPermission -Identity "OU=Workstations,DC={{DOMAIN}},DC={{TLD}}" `
  -AllowedPrincipals "{{DOMAIN}}\Helpdesk-L1","{{DOMAIN}}\Server-Admins"

# Déploiement via GPO :
# Computer Configuration > Administrative Templates > System > LAPS
# Enable local admin password management = Enabled
# Backup directory = Active Directory
# Password Settings : complexité élevée, longueur 20+, rotation 30 jours

# Lire le mot de passe d'un ordinateur (nécessite droits de lecture)
Get-LapsADPassword -Identity "{{COMPUTER_NAME}}" -AsPlainText

# Historique des mots de passe LAPS
Get-LapsADPassword -Identity "{{COMPUTER_NAME}}" -AsPlainText -IncludeHistory
```

```powershell
# LAPS v1 legacy (si Windows Server < 2022)
# Import-Module AdmPwd.PS

# Étendre le schéma
Update-AdmPwdADSchema

# Permissions
Set-AdmPwdComputerSelfPermission -OrgUnit "OU=Workstations,DC={{DOMAIN}},DC={{TLD}}"

# Lecture
Get-AdmPwdPassword -ComputerName "{{COMPUTER_NAME}}" | Select-Object Password, ExpirationTimestamp
```

## Kerberos Hardening

```powershell
# Désactiver RC4-HMAC sur les comptes utilisateurs, forcer AES256
# Sur tous les comptes (opération longue en prod — faire par batches)
Get-ADUser -Filter * -Properties KerberosEncryptionType | Where-Object {
  $_.KerberosEncryptionType -band 4  # 4 = RC4 activé
} | ForEach-Object {
  Set-ADUser -Identity $_ -KerberosEncryptionType AES256
  Write-Host "RC4 désactivé pour $($_.SamAccountName)"
}

# Kerberos Armoring (FAST) — protège contre AS-REP Roasting
# GPO : Computer Configuration > Administrative Templates > System > Kerberos
# Enable: Kerberos client support for claims, compound authentication and Kerberos armoring
# Enable: Fail authentication requests when Kerberos armoring is not available

# Paramètres de durée des tickets (Default Domain Policy)
# MaxTicketAge = 10 heures (défaut 10h — OK)
# MaxRenewAge = 7 jours (défaut 7j — OK)
# MaxServiceAge = 600 minutes (défaut 600 — OK)

# Vérifier les paramètres Kerberos actuels
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() |
  Select-Object -ExpandProperty DomainControllers | ForEach-Object {
    Get-ADDefaultDomainPasswordPolicy
  }
```

### SPN Scanning — Réduire la surface Kerberoasting

```powershell
# Lister tous les comptes avec SPN (cibles potentielles de Kerberoasting)
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} `
  -Properties ServicePrincipalName, PasswordLastSet, AdminCount |
  Select-Object SamAccountName, ServicePrincipalName, PasswordLastSet, AdminCount |
  Sort-Object PasswordLastSet

# Comptes de service avec SPN et mot de passe ancien (> 90 jours)
$cutoff = (Get-Date).AddDays(-90)
Get-ADUser -Filter {ServicePrincipalName -ne "$null" -and PasswordLastSet -lt $cutoff} `
  -Properties ServicePrincipalName, PasswordLastSet |
  Select-Object SamAccountName, PasswordLastSet, ServicePrincipalName

# Recommandation : utiliser des Managed Service Accounts (MSA/gMSA)
# gMSA = mot de passe 240 bits géré automatiquement par AD, rotation toutes les 30 jours
New-ADServiceAccount -Name "svc-webapp" -DNSHostName "webapp.{{DOMAIN}}.{{TLD}}" `
  -PrincipalsAllowedToRetrieveManagedPassword "WebApp-Servers"
```

## Audit et détection AD

```powershell
# Activer l'audit avancé via Default Domain Controllers Policy
# Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration

# Categories clés sur les DC :
# - Account Logon > Kerberos Authentication Service : Success, Failure
# - Account Logon > Kerberos Service Ticket Operations : Success, Failure
# - Account Management > Security Group Management : Success
# - Account Management > User Account Management : Success, Failure
# - DS Access > Directory Service Changes : Success
# - Logon/Logoff > Logon : Success, Failure

# Event IDs AD critiques
# 4662 : Opération sur un objet AD (inclut modification AdminSDHolder)
# 4728 : Ajout à un groupe global de sécurité
# 4732 : Ajout à un groupe local de sécurité
# 4756 : Ajout à un groupe universel de sécurité
# 4769 : Demande de ticket Kerberos (surveiller RC4 : encryption type 0x17)
# 4771 : Échec pre-auth Kerberos (force brute, AS-REP Roasting)
# 5136 : Modification d'un objet AD

# Détecter les demandes Kerberoasting (RC4 dans les TGS)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4769} |
  Where-Object { $_.Properties[5].Value -eq '0x17' } |  # 0x17 = RC4
  Select-Object TimeCreated, @{n='User';e={$_.Properties[0].Value}},
    @{n='Service';e={$_.Properties[2].Value}} |
  Sort-Object TimeCreated -Descending | Select-Object -First 20
```

## Délégation Kerberos

```powershell
# Auditer les comptes avec délégation non contrainte (dangereux)
# La délégation non contrainte permet d'usurper n'importe quel compte qui s'y connecte
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation |
  Select-Object Name, TrustedForDelegation | Where-Object {$_.Name -notlike "*DC*"}
# Les DC ont légitimement TrustedForDelegation — tout le reste est suspect

Get-ADUser -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation |
  Select-Object SamAccountName, TrustedForDelegation

# Supprimer la délégation non contrainte (sauf DC)
Set-ADComputer -Identity "{{COMPUTER_NAME}}" -TrustedForDelegation $false

# Vérifier la délégation contrainte (KCD — moins dangereuse)
Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} `
  -Properties msDS-AllowedToDelegateTo, SamAccountName |
  Select-Object SamAccountName, "msDS-AllowedToDelegateTo"
```

## AdminSDHolder & SDProp

```powershell
# SDProp s'exécute toutes les 60 minutes et synchronise les ACLs
# des objets protégés (membres directs/indirects des groupes privilégiés)
# avec le template AdminSDHolder (CN=AdminSDHolder,CN=System,DC=...)

# Surveiller les modifications sur AdminSDHolder (Event 5136)
# Un attaquant peut y ajouter une ACL de backdoor persistante

# Lister les comptes avec AdminCount = 1 (protégés par SDProp)
Get-ADUser -Filter {AdminCount -eq 1} -Properties AdminCount, MemberOf |
  Select-Object SamAccountName, AdminCount, MemberOf

# Vérifier l'ACL actuelle de AdminSDHolder
$adminSDHolder = [ADSI]"LDAP://CN=AdminSDHolder,CN=System,DC={{DOMAIN}},DC={{TLD}}"
$acl = $adminSDHolder.psbase.ObjectSecurity
$acl.Access | Where-Object {$_.IdentityReference -notlike "*Domain Admins*" -and
  $_.IdentityReference -notlike "*SYSTEM*" -and $_.IdentityReference -notlike "*Enterprise Admins*"}

# Membres récursifs des groupes Domain Admins (surveiller les ajouts non autorisés)
Get-ADGroupMember "Domain Admins" -Recursive |
  Select-Object Name, SamAccountName, ObjectClass |
  Sort-Object ObjectClass, Name
```

## Checklist hardening Active Directory

<Checklist
  storageKey="hardening-ad"
  items={[
    { id: "tier-model", label: "Modèle de tiering implémenté (Tier 0/1/2), OUs séparées, GPO de restriction", critical: true },
    { id: "paw", label: "PAW (Privileged Access Workstation) déployés par tier" },
    { id: "dedicated-accounts", label: "Comptes admin dédiés par tier (adm-t0-*, adm-t1-*, adm-t2-*)", critical: true },
    { id: "builtin-admin", label: "Compte Administrator intégré (SID -500) désactivé ou renommé", critical: true },
    { id: "protected-users", label: "Comptes Tier 0 dans le groupe Protected Users (désactive NTLM, RC4)" },
    { id: "laps-deployed", label: "LAPS déployé sur tous les postes et serveurs membres" },
    { id: "kerberos-aes", label: "RC4-HMAC désactivé sur les comptes, AES256 forcé" },
    { id: "kerberos-armoring", label: "Kerberos Armoring (FAST) activé via GPO" },
    { id: "spn-audit", label: "SPNs audités, gMSA utilisés pour les comptes de service" },
    { id: "unconstrained-delegation", label: "Délégation non contrainte supprimée (sauf DC)", critical: true },
    { id: "dc-audit", label: "Audit avancé activé sur les DC (DS Access, Account Management, Kerberos)" },
    { id: "da-members", label: "Domain Admins : moins de 5 membres, vérification mensuelle" },
    { id: "adminsdholder", label: "ACL AdminSDHolder vérifiée, modifications surveillées (Event 5136)" },
    { id: "mdi-deployed", label: "Microsoft Defender for Identity (MDI) déployé sur les DC" }
  ]}
/>

<Tip>
Le premier vecteur d'escalade en AD est un compte de service avec un SPN et un mot de passe faible (Kerberoasting) — auditer tous les SPNs avec `Get-ADUser -Filter {ServicePrincipalName -ne "$null"}` et forcer des mots de passe 25+ caractères aléatoires, ou mieux, migrer vers des gMSA dont le mot de passe (240 bits) est géré automatiquement par AD.
</Tip>
