Code : MO-AD-002 | Version : 1.0 | Date : 15 avril 2026 | Auteur : C. Legrand
Ce mode operatoire decrit la double rotation du compte krbtgt, compte systeme Active Directory qui signe l'integralite des tickets Kerberos (TGT) emis par les controleurs de domaine. La procedure vise a neutraliser toute attaque de type Golden Ticket : une cle krbtgt compromise permet a un attaquant de forger des tickets Kerberos arbitraires, valables jusqu'a ce que la cle soit invalidee par une rotation — et cette rotation doit etre executee deux fois (la premiere ne suffit pas, voir section 4).
Frequence recommandee : tous les six mois (ou 180 jours), ou immediatement apres toute suspicion de compromission : extraction NTDS.dit, attaque DCSync, depart d'un administrateur de domaine.
Contexte initial : le compte
krbtgtdu domainebts.sioa ete cree le 06/09/2022 a 17:38 et n'avait jamais ete tourne avant l'execution de cette procedure en avril 2026, soit 1 316 jours de fenetre d'exploitation potentielle. PingCastle signalait cet etat via la regle A-Krbtgt #37. Ce mode operatoire formalise le traitement de ce risque.
| Public concerne | Administrateurs du domaine BTS SIO (role Domain Admins) |
| Systemes cibles | Domaine bts.sio, controleurs DC1 (Srv2022, 10.0.112.2) et DC2 (Srv2022Phy, 10.0.112.3) |
| Outils | PowerShell avec module ActiveDirectory, repadmin, WinRM via pywinrm |
| Authentification | Compte Domain Admin (BTS\Administrateur ou equivalent) |
| Duree | Deux interventions d'environ 5 minutes espacees de 10 a 48 heures |
| Presentiel requis | Non : la procedure s'execute integralement via WinRM depuis le poste d'administration, sous couvert d'une connexion VPN WireGuard a l'infrastructure |
repadmin /replsummary sans erreur bloquante, services NTDS, kdc, Netlogon UP, FSMO accessibles)wbadmin get versions. Une restauration authoritative de l'objet krbtgt ne se fait que depuis ce backup
Erreur RPC 110 chronique sur DC2 : dans l'infrastructure actuelle,
repadmin /syncall /AdePet certaines sous-commandes derepadminremontent une erreur 110 (RPC timeout) sur le serveurSrv2022Phy(port 5722 bloque, DFSR partiellement casse depuis le 27/03/2026). Cette erreur n'interdit pas la rotation : la replication AD principale passe par les ports 135, 389 et 636 qui sont ouverts, etrepadmin /replsummarymontre une latence inferieure a une minute entre les deux DCs. Le depannage de DFSR/RPC 5722 fait l'objet d'une intervention distincte ; il ne doit pas retarder la rotationkrbtgt.
Le compte krbtgt est un compte de service AD automatiquement cree a la promotion du premier controleur de domaine. Il est :
NTDS.dit avec un hash NTLM accessible en lecture au systeme et aux comptes de haut privilege.Chaque ticket TGT emis par un KDC est signe avec la cle courante de krbtgt. Sa duree de vie par defaut est de dix heures (extensible a sept jours par renouvellement). Tant qu'un TGT est valide, son porteur peut demander des tickets de service (TGS) aupres du KDC sans reauthentification.
Un attaquant qui parvient a extraire le hash NTLM de krbtgt (par DCSync, dump memoire LSASS sur un DC, ou lecture NTDS.dit hors ligne) peut alors forger, sur n'importe quelle machine et sans base AD, un TGT arbitraire. Les caracteristiques typiques d'un Golden Ticket sont :
krbtgt qui l'a signe est acceptee par les KDCs.La seule contre-mesure definitive consiste a changer le hash krbtgt. Les tickets forges avec l'ancien hash deviennent alors invalides des qu'ils sont presentes a un KDC dont la cle krbtgt a ete rotatee.
Active Directory conserve deux versions du hash krbtgt : la version courante N et la precedente N-1. Ce mecanisme evite d'invalider massivement les tickets encore en circulation lors d'un changement de cle. Concretement :
L'intervalle minimal entre les deux rotations est dicte par la duree de vie des TGTs (dix heures par defaut). Microsoft recommande 10 a 24 heures, et interdit formellement les deux rotations consecutives rapprochees qui « cassent » l'ensemble des tickets en vol.
Se connecter a DC1 via WinRM depuis le poste d'administration :
python3 -c "
import winrm
s = winrm.Session('10.0.112.2',
auth=('BTS\\\\Administrateur', OLD_PW), transport='ntlm')
print(s.run_ps(open('/tmp/krbtgt_precheck.ps1').read()).std_out.decode('cp850'))"
Contenu du script krbtgt_precheck.ps1 :
$k = Get-ADUser krbtgt -Properties PasswordLastSet, Created
$days = ((Get-Date) - $k.PasswordLastSet).Days
Write-Host "Derniere rotation : $($k.PasswordLastSet) ($days jours)"
repadmin /replsummary
Get-Service NTDS, kdc, DNS, Netlogon | Format-Table
netdom query fsmo
Checklist pre-verifications :
repadmin /replsummary : 0 echec, latence < 5 minNTDS, kdc, Netlogon : etat Running sur DC1 et DC2wbadmin get versions)Etape 1 — Generation et application du nouveau mot de passe
# Bloc PowerShell injecte via WinRM sur DC1
$charset = 33..126 | ForEach-Object { [char]$_ }
$newPwd = -join ($charset | Get-Random -Count 32)
$secure = ConvertTo-SecureString -String $newPwd -AsPlainText -Force
Set-ADAccountPassword -Identity krbtgt -NewPassword $secure -Reset
$newPwd = $null # ne JAMAIS logger le mot de passe
[System.GC]::Collect()
Le mot de passe n'est pas stocke et n'a pas besoin de l'etre : on ne se sert jamais du mot de passe de krbtgt en clair, seul son hash est utilise par les KDCs. Microsoft recommande une longueur de 24 a 32 caracteres aleatoires.
Etape 2 — Forcer la replication vers DC2
repadmin /syncall /AdeP
Start-Sleep -Seconds 10
repadmin /replsummary
Le drapeau /AdeP force une synchronisation pull sur tous les DCs et attend la fin de chaque replication avant de rendre la main. L'option /e etend a tous les sites.
Etape 3 — Confirmer la propagation sur les deux DCs
foreach ($dc in (Get-ADDomainController -Filter *)) {
Get-ADUser krbtgt -Server $dc.HostName -Properties PasswordLastSet |
Format-Table SamAccountName, PasswordLastSet
}
La valeur de PasswordLastSet doit etre identique sur DC1 et DC2 (a la seconde pres, une fois la replication terminee).
Horodatage de reference : lors de l'execution reelle du Sprint 2, Phase 1 a ete executee le 14/04/2026 a 13:02:38. Conserver ce timestamp (capture d'ecran ou journal de session) est indispensable pour decider du moment de la Phase 2.
Entre Phase 1 et Phase 2, ne rien modifier sur les comptes de service ni sur les tickets. Le delai a trois objectifs :
klist des postes clients ne renouvelant pas leurs tickets, etc.) avant de figer la rotation.
Tracker l'echeance : un simple oneliner PowerShell lance periodiquement repond a la question « quand puis-je lancer la Phase 2 ? » :
$h = ((Get-Date) - (Get-ADUser krbtgt -Properties PasswordLastSet).PasswordLastSet).TotalHours
"Heures depuis Phase 1 : {0:N2}" -f $h
Avant toute chose, verifier que l'intervalle est respecte :
$h = ((Get-Date) - (Get-ADUser krbtgt -Properties PasswordLastSet).PasswordLastSet).TotalHours
if ($h -lt 10) {
throw "Intervalle insuffisant ($([math]::Round($h,1)) h) : ANNULATION Phase 2"
}
Le bloc est rigoureusement identique a la Phase 1 : meme generation aleatoire 32 caracteres, meme Set-ADAccountPassword -Identity krbtgt -Reset, meme repadmin /syncall /AdeP. Cette repetition est l'essence de la procedure : c'est le deuxieme cycle qui jette definitivement la cle N-1.
Verification finale
$before = [datetime]"2026-04-14 13:02:38" # horodatage Phase 1
$after = (Get-ADUser krbtgt -Properties PasswordLastSet).PasswordLastSet
$delta = ($after - $before).TotalHours
"Phase 1 : $before"
"Phase 2 : $after"
"Delta : $([math]::Round($delta,2)) heures"
La valeur de $delta doit etre superieure a 10 heures et inferieure a la duree maximale recommandee (~48 h). Dans l'execution de reference de ce MO, Δ = 29,81 heures (Phase 2 le 15/04/2026 a 18:52:21).
Apres la Phase 2, valider chaque item ci-dessous :
PasswordLastSet krbtgt identique sur DC1 et DC2repadmin /replsummary : 0 echec, latence < 5 minrepadmin /showrepl : dernieres replications reussies sur chaque DCklist tgt avec nouveau KerbTicket Encryption Type et increment de kvnoCote poste client, forcer le renouvellement pour valider l'operation :
klist purge # vide le cache local
gpupdate /force # force un rafraichissement GPO
klist tgt # doit afficher un ticket frais
Cache NTLM : le cache NTLM des DCs et des clients conserve pendant environ une heure la correspondance
utilisateur <-> mot de passepour les authentifications non-Kerberos. Ce cache n'a rien a voir aveckrbtgt: il concerne les mots de passe des comptes utilisateur, jamais la clekrbtgt. Sa presence ne remet pas en cause l'efficacite de la rotation.
| Symptome | Diagnostic et correction |
|---|---|
repadmin /syncall /AdeP renvoie Access Denied sur CN=NTDS Settings |
L'erreur n'est pas liee a la rotation mais a des ACL RPC particulieres. Tant que repadmin /replsummary montre 0 echec, la replication passe par les canaux normaux. Voir MO-AD-005 pour diagnostic approfondi. |
| Utilisateurs deconnectes massivement apres Phase 2 | Phase 2 lancee trop tot (moins de 10 h apres Phase 1). Les TGTs actifs n'ont pas eu le temps de se renouveler. Forcer klist purge + gpupdate /force sur les postes ou attendre l'expiration naturelle (≤ 10 h). |
| Service avec compte de service casse | Un compte de service standard utilise son propre mot de passe, pas celui de krbtgt. Si le service casse, c'est qu'il utilisait un TGT stocke en cache : redemarrer le service resoud le probleme. |
Set-ADAccountPassword : « The server is unwilling to process the request » |
Le mot de passe genere ne respecte pas la politique de mot de passe du domaine (FGPP la plus stricte applicable au compte). Regenerer en ajoutant un echantillon garanti de chaque classe de caracteres (upper, lower, digit, special). |
| DFSR SYSVOL casse apres rotation | Non cause par la rotation krbtgt (qui ne touche pas SYSVOL). Verifier dfsrdiag pollad et les journaux DFSR. Voir MO-AD-005 section 6. |
Service kdc arrete sur DC2 |
La Phase 2 echoue silencieusement sur ce DC. Redemarrer : Start-Service kdc via WinRM, puis relancer repadmin /syncall. |
T21_rotation_krbtgt.ps1Un script PowerShell parametre est deja disponible, fonctionnant en trois modes :
# Etat courant, sans modification
.\T21_rotation_krbtgt.ps1 -Phase Check
# Premiere rotation (demande confirmation 'oui')
.\T21_rotation_krbtgt.ps1 -Phase Phase1
# Seconde rotation (garde-fou < 10h)
.\T21_rotation_krbtgt.ps1 -Phase Phase2
Une planification semestrielle automatique peut etre posee via Register-ScheduledTask, en s'assurant imperativement que les deux phases soient espacees de plus de 12 heures :
$trig1 = New-ScheduledTaskTrigger -Once -At "2026-10-14T13:00:00"
$act1 = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-File C:\Scripts\T21_rotation_krbtgt.ps1 -Phase Phase1"
Register-ScheduledTask -TaskName "krbtgt-phase1" -Trigger $trig1 -Action $act1 `
-RunLevel Highest -User "BTS\Administrateur"
$trig2 = New-ScheduledTaskTrigger -Once -At "2026-10-15T13:00:00"
$act2 = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-File C:\Scripts\T21_rotation_krbtgt.ps1 -Phase Phase2"
Register-ScheduledTask -TaskName "krbtgt-phase2" -Trigger $trig2 -Action $act2 `
-RunLevel Highest -User "BTS\Administrateur"
Automatisation complete deconseillee : planifier Phase 2 sans verification humaine revient a accepter que toute erreur operationnelle (panne DC2, perte de connectivite entre DCs, incident de replication) se propage directement a une rotation consecutive. Une execution
-Phase Phase2manuelle reste preferable, avec le garde-fou integre qui verifie l'intervalle.
Il n'existe pas de rollback simple pour une rotation krbtgt. Une fois le nouveau mot de passe pose, l'ancien hash n'est plus reconstructible (la generation etait aleatoire et le mot de passe clair jamais conserve). Les solutions en cas d'incident majeur :
krbtgt depuis le backup System State (MO-AD-006) : operation lourde, necessitant le demarrage d'un DC en Directory Services Restore Mode (DSRM). Reserver aux situations ou la rotation a litteralement casse l'authentification sur tout le domaine.Dans la pratique, le pire scenario observable a la rotation est la deconnexion temporaire des sessions, resolue par un simple klist purge et une nouvelle ouverture de session.
| Version | Date | Auteur | Modifications |
|---|---|---|---|
| 1.0 | 15/04/2026 | C. Legrand | Creation initiale — procedure executee au titre du Sprint 2 (T21). Phase 1 : 14/04 13:02:38. Phase 2 : 15/04 18:52:21. |
krbtgt est bien tourne regulierement)T1558.001 (Forge Kerberos Tickets: Golden Ticket)KB2549833)