Havoc Extensions In-Depth

go back / p4p1


Created on Fri. 22 Dec 2023



After answering a lot of messages on Discord and other I realised I was answering most of the time the same questions and this is a great way to explain my point in a more in depth way. I realised that a lot of people writing extensions either don't really know where to start. Or are confused on how to get it on the Store / Extensions Tab.

This post has the main focus on explaining from scratch how to get up and running on Havoc extensions. All of the resources I wrote and where to find them. I'll also be diving in the code of the havoc Extensions tab and the store website since those are both synced.

Hopefully this post covers most things, I will also in the future update this post in case there are some questions that come often. Let's get started! Main objective should be getting you extension on the previous page ^^.

Initial Setup

So in all the examples I will note that I am running a Linux laptop. I have no idea how you would develop things like this on windows. I'm pretty sure it's as easy I wouldn't see why but I haven't tried it so I cannot explain. The laptop is running Arch-Linux specifically but what I will explain is distro independent. You will need a few tools and things. Here is a list of what you need installed on your linux machine:

  • - Havoc
  • - havoc's dependencies: 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
  • - git
  • - python
  • - Any text Editor
  • - A Github Account (make one here)
After gathering all of this we can now setup our environment and installing Havoc. I recommend saving your install inside of /opt but you can just go install it where you want. On my machine I just ran the following commands:

          
          sudo chown $(whoami):$(whoami) /opt/ # giving my user ownership of the folder
          cd /opt/
          git clone https://github.com/HavocFramework/Havoc
          cd Havoc
          make # build everything
          
        

Note that if this section is not working like I am showing I can also recommend going through this tutorial to install havoc since on different machines it will be different. After installing run the server and the client with

          
          ./havoc server --profile ./profiles/havoc.yaotl -v --debug # for server
          ./havoc client # for the client
          
        

From here you can navigate the UI and go to Scripts -> Script Console This is where you will find a python interpreter where you can interact with Havoc's client app. Type in the following line for you first Hello World type of program

          
          havocui.messagebox("Hello", "Hello World!")
          
        

The development workflow

Now this is the bit where you can now build your extensions. The first thing in the development workflow will be getting your external script files in havoc then from there I'll showcase documentation and I'll explain two kinds of script the command line ones and the GUI ones.

Importing scripts

With havoc open and ready to make extensions create a python script file on your computer you can call it what you want and you will need to import the Havoc API. For GUI apps you will need to import havocui for things that are core functionality to the client like demons listeners you can import havoc I will now showcase this inside of a simple test script.

          
          import havoc
          import havocui

          result = havoc.GetDemons()
          havocui.messagebox("Demon Number", "You have %d demons connected" % len(result))
          
        

After saving this file you can open the Script Manager inside of Script / Scripts Manager and load them through the Load Script button:

After loading this script you should get a pop-up with the number of demons that you have inside of Havoc:

If you then modify the script let's say we want the number of listeners instead of the number of Demons we can change the GetDemons function to GetListeners like so:

          
          import havoc
          import havocui

          result = havoc.GetListeners()
          havocui.messagebox("Listener Number", "You have %d listeners" % len(result))
          
        

You can now reload the script inside of the Scripts Manager by right clicking the script and selecting Reload:

Once you clicked on Reload the script will automatically be re-executed by Havoc where you should see our changes:

Now they are a lot of functions and scripts that can be used to interact with havoc in this tutorial I will not be going through all of the functions but I will showcase where you can find the documentation.

Finding Documentation and Functions

Currently they are a few places to find the different API functions. The first and main one is the official website. Inside of the Client Script section. Now as of today (22 Dec 2023) the Documentation is not published online but it is on the website inside of the Dev branch (here).

The second place where you can find API information is on different blog posts. There is obviously the ones on this blog where I explain how I coded some of the API functions I do not explain how I coded all of them but they are a great first step in deciphering the API if you want to understand how they work. Also some people that have made modules for the store also did blog posts on how they made them. Like Jakob's one here is one that is coming to my mind right now and I am sure they are many others.

The last way to find how some functions work is by actually reversing them through the code. Here is a quick crash course on how to do that. First of all the dir() function in python is brilliant of quick lookup of what has what function inside of the API. I actually used this to make the example above since I don't know everything by heart I still have to lookup the syntax of some functions so inside of the Script Console I would quickly print the result of a dir to see what module has what function:

          
            print(dir(havoc))
          
        

