Skip to content

Python library basics

The full documentation for the Python library is available at python.shelldot.com.

After connecting to C2, you can ask for list of available listener plugins and create said listener (using default configuration in current case).

Creating a listener

import tuoni

# Connect to the backend server
tuoni_c2 = tuoni.TuoniC2()
tuoni_c2.login("https://localhost:8443", "username", "password")

# Get the available listener plugins from the C2
listener_plugins = tuoni_c2.load_listener_plugins() 

# Select the HTTP listener by its plugin name
http_plugin = listener_plugins["shelldot.listener.agent-reverse-http"] 

# Create the HTTP listener using default configuration
http_obj = http_plugin.create(http_plugin.conf_examples["default"])

Generating an agent to connect to the created listener

You can use listener ID created on the previous step to generate agent that connects to said listener. The file is saved to the filesystem.

1
2
3
4
5
# Create a "shelldot.payload.windows-x64" payload definition for listener ID 1, of type executable
payload_id = tuoni_c2.create_payload("shelldot.payload.windows-x64",  http_obj.listener_id, {"type": "executable"})

# Generate the artifact and download the binary from C2 as "executable64.exe"
tuoni_c2.download_payload(payload_id, "executable64.exe")

Waiting for a single connection

You can make python wait for a new connection

agent = tuoni_c2.wait_new_agent()
print("New agent connected: %s" % agent.guid)

Waiting for multiple connections

You can add tuoni connection an new connection event handler.

1
2
3
4
def new_agent_event_handler(agent):
    print("New agent connected: %s" % agent.guid)

tuoni_c2.on_new_agent(new_agent_event_handler)

Sending commands to agent

Numerous predefined command classes are available for use, and you can also write commands in a form similar to how they are sent to the REST API.

In the following example, the cmd command is invoked to execute the dir command. Python then waits for the result and displays it upon receipt.

Predefined class

1
2
3
4
command = agent.send_command(tuoni.TuoniCommandCmd("dir"))
result = command.wait_result()
if result.status == "success":
    print(result.parts[0].get_as_text())

Raw format

1
2
3
4
command = agent.send_command("cmd", {"command":"dir"})
result = command.wait_result()
if result.status == "success":
    print(result.parts[0].get_as_text())