General architectural overview
This document provides a general overview of the Tuoni architecture. It is intended not as a detailed reference, but rather as a broad, high-level description of the various components of the tool.
Tuoni main parts
This section presents an overview of the main functional components of Tuoni.
C2
The Command and Control (C2) center is the core of Tuoni's operations. It serves as the hub where agents, remote shells, and similar elements connect. C2 is responsible for managing these connections, maintaining their history, and overseeing ongoing activities. Developed in Java, C2 incorporates technologies such as Spring and SQLite, along with other well-established frameworks and libraries. Additionally, it offers a REST API and WebSocket access, enabling users to control both the agents and the C2 center itself.
Agent
The agent component of Tuoni operates on the targeted machine, receiving commands from the C2 center and returning the results. Tuoni offers a variety of agent versions, differing in both functionality (ranging from public free versions to more advanced private ones) and types (such as executables, DLLs, service executables, shellcode, etc.).
Typically, the inherent functionality of the agent is relatively limited. Most of its capabilities are delivered through command ExecUnits provided by the C2 along with the command itself. An ExecUnit can be legacy native shellcode, a .NET executable, a .NET DLL, or a native library, depending on what the command and agent both support. This design strategy helps maintain a smaller agent size and reduce detection rates, while still offering a broad range of functionalities. Additionally, it allows for the extension of the agent's capabilities without needing to modify the agent itself. This approach and its underlying logic will be elaborated upon in subsequent documents.
Main features of the agent:
- Multithreading
- Capable of managing multiple communication channels simultaneously.
- Supports the execution of multiple commands concurrently.
- Ability to run parts of its operations in different processes, enhancing security and stability.
- Designed for heavy extensibility, allowing for real-time enhancements or modifications without needing to restart or redeploy.
- Engineered to be resilient against crashes, ensuring consistent operation even in unstable environments.
- Compatible with the execution of Beacon Object Files (BOF), expanding its operational scope.
- ...
GUI
The Graphical User Interface (GUI) provided by ShellDot is designed to facilitate communication with the Tuoni C2 center. While its use is not mandatory, and users have the option to employ their own interfaces, scripts, or even use tools like curl (though this might be less convenient for overall use), the Tuoni GUI is highly recommended. It was developed by active members of the red team who focused on creating a user-friendly yet powerful interface. This GUI interacts with the C2 center via REST API and WebSocket. It is continuously enhanced and expanded to align with updates and changes made to the C2 center, ensuring a seamless and effective user experience.
Tuoni supporting parts
The non-core components of Tuoni, while not part of the central architecture, are still crucial as they provide the majority of the agent's functionality. These elements are integral to the overall effectiveness and versatility of the tool, enhancing its operational capabilities significantly.
Listener plugins
The core component of the C2 in Tuoni does not inherently include any listener implementations. Instead, all listener functionalities are implemented through plugins. While some of these plugins are provided with the C2 by default, the design is such that adding new listeners is a fundamental aspect of the C2's architecture. This approach is intended to significantly broaden the capabilities of Tuoni in the future.
Each listener plugin is composed of two main parts:
-
C2 Side of the Plugin: This is the segment of the plugin that integrates with the C2 system, managing the reception and coordination of communications and data.
-
Agent Executable-Code Side: This part pertains to the agent, involving the execution of listener code that corresponds with the listener functionality, ensuring effective communication and operation within the agent's environment.
Listener plugin C2 side
This is plugin developed in JAVA and designed to handle the transmission and reception of data between the agent and the core of the C2. It acts as a relay, ensuring smooth data flow in both directions. Moreover, the C2 side of the plugin includes the executable code necessary for the agent side. This allows listener code to be either integrated into newly generated agents or dispatched to existing agents for subsequent execution. The plugin's architecture ensures seamless integration and communication within the Tuoni system, facilitating effective and efficient operations.
Listener plugin agent executable-code side
This component is executable code that operates either within the agent's process or in another process on the same machine (the specifics of which will be discussed in a subsequent section). It is responsible for executing the listener's communication logic from the agent's side. The listener code facilitates interaction between the core part of the agent (e.g., via a pipe) and the C2 side of the plugin.
Agent-side listener code can be delivered as legacy native shellcode or as an ExecUnit format such as a .NET executable, .NET DLL, or native library when the listener and payload support it. Shellcode-format listeners are often written in higher-level languages like C/C++ or C# and then converted into shellcode format using tools such as Donut.
Command plugins
Although the agents in Tuoni do possess some native commands, the majority of their command functionalities are implemented as plugins, in a manner closely resembling the listener plugins. Similar to listener plugins, these command plugins are structured with two distinct components: the C2 side and the agent side.
-
C2 Side: This part of the command plugin is integrated into the C2 system. It is responsible for managing the command's configuration, processing, and overall interaction with the C2 infrastructure.
-
Agent Side: The agent side of the plugin is executed within the agent's environment. It is where the actual command logic is implemented, allowing the agent to perform the specific tasks as directed by the C2.
This dual-component structure enables a flexible and scalable approach to command implementation, allowing for a wide range of functionalities to be added to the agents as needed.
Command plugin C2 side
This is plugin developed in JAVA and is designed to handle the command and control (C2) side of operations. It operates by integrating user-provided parameters through the C2 code into a configuration and ExecUnit that can be processed by the agent. Upon receiving a response, the plugin parses the results and delivers them in a structured format to the C2 core. This core then presents the final results to the user. This process ensures a seamless flow of commands and information between the user and the C2 infrastructure.
Command plugin agent ExecUnit side
This ExecUnit operates within the agent process, or potentially in another process on the same machine, details of which will be discussed later. Its primary function is to execute command logic from the agent's perspective. Communication with the core part of the agent occurs through mechanisms such as pipes, facilitating the reception of command parameters and the transmission of command results.
ExecUnits can be legacy native shellcode, .NET executables, .NET DLLs, or native libraries. The C2 chooses a compatible format from the command's supported formats and the agent's reported capabilities, unless the command request explicitly asks for a specific execUnitType.
Agent generation
To ensure seamless operation, the Command and Control (C2) system must be capable of creating payloads for execution on the target machine. These payloads, once deployed, establish a connection to the C2 system, acting as agents. The process of creating these payloads, or agents, essentially involves generating executable files (.exe), dynamic link libraries (.dll), or shellcode. These files are embedded with the necessary configuration and functionality to connect to the C2 and begin receiving instructions. The generation of these payloads is fundamentally straightforward, yet it comprises several components. Below is a detailed description of these components and the overall generation process.
Payload/agent templates
Within the Command and Control (C2) framework, a variety of templates for different agents exist. These templates include executable files (.exe), dynamic link libraries (.dll), and shellcode, each encapsulating the core functionalities of an agent. When a user requests the creation of a new agent, they specify the type of agent (such as a 64-bit executable) and an existing listener to which the agent will connect. The agent is then generated from the selected template by embedding additional configuration details and listener executable code into it. The final binary, a synthesis of the template and custom configurations, is subsequently provided to the user.
What is implanted into generated agent
Typically, during the generation of a payload, only one primary data structure is integrated into the payload template. This data structure encompasses the following information:
- Executable code for the listener plugin, either legacy shellcode or an ExecUnit.
- Configuration details for the listener code, outlining how it should establish a connection with the listener.
- The execution method of the listener code, specifying whether it runs within the same process or a different one.
- The communication method between the listener code and the core agent, which predominantly involves the use of pipes.
These elements are embedded into the agent's resources, enabling the agent to access and utilize them during execution. Additionally, a separate data structure is also incorporated into the template. This structure is generated by the C2 system itself and contains the C2's public key, which is essential for securing the underlying communication between the agent and the C2.