This will list out all of the functions available like so:

Most of the API source code is fond inside of the Havoc Repository under client/src/Havoc/PythonApi/. Here it has all of the definition and logic of all of the functions. Here is a quick explanation of the different files found here:

          
  client/src/Havoc/PythonApi/
  ├── Event.cc                # Function to define triggers on events
  ├── Havoc.cc                # The main module initial functions
  ├── HavocUi.cc              # The main UI module initial functions
  ├── PyAgentClass.cc         # The class to handle agents
  ├── PyDemonClass.cc         # The class to handle Demons
  ├── PythonApi.cc            # The main python initialisation in C++ you can ignore this one
  └── UI
      ├── PyDialogClass.cc    # The HavocUI dialog class
      ├── PyLoggerClass.cc    # The HavocUI Logger class
      ├── PyTreeClass.cc      # The HavocUI Tree class
      └── PyWidgetClass.cc    # The HavocUI Widget class

  2 directories, 10 files
          
        

These files are mostly all constructed the same, you want to look at the variable called Py{Somethis}Class_methods[] this is where you can find the different methods for the class / library:

With all of this information you should now be able to create an amazing extension!

Publishing an extension

Currently extensions are managed in two ways, we have the hard coded extensions that are present in the Modules repository:

Hard Coded way

These modules like mentioned are hard coded inside of the Havoc client so if you wish to add a module through here you will need to make sure that inside of the Havoc client you import them correctly:

The second way to publish a module is Externally and dynamically with this method you are able to push updates to your extensions independently from the code being merged into main it does mean that if your code breaks havoc I'll be removing your extension from the page but if you follow a few principles it should be fine.

Dynamic way

Inside of Havoc for every user there is a section inside of Attack called Extensions:

These extensions are hosted on the following link https://p4p1.github.io/havoc-store/havoc-modules.json. This website that has the extensions is hosted on my end through github pages. Anyone can publish there extensions on the web page through creating a pull request, more on this later(store section). All these extensions can be installed through a user clicking the Install button on the GUI a little bit like Burp Extender. I am first going to go in depth on how this part of Havoc works so that there is no confusion of what you need to do when you want it to work correctly. Currently you can only host you payloads on Github I decided to build it this way to simplify everything since currently most of the extensions I have seen are on GitHub. You can either have a module that is single file (hosted as a github gist) or a bigger project through a github repository. To download the github repo's on the client end the client runs this function:

          
  git clone --recurse-submodules --remote-submodules ${yoururl} ${havoc_install_path}/data/extensions/${your_reponame}
          
        

With this command it allows extension developers to directly add to their workflow any dependencies without needing to ask for to much user input.

The json file that has all of the extensions has an entry called entrypoint This is the script inside of the repo that needs to be loaded into havoc in the back ground after cloning the repository on selecting the Install button it will take that entrypoint and automatically add it to the script Manager. Because of all of this there are a few mistakes and best practices you should follow

Best Practices

The first one is do not use os.chdir() if your python script changes directory to often that is not normal. Since a lot of the paths inside of Havoc are relative paths where the execution area is always at the base of the program we expect everything to be there. I also recommend to even just navigate to your data/extensions directory create a folder there and start development inside of that folder. This is just how the Extensions tab functions so if you just do it like that there will be no surprises.

Havoc-Store

Havoc-Store is the webpage that hosts the list of extensions for havoc here you can view different extensions and maybe add your own ^^

To do that just navigate to the havoc-store github repository and Fork the project.

From there you need to locate the havoc-modules.json file it is currently located inside of public/havoc-modules.json. You will then need to create you own entry in the json following this syntax:

          
  {
    "title":"your title",
    "description":"Your description",
    "author":"Your username on github",
    "link":"the link to the module",
    "preview":"The preview image of the module",
    "entrypoint":"script.py",
    "category": {
      "BOF": false,
      "Console": false,
      "Graphical": true
    }
  }
          
        

After that do a pull request where I will go through the script test it locally on my end and from there I'll accept it.


Well well well, you have read all of the post on making an extension. I hope all of this explains how you can make your own extensions for havoc follow me on twitter and on github where I do posts on new havoc extensions and more projects I build.

p3ng0s
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!
Donate
sponsor me image

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