Skip to content

Client Python API

kthreatt edited this page Sep 1, 2026 · 1 revision

Client Python API

The client embeds CPython and registers three modules at startup (HavocUi::PythonPrepare()): emb (stdout redirection), havoc (C2 operations), havocui (Qt UI building). Bindings live in client/src/Havoc/PythonApi/.

Loading scripts

  • Autoload on connect: the toml ["scripts"] files list is parsed and executed in Packager.cc:189-193 after login (only [font] is parsed in Havoc.cc:64-66).
  • Persisted scripts (SQLite) are reloaded at startup by HavocUi::PythonPrepare(): each script triggers a Yes/No trust confirmation dialog ("Scripts run unsandboxed…") before execution (HavocUi.cc:686-708).
  • Runtime loading: menu Scripts → Scripts Manager, the Script Console, or havoc.LoadScript(path).

havoc module

Functions:

  • LoadScript(path) -> bool
  • GetDemons() -> list[str]: Demon session IDs
  • GetListeners() -> list[str]
  • GetAgents() -> list[str]: agent type names ("Demon" + registered service agents)
  • GeneratePayload(callback, agent, listener, arch, format, config): async payload build; base64 payload delivered to callback
  • RegisterCommand(function, module, command, description, behavior, usage, example, agent="Demon"): adds a console command; function(demonID, *args); re-registering replaces
  • RegisterModule(name, description, behavior, usage, example, options)
  • RegisterCallback(callable): called on new-session events

havoc.Demon class

Demon(DemonID="<id>"). Attributes: Listener, DemonID, ExternalIP, InternalIP, User, Computer, Domain, OS, OSBuild, OSArch, ProcessName, ProcessID, ProcessArch. Constants: CONSOLE_INFO=1, CONSOLE_ERROR=2, CONSOLE_TASK=3.

Methods:

  • ConsoleWrite(type, message): with CONSOLE_TASK returns a generated TaskID
  • ProcessCreate(TaskID, App, Cmdline, Suspended, Piped, Verbose)
  • InlineExecute(TaskID, EntryFunc, Path, Args: bytes, Threaded: bool): BOF/COFF execution
  • InlineExecuteGetOutput(callback, EntryFunc, Path, Args: bytes) -> TaskID: output routed to callback
  • DllSpawn(TaskID, DllPath, DllArgs: bytes)
  • DllInject(TaskID, Pid, DllPath, DllArgs: bytes)
  • DotnetInlineExecute(TaskID, Path, Args)
  • ShellcodeSpawn(TaskID, InjectionTechnique, TargetArch, Path, Arguments: bytes)
  • Command(TaskID, Command) / CommandGetOutput(TaskID, Command, callback)

havoc.Agent class (third-party agents)

Agent(AgentID). Constants: CONSOLE_INFO/ERROR/TASK. Methods: ConsoleWrite(type, msg), Command(TaskID, Name, CommandArg: bytes): sends an AgentCommand package to the service agent's controller.

havoc.Event class

  • Event.OnNewSession(callable)
  • Event.OnDemonOutput: declared but unimplemented stub in this version.

havocui module

Functions: messagebox(title, content), errormessage(msg), questiondialog(title, content) -> bool, inputdialog(title, content) -> bytes, openfiledialog(title) -> bytes, savefiledialog(title) -> bytes, colordialog() -> bytes, progressdialog(title, text, callable, max), createtab(title, label1, callable1, label2, callable2, ...) (adds a menubar menu; flat label/callable pairs: a nested tuple like (label, callable) will fail).

Classes (dockable via setBottomTab() / setSmallTab(). Dialog is an exception: it is a modal dialog and has no docking methods):

  • havocui.Widget(title=..., scrollable=...): addLabel, addImage, addButton(text, callback, style=""), addCheckbox(text, callback, checked=False, style=""), addCombobox, addLineedit, addCalendar, addDial, addSlider, replaceLabel, clear
  • havocui.Dialog(title=..., scrollable=..., width=..., height=...): same add* methods plus exec(), close()
  • havocui.Logger(title=...): addText(text), clear()
  • havocui.Tree(title=..., callback=..., panel=...): addRow, setPanel, setItem

Limitations

  • The embedded Python API can register commands, modules, callbacks and UIs, but not agent types or listeners. Those are registered through the teamserver Service API (see Building a Third-Party Agent), typically via the external havoc-py library.
  • No example scripts ship in this repo; the community modules live in a separate repository.

Clone this wiki locally