Archive for the ‘Cobalt Strike’ Category


Cobalt Strike 3.5.1 – Important Security Update

October 3, 2016

Cobalt Strike 3.5.1 is now available. This release addresses a remote code execution vulnerability in Cobalt Strike. This vulnerability was discovered after a report of in-the-wild exploitation by a third-party. Cobalt Strike 3.5 and all prior versions are vulnerable. This includes 2.5 and below. Read last week’s advisory for more details.

Strategic Cyber LLC advises all Cobalt Strike users to update to Cobalt Strike 3.5.1.

Strategic Cyber LLC urges all Cobalt Strike users to sign-up for the Cobalt Strike Technical Notes mailing list. This list is Strategic Cyber LLC’s primary means to notify users of updates, security advisories, and to communicate other urgent notices.

The rest of this post describes the vulnerability and the hardening measures taken to mitigate it and its variants. This post also provides update advice for users who use older versions of Cobalt Strike to support long-running engagements.

The Vulnerability

Cobalt Strike’s team server is a controller for the Beacon post-exploitation payload. Cobalt Strike has options to serve and control the Beacon payload over HTTP, HTTPS, and DNS. Embedded within the Beacon payload are directives that tell the Beacon payload how to communicate with its team server.

By design, any party can download the Beacon payload and its embedded configuration. This allows a Beacon to bootstrap on a newly compromised system and take steps to authenticate and communicate with its team server. Conversely, this means the information a malicious actor needs to establish communication with a team server is available to them.

Once Beacon runs, its first job is to securely send a randomly generated session key and other information about itself (username, IP address, process ID, etc.) to its team server. Cobalt Strike refers to this information as session metadata.

After this, the Beacon periodically connects to its team server, asks for tasks, sends response directives, and goes back to sleep. These response directives are a limited set of actions that a Beacon may ask its team server to execute. Most of the responses simply format and present output to the user (e.g., keystrokes, output from a command, etc.).

Some response directives work together to support more complicated tasks. For example, there are three response directives that support file downloads.

The first file response directive starts a file download. This directive accepts as input an integer file ID, an integer that is the file length, and a string with the full path to the file on the remote system. This directive notifies users that a download has begun and it opens a handle to write the downloaded file to disk. This directive then associates the file ID with this handle.

The second file response directive accepts an integer file ID and a binary blob. This directive writes the binary blob to the file handle that maps to the file ID for the current session. A Beacon session may make multiple requests with this directive to send a large file to a team server.

The third file response directive accepts an integer file ID. This directive formally informs the team server that the file download is complete.

The team server does not map response directives to previous tasks. Once a client establishes a session, it has freedom to request execution of any response directives in any order or quantity.

The team server stores files it downloads into a fixed path. That path is downloads/[internal IP address of session]/[path/to/remote file].

The [path/to/remote file] input comes from the first file response directive. The team server took steps to sanitize this value in an attempt to prevent a directory traversal attack. These steps were not best practice for the Java platform, but some measure was in place. The information provided to Strategic Cyber LLC did not indicate that this value was the source of the directory traversal input.

What other input is there? There’s the [internal IP address of the session]. The team server uses this value to organize downloaded files and to organize its logs. Where does this value come from? It comes from the session metadata. Who controls the session metadata? The Beacon session controls this value.

This led to the root cause of the issue: The team server extracts information from the session metadata and makes that information available to other features as trusted information about that session. The team server did not validate these metadata parameters for expected form or sanitize these parameters for malicious inputs.

Hot Fix 1 took steps to mitigate the in-the-wild exploit and buy time for further investigation. Hot Fix 2 mitigated the identified root cause of this vulnerability and potential variants by adding strict checks and sanitization to the session metadata.

The Hardening Measures

This release restores functionality degraded by last week’s Hot Fixes for this vulnerability, improves on Hot Fix 2’s measures, and hardens the Cobalt Strike team server against this vulnerability and potential variants.

Here are the changes:

1. This release reworks the download response directives to use randomly generated names for downloaded files stored on the team server. Information about the downloaded files (name, where they came from, etc.) is logged to logs/[date]/downloads.log. The View -> Downloads tab displays the real file name and original remote path. The Sync Files button works as it did prior to the Hot Fixes.

2. The team server now uses a safe path concatenation function throughout its codebase. This function compares the canonical paths of the parent and candidate result to make sure the result doesn’t break out of its parent.

