h1

Cobalt Strike 3.12 – Blink and you’ll miss it

September 6, 2018

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";
}

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.

h1

Broken Promises and Malleable C2 Profiles

June 4, 2018

Red Team infrastructure is a detail-heavy subject. Take the case of domain fronting through a CDN like CloudFront. You have to setup the CloudFront distribution, have a valid SSL configuration, and configure your profile properly. If any of these items is wrong, your C2 will not work.

Many folks take “configure your profile properly” for granted. A profile that passes a c2lint check isn’t guaranteed to work in all circumstances you throw at it. A lot of things can go wrong. For example, the CDN may rewrite your HTTP requests in ways that break your Malleable C2 profile. That’s what this blog post is about…

One of my favored ways to quickly setup an SSL-enabled Cobalt Strike is with Alex Rymdeko-harvey‘s HTTPsC2DoneRight.sh script. This script asks a few questions, requests a LetsEncrypt certificate, and sets up a modified Malleable C2 profile that uses this certificate.

The profile used by Alex’s script is amazon.profile. I’ve noticed that many red teamers opt to use this profile with their first experiments to use CloudFront as a redirector for Cobalt Strike.

An Amazon Web Service and an Amazon-like profile, what could go wrong? A lot of things can go wrong. 🙂 If you’ve tried this setup, you may have found a console message [on the team server] that looks like this:

This message means Cobalt Strike could not recover information from an HTTP transaction. Some aspect of the HTTP transaction differs from the assumptions provided by your Malleable C2 profile.

Assumption is the key word. Malleable C2 gives operators a lot of power to change what Cobalt Strike’s HTTP communication looks like. Malleable C2 is an example of a declarative programming language. You, the operator, specify what Beacon’s communication should look like. Cobalt Strike figures out how to make that happen. Specifically, Cobalt Strike compiles your specification into two different programs. One program transforms data and stores it in a transaction. The other program recovers data from a transaction and reverses the transformations made to the data. These programs are patched into the Beacon payload and its controller. If the assumptions of these derived programs break, your communication breaks.

When the above happens, it’s helpful to know how to read the output above and use it to troubleshoot your communication.

Our error message states that Malleable C2 could not recover data from the http-get -> client -> metadata transaction. Beacon provides metadata to tell Cobalt Strike about the session. This RSA-encrypted blob includes situational awareness information (e.g., username, PID, hostname, etc.) and a unique key for the session. Without metadata, Cobalt Strike knows nothing about the session. It’s important that this part of the transaction works.

To resolve this issue, it’s our job to figure out how the expectations of the Malleable C2 profile differ from the reality of the HTTP request received by Cobalt Strike.

Where should we look? The right place is to look at the parts of the HTTP transaction relevant to our failed transaction.

Here’s what the .http-get.client.metadata block looks like in the (slightly modified) amazon profile I used with CloudFront:

