Havoc C2 Python API

go back / p4p1

Created on Sat. 02 Sept 2023

Oy Oy! I am back have been hard at work for the past 2 months trying to build cool things! Between finishing my linux distro, a new front-end for xss_bomb my new sales page and completing rastalabs and offshore!

Let's just say I have had many sleepless nights and a lot of things to wrap up. When I started this year I had for objective to wrap up a lot of the stuff I started the last 2 years and starting to plan what I will do next in my life. So to "celebrate" the past 2 months of wrapping up I am doing a series of blog posts back to front starting with the havoc c2 work and finishing with my distro since that is the first thing I wrapped up.

The Havoc C2

For rastalabs and offshore I wanted to setup a command and control framework so that I could learn how these cool pieces of kit work and how they could improve my framework. My mates mostly use cobalt strike and I thought if I was going to pick one I was going to get one that was open source so that I could potentially add to it in some way and understand exactly how it works. The Havoc C2 is actually quite simple with a server written in go a GUI client with dracula theme in C++ and clients (implants or deamons) written in C. Since C is my favourite programming language Havoc was a no brainer pick.

The endpoints located on the infected machines are called deamonds like mentioned previously they are created in C and Assembly. These deamonds can be controlled through the C++ qt interface client which is what I focused my work on in this post.

Compiling the server

To compile the server it is quite easy you need the following packages installed on your system:

            sudo pacman -S git gcc base-devel cmake make fontconfig glu gtest spdlog boost boost-libs ncurses gdbm openssl readline libffi sqlite bzip2 mesa qt5-base qt5-websockets python3 nasm mingw-w64-gcc go

And you will need to run the following command:

            make ts-build

After you can run the server as such:

          ./havoc server --profile profiles/havoc.yaotl -v

The profile files are used to configure the server behaviour on startup.

Compiling the client

The packages for the client are the same as the server so I would recommend to have all of them installed to make sure everything works as expected. You can build the client with the following command:

            make client-build

After that you can run the havoc client with the following command:

            ./havoc client

After logging in you should be presented with the following window:

Creating deamonds

To create a deamond you will first need a listener setup on havoc. This can be done through View -> Listeners -> Add.

You then can create payloads through Attack -> payloads.

After running the agent on the targeted machine you will see it appear in the client list:

The Python API

The Havoc clients come bundled with a scripting API to automatically do actions on the demons. By default there are modules automatically loaded into python from this API like bofbelt which is a simple port of seatbelt to guide in privileges escalation:

These python scripts can be interacted with through the Scripting Console and the Script Manger:

With the python API you can work with 3 main parts (demons, the havoc UI, Event which is not yet implemented as of September 2023). In this post I will cover the API for the demons and the HavocUI since the later is what I personally worked on.

Demons API


A function that will return a list of all of the connected demons:

havoc.InlineExecuteGetOuput(call_back, "go", "Objectfile/file.o", b'')

A function to call object files.

They are many more functions inside of the demon python API and I recommend going through the source of the client to discover them I just showcased these two to give an idea on what can be done ^^ source here.


Now this is the section I actually implemented so I will cover how to use each function and how to script with those functions. Except the first function messagebox which was already implemented.

havocui.messagebox("title", "message")

A function to have a popup from the havoc UI

havocui.createtab("tab title", "first element", callback_function, ...)

A function to add a tab to the havoc ui window.

havocui.inputdialog("title", "message")

A function to open a dialog menu to get a users input


A function to open a file dialog menu and get the path of the file opened.


A function to open a save file dialog menu to get the path of the file saved.

havocui.questiondialog("title", "question")

A function to open a dialog for a Yes/No question. This will return a boolean of True if pressed Yes and False if pressed No.


To implement these functionalities it was quite a struggle for me since I haven't done C++ since my second year of college and even back then I remember hating C++ so getting in the mood to do this addon was a pain for me to be fair. I am still glad I did since I learned a lot on how to extend python from a C/C++ perspective. I first started by trying to build the createtab function since that was my main objective on what to implement. To have the behaviour I wanted I needed to be able to call the menubar QT class since QT works in a cool way where you can specify a parent to append to directly so I thought if I could just append the QT elements directly on the QT bar creating tabs on the fly would be quite easy.

To get access to this behaviour I also studied how does the rest of the python API gain access to the Agent classes and data? I discovered of this cool global variable called HavocX where that data was stored.

So I added a pointer to the main HavocUI class where all of the variables to manage the UI are stored. From there it was quite simple to access directly through:


With all this defined I started working on the logic of the functions. I wanted to have infinite arguments on the create tab so I thought adding a loop would work perfectly:

From here it's quite simple I treat the 1st argument differently since it will represent the title of the tab and then the rest is just a succession of the title then the function callback that will run whatever we define inside of the script:

This implementation is not the best since the lack of cleanup of pointers but for now at least it works and can be improved in the future. I thought since that sections of the source code was not getting a lot of attention I should quickly bang up a solution temporally plus now I can start implementing more advanced scripts inside of my havoc workflow.

With these cool functions it is now possible to extend Havoc a bit more and add cool automation and nicer looking menu's for addons inside of Havoc. I hope you will find those functions I implemented inside of Havoc usefull and will be able to extend that command and control framework! Follow me on github to see what I contribute to next.

arch linux iso

A linux distribution with my entire config pre-installed. Great for learning linux and pentesting with a steep learning curve.

wiki | repo
Questions / Feedback
For any questions or feedback you can contact me on LinkedIn or twitter / X. I also use twitter as a platform to update on new posts!
sponsor me image

If you like the content of my website you can help me out by donating through my github sponsors page.