Skip to content

API Reference

import tuoni

tuoni.agents       # Agent management
tuoni.commands     # Command execution & alias registration
tuoni.discovery    # Host/service/credential management
tuoni.events       # Event system

# Execution configuration classes
tuoni.NewExecutionConfiguration
tuoni.SelfExecutionConfiguration
tuoni.ExistingExecutionConfiguration

tuoni.agents

Query and access connected agents.

Method Returns Description
all() list[Agent] All agents, including inactive
all_active() list[Agent] Only currently active agents
get(guid: str) Agent Get a specific agent by its GUID
1
2
3
4
5
6
7
8
9
import tuoni

# List all active agents
for agent in tuoni.agents.all_active():
    print(f"{agent.guid} - {agent.type} - {agent.metadata.hostname}")

# Get a specific agent
agent = tuoni.agents.get("550e8400-e29b-41d4-a716-446655440000")
print(agent.is_active())

tuoni.commands

Register aliases, send commands to agents, and manage command lifecycle.

Method Returns Description
register_dynamic_alias(name: str, alias) None Register a dynamic alias with explicit name
register_dynamic_alias(alias) None Register using alias.name attribute
queue_command(agent_guid, template, config, exec_config=None) SentCommandContext Send a command to an agent
find_by_id(command_id: int) CommandState Look up a command by ID
all() list[CommandState] List all commands
stop(command_id: int) CommandState Stop/cancel a running command
update_command(command_id: int, config: dict) CommandState Update a command's configuration

Sending Commands Directly

Outside of alias execute() methods, use tuoni.commands.queue_command() to send commands:

import tuoni

def on_new_agent(event, agent):
    cmd = tuoni.commands.queue_command(
        agent.guid,
        "sh",
        {"command": "hostname"}
    )
    cmd.wait_for_finish()
    if cmd.is_success():
        print(f"Agent hostname: {cmd.get_result()['STDOUT']}")

tuoni.events.register_callback_by_event_type("REGISTER_AGENT", on_new_agent)

Alias Context vs Direct Commands

Inside an alias execute() method, use ctx.queue_command() (on the AliasContext). Outside of aliases (e.g. in event handlers or top-level script code), use tuoni.commands.queue_command().


tuoni.discovery

Add discovered hosts, services, and credentials to Tuoni's discovery database.

tuoni.discovery.hosts

1
2
3
4
5
tuoni.discovery.hosts.add(
    address="192.168.1.10",      # Required
    name="web-server",           # Optional
    note="discovered via script"  # Optional
)
Parameter Type Required Description
address str Yes IP address or hostname
name str No Display name
note str No Freeform note

tuoni.discovery.services

1
2
3
4
5
6
7
tuoni.discovery.services.add(
    address="192.168.1.10",      # Required
    port=22,                      # Required
    protocol="tcp",               # Optional
    banner="OpenSSH 8.9",        # Optional
    note="discovered via script"  # Optional
)
Parameter Type Required Description
address str Yes Host address
port int Yes Port number
protocol str No Protocol name (e.g. tcp, udp, ssh)
banner str No Service banner or version
note str No Freeform note

tuoni.discovery.credentials

1
2
3
4
5
6
7
8
tuoni.discovery.credentials.add(
    username="admin",             # Required
    password="secret",            # Required
    host="192.168.1.10",         # Optional
    source="nmap",                # Optional
    realm="DOMAIN",               # Optional
    note="discovered via script"  # Optional
)
Parameter Type Required Description
username str Yes Username
password str Yes Password or hash
host str No Associated host
source str No How the credential was obtained
realm str No Domain or realm
note str No Freeform note

tuoni.events

Register callbacks for server events. See Event System for the full event type reference.

Method Returns Description
register_callback_by_event_type(event_type: str, callback) BackgroundTask Listen for a specific event type
1
2
3
4
5
6
7
8
9
import tuoni

def on_agent(event, agent):
    print(f"New agent: {agent.guid}")

task = tuoni.events.register_callback_by_event_type("REGISTER_AGENT", on_agent)

# Later, to stop listening:
# task.stop()

The callback signature is def callback(event: Event, data) -> None where data depends on the event's reference type.


Type Reference