http-get {

    set uri "/s/ref=nb_sb_noss_1/167-3294888-0262949/field-keywords=books";

    client {

        header "Accept" "*/*";

        metadata {
            base64;
            prepend "session-token=";
            prepend "skin=noskin;";
            append "csm-hit=s-24KU11BB82RZSYGJ3BDK|1419899012996";
            header "Cookie";
        }
    }

The metadata block base64 encodes the metadata, prepends two strings to it, appends another string, and it stores the entire thing in the HTTP Cookie header. OK.

And, here’s a screenshot of the preview generated by c2lint:

In troubleshooting this specific issue, we should ask: does the HTTP Cookie header received by Cobalt Strike differ from the HTTP Cookie header Malleable C2 expects. If so, how and why?

Let’s look at the preview Cookie and the received Cookie side-by-side:

Here, the issue becomes a little more obvious. The Cookie received by Cobalt Strike has the same information, but the parts of the Cookie are in a different order. This is a change CloudFront made to our HTTP transaction. This breaks our profile.

Malleable C2 does not know the semantics of the Cookie field. To recover data from this transaction, it knows it must recover the value of the Cookie header, remove some appended strings, remove some prepended strings, and base64 decode what’s left. Any unexpected change (e.g., spaces removed, new strings, re-arranged strings, etc.) breaks this process.

What’s the solution? In this case, we could update the structure of our HTTP Cookie to match what CloudFront will transform it to. This would work just fine. We could also store our metadata in something other than the Cookie header. Either approach is OK.

http-get {

    set uri "/s/ref=nb_sb_noss_1/167-3294888-0262949/field-keywords=books";

    client {

        header "Accept" "*/*";

        metadata {
            base64;
            prepend "session-token=";
            append "csm-hit=s-24KU11BB82RZSYGJ3BDK|1419899012996";
            append "; skin=noskin";
            header "Cookie";
        }
    }

Note: This metadata block will fail a c2lint check because of the space between ; and skin=noskin. c2lint’s advice is sound, but risk averse. Here, the space is necessary to match what we will receive after passing an HTTP transaction through CloudFront.

This blog post focuses on CloudFront because I’ve answered questions about this circumstance in the past. Profile assumptions can fail for other reasons. For example, if you change a profile mid-engagement, expect to see issues like this one. If your HTTP communication fails, due to broken profile assumptions, these steps can help you diagnose the issue and correct your profile.

h1

PowerShell Shellcode Injection on Win 10 (v1803)

May 24, 2018

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.

h1

Fighting the Toolset

April 23, 2018

What happens when your advantages become a disadvantage? That’s the theme of Fighting the Toolset. This lecture discusses Offensive PowerShell, staging, memory-injected DLLs, and remote process injection as technologies that deliver(ed) a universal advantage to attackers.  Today, that’s not always the case. In some contexts, these technologies are the tell that gives you away. In other contexts, they continue to deliver as advertised. This lecture is all about how to adapt when your advantages are your weakness.

 

h1

Cobalt Strike 3.11 – The snake that eats its tail

April 9, 2018

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.

h1

Beware of Slow Downloads

March 9, 2018

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.

h1

In-Memory Evasion

February 8, 2018

Many analysts and automated solutions take advantage of various memory detections to find injected DLLs in memory. Memory detections look at the properties (and content) of processes, threads, and memory to find indicators of malicious activity in the current process.

In-memory Evasion is a four-part mini course on the cat and mouse game related to memory detections. This course is for red teams that want to update their tradecraft in this area. It’s also for blue teams that want to understand the red perspective on these techniques. Why do they work in some situations? How is it possible to work around these heuristics in other cases?

Part 1 of In-memory Evasion introduces Memory Detections. This lecture walks through the observable properties of Processes, Threads, and Memory with Process Hacker. Common heuristics, the in-memory indicators we want to evade, are covered too.

Part 2 of In-memory Evasion goes through A Payload’s Life. This lecture discusses the heuristics in Part 1 and where they interact with actions taken by a representative offense platform (in this case, Cobalt Strike). This lecture makes the case that offense toolsets do strange things, but in some cases, these deviations from normal program behavior are optional.

Part 3 of this course discusses Evasion. General tips to avoid the strange behavior these detections find are discussed. This lecture then gets into the meat: options to configure how Cobalt Strike’s Beacon payload lives in memory are explained and demonstrated. This lecture also shows how to conduct an OPSEC review of your configuration prior to action on a target. Finally, this lecture concludes with a discussion on process context and how it influences the amount of suspect actions/indicators an automated solution will allow.

Part 4 concludes the course with a brief discussion of Threat Emulation. Cobalt Strike’s flexibility in this area is demonstrated to steer an analyst to believe they’re dealing with a specific real-world actor in a simulated incident.

Part 5 is an April 2018 addendum to this course. This video covers the memory-related threat emulation and evasion features in Cobalt Strike 3.11.

I’m a big believer that red teams should know the defenses they work with and know how their tools interact with these defenses. The area of memory detections has developed considerably over the past several years. Whether you’re on the red or blue side, I hope you find this perspective helpful.