3. This release adds a host_stage option to Malleable C2. This option controls whether or not Cobalt Strike hosts Beacon stages for download over HTTP, HTTPS, and DNS. If set to false, staging functionality will be unavailable, but this is useful for teams with a no-network staging policy.

4. The team server now refuses to process a session if any of its metadata fails validity checks. This is a minor improvement on the changes made in Hot Fix 2.

5. The team server now denies new sessions with no prior tasks access to most response directives.

Update Advice (for those with Live Sessions)

If you have live accesses and can’t afford to lose control of them, then you’ll want to approach an update with caution.

If you have Cobalt Strike 3.2 and below with live sessions, do not update the team server in place. The 3.5.1 team server cannot control Beacons in 3.2 and below. Migrate your accesses to a new server with 3.5.1.

If you have Cobalt Strike 3.3 with live sessions, you may stop your team server and update in place. After this update, you should migrate accesses to new infrastructure.

If you have Cobalt Strike 3.4 or 3.5 with live sessions, then you may stop your team server and update in place to 3.5.1. Cobalt Strike 3.5.1 can control sessions from 3.4 and 3.5 with little or no impact. The ssh and ssh-key commands will not work in Beacons from Cobalt Strike 3.4.

Update Instructions

Licensed users may use the update program to get the latest. Trial users must download the trial again.

To verify that you have Cobalt Strike 3.5.1, go to Help -> About. The software will report version 3.5.1.


Cobalt Strike RCE. Active Exploitation Reported.

September 28, 2016


There is a remote code execution vulnerability in the Cobalt Strike team server.

A hot fix that breaks this particular exploit chain is available.

Customers may use the built-in update program to download an update with this hotfix. The latest trial download has this hotfix as well.

Strategic Cyber LLC is working on a comprehensive update for this issue. This comprehensive update will be available as soon as possible.

Update 29 Sept 2016: A second hot fix is available. The original hot fix was scoped to the reported attack chain. This second hot fix provides broader protection against the reported attack chain and potential variants. Cobalt Strike users are urged to update to the second hot fix until the comprehensive update is available.

Update 3 Oct 2016: Cobalt Strike 3.5.1 is now available. This release restores functionality degraded by the Hot Fixes for this vulnerability, improves on Hot Fix 2’s measures, and hardens the Cobalt Strike team server against this vulnerability and potential variants. This is the comprehensive update to address this vulnerability and its variants.

What happened?

Strategic Cyber LLC received a report with suspicious indicators of active exploitation from a third-party. Strategic Cyber LLC investigated the indicators and determined that the likelihood of a remote code execution vulnerability is high.

The Vulnerability

The vulnerability is a directory traversal attack allowed by improper sanitization of parameters in the file download feature of the Beacon and SSH session payloads.

One may connect to a Cobalt Strike listener, download the payload stage, use the information in the stage to fake a session, and craft a message to force Cobalt Strike to write a file to an arbitrary location.

Potential Indicators of Compromise

These are the indicators that may indicate an exploitation attempt:

1. a GET to /aaaa was one of the reported indicators. While this is a valid URI to grab a payload stage–Cobalt Strike randomizes this URI when it downloads a payload stage.

2. The activity report showed downloads of .config, /etc/crontab, and /etc/cron.d/.hourly.

3. The reporter states that the attacker cleared logs from the server, cleared the downloaded files, and cleared the Cobalt Strike data model and log files.

Steps to Mitigate

Trial users: download the trial for Cobalt Strike 3.5.1.

Customers: run the built-in update program to update to Cobalt Strike 3.5.1.

If you have Beacons that are already deployed with Cobalt Strike 3.5, 3.5-hf1 or 3.5-hf2, you may update to this release without affecting them. The fix is entirely in the controller.

To verify that you have the hot fix, go to Help -> System Information. Cobalt Strike will report its version as 20161003. Help -> About will state 3.5.1.

What’s affected?

All versions of Cobalt Strike 3.5 and below (without the hotfix) are affected.

It’s likely this issue also exists in the deprecated Cobalt Strike 2.x and below as well.

What’s next?

Strategic Cyber LLC will issue a comprehensive fix for this issue as soon as possible. As more information is available, Strategic Cyber LLC will post it to two places:

1. Updates to this blog post.

