Skip to content
kthreatt edited this page Sep 1, 2026 · 1 revision

Client

The operator client is a C++ / Qt5 application with an embedded CPython interpreter (raw CPython C API, no pybind11). Root: client/, built with CMake (client/CMakeLists.txt).

Source layout

  • client/src/Main.cc: main(): QApplication + HavocSpace::Havoc::Init() + event loop.
  • client/src/Havoc/
    • Havoc.cc: application class; parses --debug / --config <path>, loads the TOML config (toml11), opens the Connect dialog.
    • Connector.cc: owns the QWebSocket; builds wss://<Host>:<Port>/havoc/. SSL verification defaults to QSslSocket::VerifyPeer and is only set to VerifyNone when the profile has IgnoreSSLErrors set (Connector.cc:17-33). The Connect dialog has an "Ignore SSL errors" checkbox for self-signed teamserver certs (Dialogs/Connect.cc:202,368). Dispatches binary messages to the Packager.
    • Packager.cc: protocol encode/decode/dispatch (see Client Teamserver Protocol).
    • Service.cc: only holds DemonMagicValue = 0xdeadbeef to distinguish Demon from service agents.
    • DBManger/: SQLite (data/client.db): the Teamservers table stores saved profiles (name, host, port, user, password hash, IgnoreSSLErrors) and the Scripts table stores script paths. Saved profiles persist PasswordIsHashed (the stored password is the SHA3-256 hash; if unchanged on reconnect it is re-sent as-is instead of re-hashed, Connector.cc:201-203, migration in DBManager.cc:32,57).
    • Demon/: Commands.cc (built-in command metadata), ConsoleInput.cc (console input parsing), CommandSend.cc / CommandOutput.cc.
    • PythonApi/: embedded Python bindings (see Client Python API).
  • client/src/UserInterface/
    • HavocUi.cc: builds the main window; PythonPrepare() registers the emb/havoc/havocui modules and calls Py_Initialize().
    • Widgets/: TeamserverTabSession (per-teamserver page), SessionTable, ListenersTable, Chat, LootWidget, SessionGraph, DemonInteracted (per-agent console), ProcessList, FileBrowser, ScriptManager, PythonScript (in-app Python console), Store, Teamserver (log view).
    • Dialogs/: Connect, Listener, Payload, About.
  • client/include/global.hpp: shared state: Util::ConnectionInfo (with ServiceAgents, RegisteredListeners, RegisteredCommands, ...), Util::SessionItem, and the HavocX:: globals.

Connect / auth flow

  1. The Connect dialog lists saved profiles (SQLite): name, host, port, user, password, and an "Ignore SSL errors" checkbox.
  2. Connector opens wss://host:port/havoc/ with QSslSocket::VerifyPeer (or VerifyNone when "Ignore SSL errors" was checked / the saved profile has IgnoreSSLErrors).
  3. On connect it sends the login package: Head.Event = 0x1, Body.SubEvent = 0x3, Info = { User, Password = hex(SHA3-256(password)) } (QCryptographicHash::Sha3_256), unless the saved profile's PasswordIsHashed is set and the password was not edited, in which case the stored hash is re-sent as-is.
  4. On InitConnection::Success the main UI is built, autoload scripts from config.toml are executed, and the server replays its event log to reconstruct state (listeners, sessions, chat).

UI structure

Main window (HavocUi::setupUi): menus Havoc (New Client / Disconnect / Exit), View (Listeners, Session View → Table/Graph, Chat, Loot, Event Viewer, Teamserver), Attack (Payload, Extensions; the Extensions item opens the Store widget), Scripts (Scripts Manager, Script Console), Help (About / Open Documentation / Open API Reference / Github Repository). The central TeamserverTabWidget holds one tab per connected teamserver; each tab has the session table on top and dockable bottom/small tabs (agent consoles, chat, file browser, process list, Python widgets). The SessionGraph view renders SMB pivot links as edges attached to the pivot parent's node (Widgets/SessionGraph.cc:171-255). The LootWidget has Screenshots/Downloads filters with a per-agent combobox, context-menu "Get file" actions (Loot GetFile wire request) and click-to-preview of content.

SmallWidgets/EventViewer.cc (the Event Viewer dock) lives outside the Widgets/ directory in the source tree.

client/config.toml

[font]
size   = 9
family = "Monospace"

[scripts]
files = [ "client/Modules/.../*.py" ]   # autoloaded on connect

CLI flags: --debug (spdlog debug logging), --config <path> (default: client/config.toml, then config.toml).

Note: this repo ships no example Python modules, but make client-build clones the community modules repo (github.com/CyberAZE-community/Modules, branch dev) into client/Modules/, which is what the default config.toml paths point at. The Store widget (Attack → Store) fetches community extensions from https://raw.githubusercontent.com/p4p1/havoc-store/main/public/havoc-modules.json (client/src/UserInterface/Widgets/Store.cc:14).

Clone this wiki locally