Agent

Represents a connected agent. Received in alias methods and event callbacks.

Property / Method Type Access Description
guid str read Agent UUID (v4)
type str read Agent type: SHELLCODE_AGENT, GENERIC_SHELL_AGENT, EXTERNAL_AGENT
metadata AgentMetadata read Current agent metadata (property)
get_latest_metadata() AgentMetadata Same as metadata property
is_active() bool Whether the agent is currently active
1
2
3
agent = tuoni.agents.all_active()[0]
print(f"Agent {agent.guid} on {agent.metadata.hostname} ({agent.metadata.os})")
print(f"Type: {agent.type}, Active: {agent.is_active()}")

AgentMetadata

Agent metadata properties. Most properties are read/write — changes persist immediately to the server.

Property Type Access Description
guid str read Agent GUID
username str \| None read/write Process username
proc str \| None read/write Process name
pid int \| None read/write Process ID
working_dir str \| None read/write Current working directory
os str \| None read/write OS name (LINUX, WINDOWS)
os_major int \| None read/write OS major version
os_minor int \| None read/write OS minor version
ips str \| None read/write Space-delimited list of IP addresses
hostname str \| None read/write Machine hostname
process_arch str \| None read/write Process architecture (X64, X86)
os_arch str \| None read/write OS architecture (X64, X86)
ansi_code_page int \| None read/write Windows ANSI code page
integrity str \| None read/write Integrity level
agent_type str \| None read/write Agent type string
agent_version int \| None read/write Agent version number
features list read Supported agent features
payload_id int \| None read Payload ID used to create agent
listener_properties dict read Listener configuration
custom_properties dict read/write Custom key-value store

custom_properties

custom_properties is an observable dictionary. Setting or deleting keys is persisted to the server immediately — no save call required.

1
2
3
agent.metadata.custom_properties["team"] = "red"
agent.metadata.custom_properties["notes"] = "#tagged"
del agent.metadata.custom_properties["obsolete_key"]

Metadata vs Agent-Reported Data

Writing to metadata properties like username, pid, or hostname modifies the server-side record. The agent may overwrite these values on its next check-in if it reports updated metadata. Use custom_properties for data that should not be overwritten by the agent.


AliasContext

Available as the ctx parameter in an alias execute() method.

Method Returns Description
queue_command(template: str, config, exec_config=None) SentCommandContext Queue a sub-command for the agent
set_result(result: dict) None Set the alias result (can be called multiple times)
fail(message: str) None Mark the alias as failed
finish() None Mark the alias as successfully completed

See Dynamic Aliases for detailed usage.


SentCommandContext

Returned by ctx.queue_command() (inside aliases) or tuoni.commands.queue_command() (outside aliases).

Method Returns Description
wait_for_finish() None Block until the command completes
is_failed() bool True if the command failed
is_ongoing() bool True if the command has partial results but is not finished
is_success() bool True if the command completed successfully
get_error_message() str \| None Error message if failed, None otherwise
get_result() dict[str, str \| bytes \| File] Result items keyed by name
1
2
3
4
5
6
7
8
cmd = ctx.queue_command("sh", {"command": "id"})
cmd.wait_for_finish()

if cmd.is_success():
    result = cmd.get_result()
    stdout = result["STDOUT"]        # str
    # Some commands return files:
    # file = result["downloaded"]    # File object

Configuration

Provided to alias validate_config() and execute() methods. Contains the user-supplied input.

Property Type Description
json.as_str str JSON configuration as a raw string
json.as_dict dict JSON configuration parsed as a Python dictionary
bytes bytes Raw bytes (only for byte-array configurations)
files dict[str, File] Uploaded files, keyed by field name

Properties, Not Methods

json.as_str, json.as_dict, bytes, and files are properties — access them without parentheses:

1
2
3
4
5
6
# Correct
cfg = config.json.as_dict
raw = config.json.as_str

# Wrong — these are not methods
# cfg = config.json.as_dict()

File

Represents a file in Tuoni's file store. Returned in command results and configuration.

Property / Method Type Description
file_name str Original filename
file_id str UUID in Tuoni's file store
vfs_path str Path in the virtual filesystem (for open())
open(mode="rb") file object Open the file for reading