2. Emails will also go out to the Cobalt Strike Technical Notes mailing list.


Raphael Mudge, Strategic Cyber LLC
[email protected]


3 October 2016, 9:05am EST – Announce Cobalt Strike 3.5.1
29 September 2016, 5:45pm EST – Announce Hot Fix 2
28 September 2016, 7:05pm EST – Initial Announcement


Cobalt Strike 3.5 – UNIX Post Exploitation

September 22, 2016

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. A 21-day Cobalt Strike trial is also available.


What happened to my Kill Date?

August 24, 2016

Cobalt Strike 3.4 introduced a Kill Date feature. This is a date that Cobalt Strike embeds into each Beacon stage. If a Beacon artifact is run on or after this date, it immediately exits. If a running Beacon wakes up on or after this date, it immediately exits. I don’t see kill dates as a replacement for tracking artifacts and cleaning up after an engagement. I see them as an extra piece of assurance.

To use Cobalt Strike’s kill date feature, you must specify a kill date when you start the team server. Here’s the help for the teamserver script:


Here’s an example of starting a team server with a kill date embedded in it:


You’ll notice that it is mandatory to specify a Malleable C2 profile, if you want to take advantage of kill dates. I’ve had a few folks ask if there is a way around this. The answer is no, not right now. The default profile isn’t anything special. It looks like a simple piece of malware on the wire. Specify a profile.🙂 You’re better off for it.

I want to call your attention to one detail though. Notice that the team server acknowledges both the profile and the kill date. This is Cobalt Strike telling you that it sees these parameters and it’s using them as you asked it to.

If you do not see this acknowledgement, Cobalt Strike is not using your custom profile, and it does not have a kill date embedded into the Beacon stage.

You may wonder, how is this situation possible? If you specify the parameters correctly, why wouldn’t Cobalt Strike use them? This is a good question and it’s the real reason for this blog post.

Cobalt Strike 3.0 and 3.1 shipped with a teamserver script that passed either two or three arguments to the Cobalt Strike software. The teamserver script shipped with these versions of Cobalt Strike would not pass an arbitrary number of arguments. The update program that ships with Cobalt Strike does not update the teamserver script.

If you have a teamserver script from Cobalt Strike 3.0 or 3.1, Cobalt Strike will not use the kill date you specify or the profile you specify when a kill date is present. If this applies to you: download the trial for the latest Cobalt Strike Linux package, update it to the licensed version with the built-in update program, and you’re set again.

The teamserver script with Cobalt Strike 3.2 and later will work fine.


Cobalt Strike 3.4 – Operational Details

July 29, 2016

Cobalt Strike 3.4 is now available. This release focuses on the DNS Beacon and a few additions to Malleable C2. Here are the highlights:

New Malleable C2 Options

This release extends the Malleable C2 feature with several useful options. The dns_idle option allows you to change the IP address the DNS Beacon uses to signal that it’s idle. The default value is and this is an indicator some use to zero-in on Cobalt Strike’s DNS Beacon payload. I recommend you set this option in your Malleable C2 profiles.

This release also adds a dns_sleep option. This option forces the DNS Beacon to sleep before each of its DNS requests. This is guaranteed to make DNS data channels very painful to use! This option is now available for those of you who asked for it.

The pipename option allows you to change the name of the named pipe SMB Beacon uses for peer-to-peer communication.


DNS IPv6 AAAA Record Data Channel

The DNS Beacon received a few enhancements beyond the Malleable C2 options above. The mode dns6 command now sets your DNS Beacon to use AAAA records as a data channel. This is similar to the mode dns option, which asks Beacon to use A records as a data channel. The benefit is that the AAAA records give you more data per request.

Kill Dates

By popular request, Cobalt Strike now allows you to embed a kill date into the Beacon payload. Beacon will automatically exit, when run, on or after its kill date. Beacon also checks the kill date each time it wakes up and exits if it’s on or after the kill date.

To take advantage of this feature, simply specify a kill date when you start your Cobalt Strike team server. Your team server will propagate the specified kill date to all payload stages it generates. Here’s the format:

./teamserver [ip address] [malleable C2 profile] [YYYY-MM-DD]

Check out the release notes to see a full list of what’s new in Cobalt Strike 3.4. Licensed users may use the update program to get the latest. A 21-day Cobalt Strike trial is also available.


