Self-Hosting Havoc C2 / or any other C2 in Docker

Running Havoc C2 server and client in Docker

Why though ? and its not new

Well, its nothing new. However, recently I was stuck and wanted to run Havoc C2 on Windows. I didn't had a lot of choice. Running a VM is an obvious choice, but why run full OS with its large footprint on system memory. Plus I have pushed myself to run everything on docker. Here's how I over did it 😂

Docker Compose

We'll be running multiple services so we will use docker-compose

Installing Havoc C2 Teamserver on docker

Installing Havoc C2 is pretty much officially documented here. Well follow the same steps.

Lets create a teamserver.Dockerfile

# Using the latest debian OS
FROM debian:latest 
# Making teamserver directory and moving to it
WORKDIR /teamserver 
# Installing the requirements. 
# Added wget, sudo and setcap (libcap2-bin ) as they are required later in the build stage
RUN apt update -y && apt install -y git build-essential apt-utils cmake \
    libfontconfig1 libglu1-mesa-dev libgtest-dev libspdlog-dev \
    libboost-all-dev libncurses5-dev libgdbm-dev libssl-dev libreadline-dev \
    libffi-dev libsqlite3-dev libbz2-dev mesa-common-dev qtbase5-dev \
    qtchooser qt5-qmake qtbase5-dev-tools libqt5websockets5 \
    libqt5websockets5-dev qtdeclarative5-dev \
    golang-go qtbase5-dev libqt5websockets5-dev python3-dev \
    libboost-all-dev mingw-w64 nasm \
    wget sudo libcap2-bin 
# Cloning the Repo
RUN git clone .
# Installing Mods
WORKDIR /teamserver/teamserver
RUN go mod download && \
    go mod download
#Building Teamserver 
WORKDIR /teamserver
RUN make ts-build
#Running Havoc
ENTRYPOINT ["/teamserver/havoc", "server" ,"--profile", "/teamserver/profiles/havoc.yaotl","-v","--debug"]

Installing Havoc C2 Client

Now this is where fun begins. The client is GUI and this requires a couple of tweaks in the Dockerfile before we can reliably run client.

One way is to forward X11 using SSH. While this may work, I am not a fan boy of forwarding X11 because it can get really slow.

Another option is to run the client in a VNC and use browser to access it. This to me seems like a viable option.

We will use NoVNC. You can also use KASMVNC but what good am I if I leaked all the goodness in one blog post. So we'll stick to NoVNC.

Since out client container consists of multiple components (client + GUI), we need to use a process manager to launch and monitor them. Here, we’ll be using supervisord. supervisord is a process manager written in Python that is often used to orchestrate complex containers.

First, we'll create and enter a directory called havoc-client for our container

mkdir ~/havoc-client
cd ~/havoc-client

Then we'll make a supervisord configuration file

Last updated