Cobalt Strike supports third party command and control by allowing external components to act as a communication layer between the Team Server and a Beacon payload.  Fundamentally, the Team Server and Beacon send frames to each other encapsulated over some transport mechanism.  Out of the box, CS can do this over HTTP, DNS, TCP and SMB, but there's nothing stopping us from encapsulating those frames over something else.  This is what External C2 allows.

Conceptually, that can look something like this:

![[14. External C2.png]]


When an External C2 "listener" is started, it exposes a port (2222 by default) on the Team Server.  A 3rd party **controller** may connect to this port over TCP and exchange data.  A 3rd party **client** talks to the controller via any means the operator can think up.  This could be directly over a protocol such as HTTP, DNS, SSH, FTP, etc (anything that the operator knows will egress the target network boundary).  It could also be indirectly via a legitimate external service, such as Office365, Slack, Google Drive and so on (or even a mixture of the two).  The only requirement is for the two components to be able to exchange data "somehow".

The client will request a new Beacon stage from the controller and the controller relays that to the Team Server.  The Team Server gives the controller an SMB Beacon, which gets relayed to the client.  The client then loads the Beacon into memory and connects to its named pipe.

They then drop into a simple process of relaying frames back and forth.  The flow goes like this:

![[15. External C2.png]]

The [External C2 Specification](https://www.cobaltstrike.com/downloads/externalc2spec.pdf) provides the low-level details such as the Beacon frame structure, and is well worth a read.  There are also several libraries out there that implement this spec, which you can utilise to build your own controller and client applications.  Some notable ones include:

-   [https://github.com/Und3rf10w/external_c2_framework](https://github.com/Und3rf10w/external_c2_framework) (Python)
-   [https://github.com/rasta-mouse/ExternalC2.NET](https://github.com/rasta-mouse/ExternalC2.NET) (.NET)
-   [https://github.com/outflanknl/external_c2](https://github.com/outflanknl/external_c2) (C++)

Here's a fun example of External C2 over Discord.

https://www.youtube.com/watch?v=OB4Xk2bCaes