Why is rundll32.exe connecting to the internet?

July 22, 2016

Previously, I wrote a blog post to answer the question: why is notepad.exe connecting to the internet? This post was written in response to a generation of defenders zeroing in on the notepad.exe malware epidemic that was plaguing them. Many offensive actions require spawning a new process to inject something into. In the Metasploit Framework (and ancient versions of Cobalt Strike), notepad.exe was the default process to spawn for these actions.

Today, rundll32.exe is the process Cobalt Strike will spawn when it needs a one-off process to inject something into. I’ve had many people write and ask: “Raphael, why rundll32.exe?” Others ask, “how do I switch from rundll32.exe to something else?” This blog post aims to answer these questions.

User-driven Attacks

Several of Cobalt Strike’s user-driven attacks automatically migrate the payload stager to a new process and then run it. I do this for two reasons:

First, the user-driven attack might land code execution in an x64 process. We can’t run an x86 payload in an x64 process. The solution here is to migrate. Cobalt Strike’s Java Applet attacks and the Microsoft Office macro attacks both migrate to rundll32.exe (by default).

Cobalt Strike’s user-driven attacks migrate for another good reason. What happens if the user closes the application we used to get code execution? If our payload ran within that application, our access would go away with it. If our payload lives elsewhere, our access is safe. This is another reason Cobalt Strike’s attacks migrate.

So, why rundll32.exe? Why not something else? Honestly, it doesn’t matter what I pick. Anything I pick is now the default. Because people rarely change defaults, it will show up enough that someone will notice. The right thing here, for all parties, is to know how to change the defaults. Fortunately, this isn’t too hard to do.

Cobalt Strike does not provide a way to override the default macro attack. Fortunately, its choice of rundll32.exe is a string inside of the macro that you can edit. If this choice does not work for you, change this to another process. Many times, I have edited Cobalt Strike’s VBA macro to spawn Internet Explorer and inject my stager into it. I found this was necessary for security postures that restricted which applications could make outbound connections.

The Java Applet is also easy to fix. If you’re using the Java Signed Applet attack with Cobalt Strike, chances are you’re familiar with the Applet Kit. This is the source code to Cobalt Strike’s Java Applet attack and the scripts necessary to build it. You’ve probably downloaded this kit to sign Cobalt Strike’s Applet with your code signing certificate. If you want the Java Applet to migrate elsewhere, edit src/injector.c, change rundll32.exe to something else, and rebuild the Applet Kit. This will require that you have the mingw-w64 package installed.

Executable and DLL Artifacts

Cobalt Strike’s options to export an x64 DLL to deliver an x86 Beacon also migrate to rundll32.exe. I do this for good reason. I can’t host the x86 Beacon inside of an x64 process! Again, the answer here is to migrate and I migrate to a default: rundll32.exe.

Cobalt Strike also generates executables that respond to commands from the Windows Service Control Manager. Cobalt Strike uses these executables with its psexec command and it lets you export them as well. These service executables automatically migrate your payload or stager. Why? I do this to make the service easier to cleanup. In the case of psexec, I can’t get rid of the executable until it stops running. If the service executable didn’t migrate, Cobalt Strike’s psexec command would have to wait until your session stopped to clean up the executable it put on target. That’s no good! This is why the service executables migrate.

Fortunately, changing the rundll32.exe indicator is pretty easy to do as well. Cobalt Strike allows users to change it process to generate executables and DLLs. This is possible through the Artifact Kit. The Artifact Kit is source code to Cobalt Strike’s executable/DLL templates and it’s a script to override Cobalt Strike’s internal process to patch shellcode into these templates.

If you edit src-common/patch.c, you can change the migrate process from rundll32.exe to something else. Rebuild the artifact kit, load its script into your Cobalt Strike client, and from that point on—you’re free of rundll32.exe in your service executable and x64 DLL artifacts.

Spawning Sessions

rundll32.exe rears its ugly head in other places too. A favorite workflow in Cobalt Strike is the ability to right-click a session, select Spawn, and send a session to another listener. This command spawns a process and injects a payload stager for the chosen listener into it. I spawn a process because stagers do crash from time to time. Injecting the stager into another process protects your access from that crash.

When Beacon spawns an executable for session passing, which one does it spawn? Why our friend, rundll32.exe. Of course!

