Beacon Command Behavior Survey

A good operator knows their tools and has an idea of how the tool is accomplishing its objectives on their behalf. This document surveys Beacon's commands and provides background on which commands inject into remote processes, which commands spawn jobs, and which commands rely on cmd.exe or powershell.exe.


These commands are built into Beacon and rely on Win32 APIs to meet their objectives.

cd cp connect download drives exit getprivs getuid inline-execute jobkill kill link ls make_token mkdir mv ps pwd rev2self rm rportfwd rportfwd_local setenv socks steal_token unlink upload

House-keeping Commands

The following commands are built into Beacon and exist to configure Beacon or perform house-keeping actions. Some of these commands (e.g., clear, downloads, help, mode, note) do not generate a task for Beacon to execute.

argue blockdlls cancel checkin clear downloads help jobs mode dns mode dns-txt mode dns6 note powershell-import ppid sleep socks stop spawnto

Inline Execute (BOF)

The following commands are implemented as internal Beacon Object Files. A Beacon Object File is a compiled C program, written to a certain convention, that executes within a Beacon session. The capability is cleaned up after it finishes running.

dllload elevate svc-exe elevate uac-token-duplication getsystem jump psexec jump psexec64 jump psexec_psh kerberos_ccache_use kerberos_ticket_purge kerberos_ticket_use net domain reg query reg queryv remote-exec psexec remote-exec wmi runasadmin uac-cmstplua runasadmin uac-token-duplication timestomp

The network interface resolution within the portscan and covertvpn dialogs uses a Beacon Object File too.

OPSEC Advice: Beacon Object Files use RWX memory by default. Set the startrwx/userwx hints in Malleable C2's process-inject block to change the initial or final memory permissions.

Post-Exploitation Jobs (Fork&Run)

Many Beacon post-exploitation features spawn a process and inject a capability into that process. Some people call this pattern fork&run. Beacon does this for a number of reasons: (i) this protects the agent if the capability crashes. (ii) historically, this scheme makes it seamless for an x86 Beacon to launch x64 post-exploitation tasks. This was critical as Beacon didn't have an x64 build until 2016. (iii) Some features can target a specific remote process. This allows the post-ex action to occur within different contexts without the need to migrate or spawn a payload in that other context. And (iv) this design decision keeps a lot of clutter (threads, suspicious content) generated by your post-ex action out of your Beacon process space. Here are the features that use this pattern:

Fork&Run Only

chromedump covertvpn dcsync execute-assembly hashdump logonpasswords mimikatz net * portscan powerpick pth ssh ssh-key

Target Explicit Process Only

browserpivot psinject

Fork&Run or Target Explicit Process

desktop keylogger printscreen screenshot screenwatch

OPSEC Advice: Use the spawnto command to change the process Beacon will launch for its post-exploitation jobs. The default is rundll32.exe (you probably don’t want that). The ppid command will change the parent process these jobs are run under as well. The blockdlls command will stop userland hooking for some security products. Malleable C2's process-inject block gives a lot of control over the process injection process. Malleable C2's post-ex block has several OPSEC options for these post-ex DLLs themselves. For features that have an explicit injection option, consider injecting into your current Beacon process. Cobalt Strike detects and acts on self-injection different from remote injection.

Process Execution

These commands spawn a new process:

execute run runas runu

OPSEC Advice: The ppid command will change the parent process of commands run by execute. The ppid command does not affect runas or runu.

Process Execution (cmd.exe)

The shell command depends on cmd.exe. Use run to run a command and get output without cmd.exe

The pth command relies on cmd.exe to pass a token to Beacon via a named pipe. The command pattern to pass this token is an indicator some host-based security products look for. Read How to Pass-the-Hash with Mimikatz for instructions on how to do this manually.

Process Execution (powershell.exe)

The following commands launch powershell.exe to perform some task on your behalf.

jump winrm jump winrm64 powershell remote-exec winrm

OPSEC Advice: Use the ppid command to change the parent process powershell.exe is run under. Use the POWERSHELL_COMMAND Aggressor Script hook to change the format of the PowerShell command and its arguments. The jump winrm, jump winrm64, and powershell [when a script is imported] commands deal with PowerShell content that is too large to fit in a single command-line. To get around this, these features host a script on a self-contained web server within your Beacon session. Use the POWERSHELL_DOWNLOAD_CRADLE Aggressor Script hook to shape the download cradle used to download these scripts.

Process Injection (Remote)

The post-exploitation job commands (previously mentioned) rely on process injection too. The other commands that inject into a remote process are:

dllinject dllload inject shinject

OPSEC Advice: Malleable C2's process-inject block gives a lot of control over the process injection process.

Process Injection (Spawn&Inject)

These commands spawn a temporary process and inject a payload or shellcode into it:

elevate uac-token-duplication shspawn spawn spawnas spawnu spunnel spunnel_local

OPSEC Advice: Use the spawnto command to set the temporary process to use. The ppid command sets a parent process for most of these commands. The blockdlls command will block userland hooks from some security products. Malleable C2's process-inject block gives a lot of control over the process injection process. Malleable C2's stage block provides options to adjust Beacon's in-memory evasion options.

Service Creation

The following internal Beacon commands create a service (either on the current host or a remote target) to run a command. These commands use Win32 APIs to create and manipulate services.

elevate svc-exe jump psexec jump psexec64 jump psexec_psh remote-exec psexec

OPSEC Advice: These commands use a service name that consists of random letters and numbers by default. The Aggressor Script PSEXEC_SERVICE hook allows you to change this behavior. Each of these commands (excepting jump psexec_psh and remote-exec psexec) generate a service EXE and upload it to the target. Cobalt Strike's built-in service EXE spawns rundll32.exe [with no arguments], injects a payload into it, and exits. This is done to allow immediate cleanup of the executable. Use the Artifact Kit to change the content and behaviors of the generated EXE.