One of my favorite features in Cobalt Strike is its ability to pivot over named pipes. A named pipe is a way for two programs on a Windows system to communicate with each other. From a programming perspective, working with a named pipe is a lot like working with a file.
I use named pipes to allow a beacon to receive its commands and send its output through another Beacon. In this way, a parent Beacon becomes the egress channel for its child Beacons.
This has some utility on the same host. Let’s say a target network tightly controls egress. Each system that wants to make an outbound web request must go through a proxy and authenticate to it. A Beacon that lives in user space will likely get out. An elevated Beacon run in a SYSTEM context will probably not get out. In these situations the named pipe Beacon has utility. An elevated Beacon can use the user-level Beacon’s channel to communicate with me. Sweet.
That’s not all though. Windows allows two programs to communicate, host-to-host, over named pipes. This communication is encapsulated within the SMB protocol. In this way, a named pipe pivot is not just communication on the same host, it’s also a way to control systems that can’t reach the internet with port 445 as a control channel. This is especially useful for lateral movement. It’s strange to make a domain controller egress to your internet-based infrastructure. A semi-mature security posture will detect and act on this very quickly. That said, it’s OK and expected for a workstation to connect to a domain controller or file server over port 445. A named pipe pivot is a way to blend in if you want to control these types of assets.
Cobalt Strike’s named pipe pivoting capability has had a long journey. I first introduced this feature in Cobalt Strike 1.48 (November 2013). At that time, this feature was just the named pipe channel and a few workflow flourishes to stage the SMB Beacon with a Metasploit Framework bind/reverse TCP stager.
This was a start, but it wasn’t enough to make great use of pivoting over a named pipe. I wanted the ability to deliver a Beacon to a target and control it entirely over port 445. This desire drove the implementation of the stageless Beacons in Cobalt Strike’s January 2014 release. A stageless artifact is one that contains the entire payload. It does not use a stager. A stageless SMB Beacon, exported as a service executable, would allow me to use the Metasploit Framework’s PsExec to deliver an SMB Beacon without a bind/reverse TCP stager. I considered this a good win for using the SMB Beacon for lateral movement.
While the Metasploit Framework’s PsExec module was nice, I wanted a way to conduct lateral movement through the Beacon payload. The February 2014 release of Cobalt Strike added token stealing and basic privilege escalation capability to Beacon. This capability, paired with several native commands, was enough to use Beacon for lateral movement.
If you ran into me at a conference in 2014, you probably saw a demonstration similar to this one:
In my 2014 demonstrations, I would show folks how to use Beacon as an operating capability. Lateral movement always makes a good demonstration. Sadly, the tools in Cobalt Strike didn’t do the job and sell the story. I had to rely on etherape in the target’s network, to show egress over one channel and peer-to-peer communication over another.
This demonstration crutch was my first signal that the named pipe pivoting required some sort of visualization. My use of Cobalt Strike was the second kick in the rear. Several times, I’ve found my teammates and I in a special ring of hell. Tracking 5+ levels of named pipe pivoting in a table is painful.
Which Beacon is linked to which? [Follow the chains in the external field!]
When I wrote the functional specification for Cobalt Strike 3.0, I knew I would need better tooling support to make named pipe pivoting useful to more of my users.
The first problem to solve was simple workflow. Cobalt Strike features that spawn a new payload always target a listener. Listeners are Cobalt Strike’s way to tie payload configuration information [and a promise to start that payload’s handler] to an easy-to-remember alias. It’s a simple abstraction, but it’s critical feature that allows one person to set up infrastructure and others to use it with fewer mistakes. I would need a way to make the SMB Beacon into a useful Cobalt Strike listener. This required solving a problem I did everything I could to avoid: staging.
I didn’t have a way to stage the SMB Beacon over a named pipe. I opted to implement a half-measure to solve this problem. I built a windows/beacon_smb/bind_tcp payload into an early build of Cobalt Strike 3.0. This listener would only work with Beacon actions that spawned a payload from the current session (privilege escalation, spawn, inject, etc.). To support a bind listener in Beacon, I instrumented Beacon’s implementation to follow any use of bind listener with a special Beacon task to deliver the Beacon stage. In this way, I could have a Beacon calling home, once every five minutes, inject a bind TCP stager into memory and complete the staging process without tunneling something through the Beacon.
Since the February 2014 release of Cobalt Strike, I’ve had folks ask: why don’t you add lateral movement automation to Beacon? I couldn’t. All Cobalt Strike features target listeners. If I were to add lateral movement automation, I would need to solve the staging problem for the SMB Beacon or have lateral movement automation without the SMB Beacon [not acceptable]. Eventually, I put together a named pipe stager for Beacon and built the lateral movement automation so many folks asked for. The windows/beacon_smb/bind_tcp payload became windows/beacon_smb/bind_pipe. I shipped this work as part of Cobalt Strike 2.5 in July 2015.
Cobalt Strike 3.0 completed the journey for the SMB Beacon feature. In 3.0, I added visualization for the SMB Beacon. Here’s what it looks like:
I no longer have to use etherape to visualize or describe my pivoting. ☺ Cobalt Strike’s workflows and dialogs expose the automation in Cobalt Strike’s Beacon for lateral movement. It’s now just as easy to deliver and use a named pipe payload in CS 3.0 as it was to deliver a bind_tcp meterpreter payload in Armitage:
Named pipe pivoting is one of my favorite features in Cobalt Strike. With the release of 3.0, the tooling support for this feature is now complete. It took nearly two years to get this feature to this point, but good things take a while. As you spend time to become familiar with Cobalt Strike 3.0, this is one feature I recommend spending some time with.