MDstable
NoteSnippetChecklistPlaybook

Hardening Active Directory — Tier Model & LAPS

Modèle de tiering, comptes privilégiés, LAPS, Protected Users, Kerberos armoring

snippetadvanced 2025-05-14 9 min read
hardeningactive-directorytier-modellapsprivileged-accesskerberospawsecurity

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
Variables
{{DOMAIN}}
{{TLD}}
# 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.

⚠ Attention —

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.

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
Variables
{{DOMAIN}}
{{TLD}}
{{COMPUTER_NAME}}
# 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
Variables
{{DOMAIN}}
{{TLD}}
{{COMPUTER_NAME}}
# 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
Variables
{{DOMAIN}}
{{TLD}}
# 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
Variables
{{COMPUTER_NAME}}
# 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
Variables
{{DOMAIN}}
{{TLD}}
# 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

Checklist0/14
💡 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.

OPS·BRAIN v1.075 notes · Securitylocal