Supported open() modes: "r" (text), "rt" (text, explicit), "rb" (binary).

Read-Only

Files can only be opened for reading. Write modes are not supported.

# Read file contents as text
with result_file.open("r") as f:
    content = f.read()

# Read as bytes
with result_file.open("rb") as f:
    data = f.read()

# Alternative: use vfs_path directly
with open(result_file.vfs_path, "rb") as f:
    data = f.read()

CommandState

Represents a command's current state. Returned by tuoni.commands.find_by_id(), tuoni.commands.all(), and in event callbacks for command events.

Property Type Description
id int Command ID
command_template_id str Template identifier (e.g. "shelldot.commands.native:global:sh")
agent_guid str Target agent GUID
result CommandResult \| None Latest result, or None if no result yet

CommandResult

A single result received for a command.

Property / Method Type Description
command_id int Command ID
status str "FAILED", "ONGOING", or "SUCCESS"
error_message str Error details (empty string if no error)
receive_time str ISO 8601 timestamp of when the result was received
is_finished() bool True if this is a final result (success or failure)
items dict[str, str \| bytes \| File] Result data keyed by name
1
2
3
4
def on_command_result(event, cmd):
    if cmd.result and cmd.result.is_finished():
        stdout = cmd.result.items.get("STDOUT", "")
        print(f"Command {cmd.id} finished: {stdout}")

Event

Passed as the first argument to event callbacks.

Property Type Description
type str Event type name (e.g. "REGISTER_AGENT")
reference_type str \| None Reference type (e.g. "AGENT", "COMMAND")
time datetime When the event occurred

BackgroundTask

Returned by tuoni.events.register_callback_by_event_type(). Controls the lifecycle of an event listener.

Method Description
stop() Stop listening for events. Once all background tasks are stopped, the script can terminate.

DetailedDiscoveredHost

Received in event callbacks for discovery host events.

Property / Method Type Description
id str UUID
address str IP address or hostname
name str \| None Display name
note str \| None Note
is_archived() bool Whether the host is archived

DetailedDiscoveredService

Received in event callbacks for discovery service events.

Property / Method Type Description
id str UUID
address str Host address
port int Port number
protocol str \| None Protocol
banner str \| None Service banner
note str \| None Note
is_archived() bool Whether the service is archived

DetailedDiscoveredCredential

Received in event callbacks for discovery credential events.

Property / Method Type Description
id str UUID
username str Username
password str Password or hash
host str \| None Associated host
realm str \| None Domain or realm
source str \| None Source of the credential
note str \| None Note
is_archived() bool Whether the credential is archived

JobState

Received in event callbacks for job events (CREATE_JOB, UPDATE_JOB).

Property Type Description
id int Job ID
name str Job name
status str Job status
messages list[SavedJobMessage] Log messages
open_resources list[JobResource] Open resources (e.g. ports)
supported_actions set[str] Available actions

SavedJobMessage

Property Type Description
time str Timestamp
message_type str Message type
message str Message content
error_stack str \| None Error stack trace if applicable

JobResource

Property Type Description
type str Resource type (e.g. "port")
port int Port number (only for port resources)

Execution Configuration Classes

Control how commands are executed on the agent. Pass as the third argument to queue_command().

tuoni.SelfExecutionConfiguration()

Execute in the agent's current process context. This is the default when no execution configuration is provided.

tuoni.NewExecutionConfiguration

Spawn a new process for command execution.

1
2
3
4
5
6
7
exec_cfg = tuoni.NewExecutionConfiguration(
    executable="cmd.exe",   # Optional: path to executable
    suspended=False,         # Optional: start suspended
    ppid=4567,               # Optional: parent PID spoofing
    username="DOMAIN\\user", # Optional: run as user
    password="pass123"       # Optional: user password
)

All parameters are optional keyword arguments. Properties can be read and set after creation:

1
2
3
exec_cfg = tuoni.NewExecutionConfiguration()
exec_cfg.executable = "powershell.exe"
exec_cfg.suspended = True

tuoni.ExistingExecutionConfiguration

Inject into an existing process by PID.

exec_cfg = tuoni.ExistingExecutionConfiguration(pid=1234)