Written by ARC Labs contributors, John Dwyer and Eric Gonzalez
ARC Labs recently capture and analyzed the second and third stage payloads used during a Cleo MFT compromise. The compromise is a result of exploitation of CVE-2024-50623 which allows for unauthorized remote code execution. Additional reports suggest that exploitation of the vulnerability continues to be possible even after applying the vendor patch indicating that the patch may be ineffective against every variation of the attack.
Based on the analysis of the behaviors of the post exploitation activity, the attack flow is broken into three stages ultimately resulting in a remote attacker achieving interactive access to the impacted host.
Overview of the Three Stages
The attack progresses in three distinct stages:
- Stage 1: A PowerShell script initiates the attack by downloading and executing a file named cleo.9261.
- Stage 2: The cleo.9261 file, implemented as a JAR containing “start.class”, connects to a Command and Control (C2) server, downloads a second JAR file, and executes its primary class (Cli).
- Stage 3: The second JAR file which has a dynamically generated name contains additional classes for managing tasks such as file transfers, command execution, and network communication.
Stage 1: PowerShell Script
Purpose:
- The script establishes a connection to a remote server (80.67.5.133) over port 443.
- It downloads an encrypted file (cleo.9261) and saves it to the local disk.
- Decrypts the file during the download using a complex XOR-based algorithm.
- Sets environment variables and executes the downloaded file with Java.
Key Operations:
- Network Communication:
- Uses Net.Sockets.TcpClient to establish a socket connection.
- Decryption Algorithm:
- Applies a dynamic XOR-based routine to decrypt data as it is received.
- Execution:
- Launches cleo.9261 using Java with the -jar argument, passing environment variables:
- $env:QUERY: Encoded information for the next stage.
- $env:F: The downloaded file name.
- Launches cleo.9261 using Java with the -jar argument, passing environment variables:
Stage 2: start.class in cleo.9261
Purpose:
- Acts as the intermediary between the PowerShell script and the second JAR payload.
- Connects to the C2 server, downloads the second JAR file, and executes it dynamically.
Key Operations:
Environment Variable Parsing:
- Decodes the QUERY variable to extract:
- C2 server address (e.g., an IP or domain).
- AES encryption key and IV.
Connection to C2:
- Establishes a socket connection to the C2 server on port 443.
- Sends an identifier string (TLS v3 <Base64-encoded session key>).
Payload Download:
The second-stage JAR is downloaded, decrypted from “arrayOfByte4”, and loaded dynamically into memory without saving it as a file on disk.
- AES decryption in CBC mode is used.
- Key and IV are derived from the QUERY environment variable.
Dynamic Class Loading:
- Instantiates and executes the Cli class from the downloaded JAR.
File Cleanup
The str variable is assigned the value of the environment variable f, which is passed by the preceding PowerShell script. After the downloaded payload (second-stage JAR) is decrypted, cleo.9261 file is overwritten with random characters, likely to obscure or destroy evidence.
Stage 3: Multi-class JAR file
The second JAR file contains multiple classes, each designed for a specific task:
Integration and Workflow
Network Communication:
- SrvSlot and ScSlot maintain primary and secondary communication with the C2 server.
- Slot provides the foundation for all network interactions.
File Management:
- Dwn, DwnLevel, and Mos collaborate to compress, send, and monitor file transfers.
Command Execution:
- Proc ensures dynamic task execution and reports results to the C2 server.
Orchestration:
- Cli ties all components together, coordinating network, file, and command operations.
1. Cli Class
Purpose: Orchestrates the execution of commands, manages the lifecycle of the payload, and interacts with the server (SrvSlot) for task management.
Core Features:
- Initializes network communication with the Command-and-Control (C2) server.
- Dynamically loads the initial file name (stage1fn) and deletes it after execution.
- Implements logging and debugging utilities (l and dmp methods).
- Establishes and monitors the SrvSlot instance for the server.
2. SrvSlot Class
Purpose: Acts as the primary server-side communication and coordination hub, managing network interactions, task execution, file transfers, and session handling.
Core Features:
- Encryption/Decryption:
- Encrypts and decrypts data streams using XOR-based logic with rolling keys.
- Packet Handling:
- Constructs and processes packets for communication with the C2 server.
- Task Management:
- Manages processes (Proc) and file channels (SFile).
- Session Management:
- Establishes and synchronizes communication sessions with the client.
- File Transfers:
- Supports upload and download operations via ZIP data handling.
3. Slot Class
Purpose: Provides a base class for network slots, facilitating low-level communication using Java NIO channels.
Core Features:
- Establishes and manages socket connections.
- Handles read, write, and connect operations with NIO Selector and SocketChannel.
- Maintains buffers (inbuf, outbuf) for incoming and outgoing data streams.
- Supports dynamic buffer resizing for large data transfers.
4. ScSlot Class
Purpose: Manages auxiliary communication channels, extending the Slot class to support secondary connections.
Core Features:
- Establishes secondary channels for parallel communication.
- Integrates with SrvSlot to coordinate additional tasks.
- Handles event-driven read/write operations efficiently.
5. Proc Class
Purpose: Handles the execution of commands and processes, providing functionality for managing and interacting with external commands.
Core Features:
- Executes system commands via subprocesses.
- Supports dynamic piping and data redirection.
- Implements a communication mechanism to send process output to the server.
6. SFile Class
Purpose: Manages file I/O operations for data transfers during the payload’s execution.
Core Features:
- Reads from and writes to files for upload/download tasks.
- Maintains file metadata (size, status) for ongoing operations.
- Ensures safe handling of file streams, including error handling and cleanup.
7. Dwn Class
Purpose: Manages the downloading of additional files or resources, supporting recursive traversal and ZIP-based transfers.
Core Features:
- Supports file compression using ZIP format.
- Handles recursive file discovery and transfer.
- Manages state and session tracking for large downloads.
8. DwnLevel Class
Purpose: Provides a helper class for managing recursive file traversal during downloads.
Core Features:
- Maintains the state and progress of directory traversal.
- Supports multi-level file hierarchy exploration.
9. Mos Class
Purpose: Acts as a middleware for managing data buffers and streaming to the Dwn class.
Core Features:
- Buffers data for efficient processing during ZIP-based operations.
- Tracks the progress of data transfers.
- Integrates with the Dwn class for seamless file handling.
Based on the analysis performed by ARC Labs it appears that each class in the Stage 3 payload plays a specialized role, contributing to a modular and robust payload framework capable of managing tasks, executing commands, and facilitating network communication with minimal detection.
Key Post Exploitation Features
Command Execution
Commands are received from the C2 server as part of SrvSlot.in().
Commands are executed by Proc.run(), using Runtime.getRuntime().exec().
Standard output and error streams are redirected back to the C2 server via the SrvSlot class.
- The command (str1) is extracted from the incoming packet.
- internalCmds() is called to handle internal commands. If the command isn’t internal:
- A new Proc object is created with the extracted command (str1) and the corresponding channel ID (m).
- The Proc object is started, executing the command.
- Initializes the command to be executed.
- Supports additional data pipelines for commands that require input streams.
- Executes the command using the Runtime.getRuntime().exec() method.
- Streams the command’s output and error streams back to the C2 server.
File Download and Upload
The ability to download and upload files in the Java classes is primarily implemented in the SrvSlot and SFile classes, with support from Dwn and related classes for specific operations like handling directories and ZIP files.
File Downloads
- SrvSlot: Handles file download initialization and writes data packets to SFile.
- SFile: Manages writing data to local files.
File Uploads
- SrvSlot: Reads file content from SFile and sends it as packets.
- SFile: Reads file content for upload.
Support for Complex Operations
- Dwn: Adds support for recursive directory traversal and ZIP compression during file uploads and downloads.
The SrvSlot class provides the primary interface for downloading files from the C2 server.
• In the in() method, case 3 processes file data packets received from the C2 server.
• The packets are written to the corresponding file managed by an SFile instance.
• Case 4 handles the initiation of a file download from the C2 server.
• Creates an SFile instance to manage the file and receive data.
SFile Class manages individual file operations for both downloads and uploads.
The read() method reads file content to be uploaded and the write() method writes data received from the C2 server to a local file.
The analysis of this multi-stage payload reveals a highly modular framework designed to operate stealthily and flexibly within a target environment. The staged deployment methodology, starting from an initial PowerShell script and culminating in the execution of a dynamic Java-based command-and-control framework, demonstrates the attackers’ intent to evade detection and maintain persistence.