You may ask, how do I change this? There are a few answers to this question. The first answer is to reconsider your use of the spawn command. The spawn command creates a child process off of your Beacon process. This child process makes outbound network connections. If a hunt team is watching process creates and network connections, your access will stand out like a sore thumb. I recommend using the inject command to pass sessions instead.

That aside, let’s say you want to continue to use the spawn command. Your choice! Here’s how to move away from rundll32.exe: First, you may change which command Beacon spawns with the built-in spawnto command. This command will change the spawn process for that Beacon instance to something else.

You may also change the default for all of your Beacon sessions with a Malleable C2 profile. Malleable C2 is Cobalt Strike’s technology to allow you to change indicators and behaviors in the Beacon payload. It’s quite handy if you want to make Beacon look like other malware or blend-in to look like something totally innocuous. Malleable C2 has an option, spawnto, that changes this default to something else.

Post Exploitation Jobs

Let’s cover the last place rundll32.exe likes to show itself, post-exploitation jobs. Beacon is a very small payload. It’s single threaded. It’s designed to do a few very simple things. It calls home, it executes a few base things, and it monitors jobs.

Post-exploitation features such as hashdump, mimikatz, screenshots, keystroke loggers, and others run as jobs. In Beacon parlance, a job is a post-exploitation task that lives in another process. This design serves a few purposes. First, it makes it possible for you to inject a capability (e.g., the screenshot tool) into a process of your choosing. This allows you to get results from the right place without migrating your access. That’s nice! Second, some post-exploitation tasks absolutely must run from a process that matches the operating system’s architecture. This scheme allows an x86 Beacon to seamlessly run x64 post-exploitation jobs without any bother to the operator. Things just work! Third, this scheme protects your access. If, for some reason (heaven forbid!) a post-exploitation task were to crash, this scheme isolates your access from that failure.

Anyways, you have the option to inject some jobs into a process of your choosing. Others jobs just kick off a process, inject the capability, let it run, get results, and tear the process down. These jobs that kick off a process happen to spawn, our old friend, rundll32.exe.

You may ask, how do I change this? Fortunately, there’s not a lot of new advice to offer here. Post-exploitation jobs use the same spawnto process that the spawn command uses. If you edit your Malleable C2 profile to ask that Beacon spawn another placeholder, your post-exploitation jobs will use this placeholder as well.

There is one caveat here. The spawnto command only affects which x86 process the x86 Beacon kicks off. If x86 Beacon has to kick off an x64 process, it doesn’t change this. I do not have a means to change the x64 spawnto process, yet. I’ll take care of this.

And, for the sake of completeness: the spawnto command does not affect which x86 process the x64 Beacon kicks off, when it needs to run an x86 job. If x64 Beacon has to kick off an x86 process, it will use rundll32.exe. I do not have a means to change this yet either. Again, this is one of those todo items.

You’re now empowered!

This post was a lovely stroll through the migrate and spawning behavior of Cobalt Strike 3.0 and later. There are three take-aways for this post:

1. Cobalt Strike migrates stagers and tasks to other processes. It does this a lot. Usually for good reasons!

2. The default process Cobalt Strike migrates to is rundll32.exe.

3. You have the power to change this behavior in most cases.


HOWTO: Reset Your Cobalt Strike License Key

July 15, 2016

Time to time, I hand out Cobalt Strike license keys to non-customers. Sometimes these are to support an event (e.g., the National CCDC Red Team). Other times, these license keys allow a potential customer to evaluate Cobalt Strike without the deliberate tells present in the trial.

Cobalt Strike’s license key is primarily used with the built-in update program. My server uses this key to verify that you’re still licensed to use the Cobalt Strike product and receive updates for it.

The built-in update program asks for this key once. Afterwards, it does not ask for this key again.

This presents a small problem. ☺ When you go from evaluator to customer, you’ll want to remove your evaluation key. If you don’t, Cobalt Strike will continue to use this key instead of the one tied to your license. Once that key expires, you can’t update Cobalt Strike or access the Cobalt Strike Arsenal.

With all that out of the way, let’s get to the question that prompted this post. How do you reset your Cobalt Strike License Key? Easy.

Cobalt Strike stores your license key in the .cobaltstrike.license file in your home directory. Simply remove this file and the update program will ask you for a new key when you run it next.

rm –f ~/.cobaltstrike.license

That’s it!