External C2
External C2 lets a custom process act as the communication bridge between the Mugen teamserver and an agent. This enables non-HTTP transports: DNS, ICMP, Slack, Teams, Twitter, or any custom channel.
Architecture
Section titled “Architecture”Agent <--custom channel--> ExternalC2 process <--WebSocket--> TeamserverThe ExternalC2 process connects to the teamserver via the Service API WebSocket, registers an External C2 listener, and relays raw agent packets in both directions.
Requirements
Section titled “Requirements”Enable the Service API in your profile:
Service { Endpoint = "service-ws" Password = "service-password"}Using havoc-py
Section titled “Using havoc-py”havoc-py provides a Python SDK that handles the WebSocket protocol. It is compatible with the Mugen teamserver.
pip install -r requirements.txtfrom havoc.service import HavocServicefrom havoc_externalc2 import ExternalC2
service = HavocService( endpoint = "wss://teamserver:40056/service-ws", password = "service-password")
# register the ExternalC2 listenerc2 = ExternalC2(service, name="my-externalc2", endpoint="/externalc2")c2.start()The Mugen teamserver then relays agent traffic through this listener.
Protocol
Section titled “Protocol”The ExternalC2 process communicates with the teamserver over JSON WebSocket messages. Key message types:
| Type | Direction | Description |
|---|---|---|
Register |
-> server | Authenticate with password |
ListenerExC2 |
-> server | Register an ExternalC2 listener |
ListenerTransmit |
<- server | Forward agent packet to the C2 channel |
ListenerTransmit |
-> server | Forward agent response back to server |
Raw agent packets are base64-encoded in the Request field.
- The ExternalC2 process runs outside Mugen - it is your responsibility to implement and deploy it.
- The Mugen client does not need to be open for ExternalC2 to function - only the teamserver needs to be running.
- Multiple ExternalC2 listeners can be active simultaneously.
