MDstable

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

TierPérimètreComptesExemples de systèmes
Tier 0Contrôle de l'identitéDomain Admins, Enterprise Admins, Schema AdminsDC, PKI, ADFS, Azure AD Connect, PAM tools
Tier 1Serveurs d'entrepriseAdmins serveurs, comptes de serviceServeurs membres, SQL, Exchange, IIS
Tier 2Postes de travailHelpdesk, admins locauxPostes 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.090 notes · Securitylocal