Cobalt Strike 3.5 is now available. This release adds an SSH client with a Beacon-like interface. This client allows you to conduct post-exploitation actions against UNIX targets from Cobalt Strike. In this post, I’ll take you through the specifics.

The SSH Client

Cobalt Strike’s SSH client is a Reflective DLL that receives tasks from and routes its output through a parent Beacon. This allows you to control UNIX targets from a compromised Windows system without interactive communication.

Use ssh [target] [user] [password] to launch an SSH session from a Beacon. You may also use ssh-key [target] [user] [/path/to/key.pem] to authenticate with a key.

The above will spawn Cobalt Strike’s SSH client and it will report any connection or authentication issues to the parent Beacon. If the connection succeeds, you will see a new session in Cobalt Strike’s display. This is an SSH session. Right-click on this session and press Interact to open the SSH console.



Cobalt Strike’s SSH sessions give you a basic set of post-exploitation features to run commands, upload/download files, and pivot.

The shell command will run the command and arguments you provide. The cd command will change the current working directory of future commands that you run. The pwd command will report the current working directory.

The upload command will upload a file to the current working directory. The download command will download a file. Files downloaded with the download command are available under View -> Downloads. You may also type downloads to see file downloads in progress. The cancel command will cancel a download that’s in progress.

SSH sessions support pivoting as well. Use the socks command to create a SOCKS server on your team server that forwards traffic through the SSH session. The rportfwd command will also create a reverse port forward that routes traffic through the SSH session and your Beacon chain.

There is one caveat to rportfwd: the rportfwd command asks the SSH daemon to bind to all interfaces. It’s quite likely the SSH daemon will override this and force the port to bind to localhost. You need to change the GatewayPorts option for the SSH daemon to yes or clientspecified.

Cobalt Strike does not support chaining through SSH sessions yet (e.g., SSH -> SSH or SSH -> Beacon). This is something I plan to investigate in the future. I’m quite interested in this feature.


Cobalt Strike’s SSH client is a Beacon-compatible agent that uses an SSH library to execute its actions. From the perspective of Cobalt Strike’s team server, there’s little difference between an SSH session and a Beacon session. This makes SSH sessions integrate with Cobalt Strike’s logging, reporting, and scripting in a natural way. Yes, SSH sessions are scriptable with Aggressor Script!

SSH sessions fire an event when a new SSH session comes in. This is your chance to respond to new sessions with automated actions.

on ssh_initial {
if (-isadmin $1) {
binput($1, "cat /etc/shadow (initial)");
bshell($1, "cat /etc/shadow");

You’ll notice that I use &bshell from Aggressor Script to task the SSH session in the above example. This is possible because the SSH client expects the same task format as the Windows Beacon. SSH sessions only implement a subset of Beacon’s command set.

The ssh_alias keyword defines new commands for use within SSH sessions. These are similar to the Beacon aliases you might define with the alias keyword.

ssh_alias survey {
bshell($1, "last -a");
bshell($1, "uname -a");
bshell($1, "id");

The above is a taste of what you can do with SSH sessions and Aggressor Script. I recommend consulting the Aggressor Script manual for more information.

The SSH client for post-exploitation is part of Cobalt Strike 3.5. Check out the release notes to see a full list of what’s new in Cobalt Strike 3.5. Licensed users may use the update program to get the latest.