Skip to content


In the Tuoni, three critical aspects of communication are integral to its functioning:

  1. Communication between the Core of Command and Control (C2) and the Core of the Agent: This involves the direct interaction between the main components of the C2 system and the deployed agent.
  2. Communication between Listener Plugin and Listener Plugin Shellcode: This pertains to the exchange of information between the listener plugin, which resides on the C2 side, and its corresponding shellcode, which operates within the agent.
  3. Communication between the Graphical User Interface (GUI)/Scripts and the C2 API: This refers to the interactions between the user interface or scripts and the Application Programming Interface (API) of the C2 system.

It is important to note that the last of these communication aspects, the interaction between the GUI/scripts and the C2 API, is not discussed in this document. Detailed information and guidelines regarding this aspect can be found in the separate documentation document dedicated to it.

C2 core & agent core communication

This passage describes the foundational communication layer that facilitates interaction between the agent operating on the target machine and the core of the Command and Control (C2) system. All commands and their corresponding results are transmitted and received through this channel. The protocol governing the data exchange is based on the Type-Length-Value (TLV) format, which is detailed at TLV protocol.

It's crucial to understand that this communication layer does not specify the methodologies for data transmission, encapsulation, or reception. It should not be confused with a 'transport layer'; rather, it functions more akin to an 'application layer' when compared to the OSI model of networking. The actual transportation of data is managed by a different layer, specifically the one facilitating communication between the listener plugin and the listener plugin shellcode.

Listener plugin and listener plugin shellcode communication

The listener plugin in the system is designed with the flexibility to adopt any protocol of choice. Its primary function is to encapsulate the communication layer, as described in the preceding step, within the selected protocol. The core component of the listener plugin is developed in JAVA and is integrated with the Command and Control (C2) system. This plugin acts as a relay, channeling data between the agent and the C2 core.

An important aspect to note is that the listener itself is not required to have an in-depth understanding of the internal protocol. In fact, in most instances, the listener is not equipped to decrypt the communication independently. Correspondingly, on the agent side, the listener plugin shellcode mirrors the protocol implemented by the listener plugin. It plays a pivotal role in relaying data from the C2 to the agent core, typically utilizing pipes for this transfer.

A commonly employed example in this context is the HTTP listener plugin. This plugin leverages the HTTP protocol to facilitate the movement of data between the agent and the C2 core, effectively demonstrating the versatility and adaptability of the listener plugin framework.

How it works in practice

The process of sending commands to an agent and receiving results, particularly in the context of the HTTP listener plugin, involves a series of systematic steps. These steps can be summarized as follows:

Sending Commands to Agent:**

  1. Command Initiation: A user, through the REST API, instructs the Command and Control (C2) to dispatch a specific command to one of the connected agents.
  2. Command Preparation: The C2 assembles a Type-Length-Value (TLV) structure containing all necessary elements for the agent to execute the given command.
  3. Command Queuing: This TLV structure is added to the agent's waiting command list.
  4. Command Retrieval: When the agent next connects to the listener plugin, the plugin inquires with the C2 core for any new commands, subsequently receiving the TLV.
  5. TLV Encapsulation: The listener plugin encases the TLV within an HTTP response.
  6. Response Transmission: The listener plugin shellcode within the agent retrieves this HTTP response and extracts the TLV structure.
  7. Command Relay: The shellcode then transmits the TLV structure to the agent core, usually via a pipe.
  8. Command Execution: Finally, based on the TLV structure and its configuration, the agent executes the command.

Receiving Results from Agent:

  1. Result Preparation: After executing a command, the agent wraps the result in a TLV structure.
  2. Result Collection: Prior to making the next HTTP request to the C2, the listener plugin shellcode requests any new results from the agent, receiving the aforementioned TLV.
  3. Result Transmission: The shellcode encases this TLV within an HTTP request, which is then sent to the listener plugin awaiting HTTP requests.
  4. Result Retrieval: Upon receiving the HTTP request, the listener plugin extracts the TLV structure and relays it to the C2 core.
  5. Result Processing: The C2 core processes the TLV, ultimately providing the user with the result.

Additional Notes:

  • Agent Metadata: All HTTP requests sent from the agent to the C2 also include metadata pertaining to the agent, which provides additional context or information regarding the agent's state or identity.
  • When the Command and Control (C2) core is involved in assembling a command TLV (Type-Length-Value) structure or interpreting a result TLV, it utilizes specific command plugins, particularly for commands that are based on these plugins. This process is intricately detailed and outlined on commands page.

Visual representation

Step 1

User tasks C2 to send command to the agent via C2 API. This can be done with GUI or script.

Communication step 1

Step 2

Based on user given data, the C2 core combines TLV structure to be sent to the agent.

Communication step 2

Step 3

Agent does the HTTP request, received by the listener plugin

Communication step 3

Step 4

Listener plugin takes the TLV structure and encapsulates it into HTTP response

Communication step 4

Step 5

Listener plugin sends the TLV encapsuled in HTTP response to agent

Communication step 5

Step 6

Listener plugin shellcode retrieves the TLV from HTTP response and sends it to agent core where it is executed

Communication step 6

Step 7

After command is executed, the result is stored to the TLV structure

Communication step 7

Step 8

When listener plugin shellcode is doing next request to C2, it asks agent core for any unsent results

Communication step 8

Step 9

Listener plugin shellcode encapsulates TLV into HTTP request

Communication step 8

Step 10

Listener plugin shellcode sends the TLV encapsuled in HTTP request to listener plugin

Communication step 8

Step 11

Listener plugin retrieves TLV from HTTP request and sends it to C2 core that parses it

Communication step 8

Step 12

User can now retrieve result data

Communication step 8