# Cazalla - Mythic C2 Agent
**A Windows implant written in C for the Mythic C2 Framework** [![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE.md) [![Mythic](https://img.shields.io/badge/Mythic-v3.x-red.svg)](https://github.com/its-a-feature/Mythic) [![Platform](https://img.shields.io/badge/platform-Windows-lightgrey.svg)]()
--- ## 📋 Table of Contents - [Overview](#overview) - [Features](#features) - [Installation](#installation) - [Supported Commands](#supported-commands) - [SOCKS Proxy Support](#socks-proxy-support) - [Communication Protocol](#communication-protocol) - [Configuration](#configuration) - [Development](#development) - [Troubleshooting](#troubleshooting) - [Credits](#credits) --- ## 🎯 Overview **Cazalla** is a lightweight Windows implant written in C, designed to work seamlessly with the [Mythic C2 Framework](https://github.com/its-a-feature/Mythic). It provides essential post-exploitation capabilities including file system manipulation, process enumeration, command execution, and SOCKS proxy functionality. This project was inspired by the article [How to build your own Mythic agent in C](https://red-team-sncf.github.io/how-to-create-your-own-mythic-agent-in-c.html) and has been extended with additional features and improvements. **Developed by:** Kaseya OFSTeam --- ## ✨ Features - **Lightweight & Portable**: Minimal dependencies, compiled with MinGW for Windows targets - **Full Mythic Integration**: Native support for Mythic's translator pattern and RPC system - **SOCKS Proxy**: Route traffic through the implant with built-in SOCKS5 support - **Dynamic Sleep**: Automatically adjusts beacon interval based on proxy activity - **Custom Binary Protocol**: Efficient binary communication with base64 encoding - **Modular Commands**: Easy to extend with new capabilities --- ## 📦 Installation ### Prerequisites 1. **Mythic Server** (v3.x or later) installed and running 2. Clone this repository ### Install Cazalla on Mythic ```bash cd ~/Mythic ./mythic-cli install github https://github.com//Cazalla ``` Or install from local directory: ```bash ./mythic-cli install folder /path/to/Cazalla ``` ### Build the Agent Cazalla can be built directly from the Mythic UI: 1. Navigate to **Payloads** → **Create Payload** 2. Select **Cazalla** as the payload type 3. Configure build parameters (C2 profile, sleep interval, etc.) 4. Click **Build** The agent will be cross-compiled for Windows using MinGW in a Docker container. --- ## 🛠️ Supported Commands ### File System Operations | Command | Description | Example | |---------|-------------|---------| | `ls` | List directory contents | `ls C:\Users` | | `cd` | Change working directory | `cd C:\Windows\System32` | | `pwd` | Print current directory | `pwd` | | `cp` | Copy files | `cp source.txt dest.txt` | | `mkdir` | Create directory | `mkdir C:\temp\new_folder` | | `rm` | Delete file or directory | `rm C:\temp\file.txt` | ### Execution & Control | Command | Description | Example | |---------|-------------|---------| | `shell` | Execute shell command | `shell whoami` | | `sleep` | Adjust beacon interval | `sleep {"seconds":30,"jitter":0}` | | `exit` | Terminate the implant | `exit` | ### System Information | Command | Description | Example | |---------|-------------|---------| | `ps` | List running processes | `ps` | ### Network Operations | Command | Description | Example | |---------|-------------|---------| | `socks` | Start/stop SOCKS proxy | `socks {"action":"start","port":7002}` | --- ## 🌐 SOCKS Proxy Support Cazalla includes full SOCKS5 proxy support, allowing you to route traffic through the implant to reach internal network resources. ### How It Works 1. **Mythic opens a SOCKS port** on the server (default: `7002`) 2. **Client connects** to Mythic's SOCKS port (e.g., via `proxychains`) 3. **Mythic forwards** SOCKS traffic to the agent with a unique `server_id` per connection 4. **Agent establishes** the actual connection to the target host 5. **Bidirectional relay** between client ↔ Mythic ↔ Agent ↔ Target ### Commands ```bash # Start SOCKS proxy on port 7002 socks {"action":"start","port":7002} # Stop SOCKS proxy socks {"action":"stop","port":7002} ``` ### Using the Proxy After starting SOCKS, configure your tools to use the proxy: #### With proxychains ```bash # Edit /etc/proxychains.conf [ProxyList] socks5 7002 # Use with any tool proxychains curl https://internal-server.local proxychains nmap -sT 192.168.1.0/24 ``` #### With curl ```bash curl --socks5 :7002 https://internal-server.local ``` #### With Firefox/Browser Configure SOCKS proxy in browser settings: - **SOCKS Host**: `` - **Port**: `7002` - **SOCKS v5**: Enabled ### Mythic Configuration for SOCKS To expose SOCKS ports externally (not just localhost), edit `~/Mythic/.env`: ```bash # Allow SOCKS ports to bind on 0.0.0.0 (all interfaces) MYTHIC_SERVER_DYNAMIC_PORTS_BIND_LOCALHOST_ONLY="false" # Define dynamic port range for SOCKS MYTHIC_SERVER_DYNAMIC_PORTS="7000-7010" # Optional: Use host networking for direct port exposure MYTHIC_DOCKER_NETWORKING="host" ``` After editing, restart Mythic: ```bash cd ~/Mythic sudo ./mythic-cli restart ``` Verify the port is open: ```bash sudo netstat -tlnp | grep 7002 # Should show: tcp 0.0.0.0:7002 0.0.0.0:* LISTEN ``` ### Performance Considerations - **Latency**: Proxy speed depends on beacon interval. SOCKS mode automatically reduces sleep to 100ms for responsive connections. - **Throughput**: Suitable for interactive sessions and moderate data transfer. Not optimized for large file transfers. - **Concurrent Connections**: Supports multiple simultaneous SOCKS connections with independent `server_id` tracking. ### Technical Details #### Binary Protocol (0xF5 SOCKS Block) Agent and translator communicate SOCKS data using a custom binary block: ``` [0xF5] [ext_len:4] [server_id:4] [exit:4] [b64_len:4] [base64_data:N] ``` - `0xF5`: SOCKS block marker - `ext_len`: Total extension length (remaining bytes) - `server_id`: Unique connection ID from Mythic - `exit`: `1` if connection should close, `0` otherwise - `b64_len`: Length of base64-encoded payload - `base64_data`: Base64-encoded raw bytes #### Agent Implementation - **File**: `socks_manager.c` / `socks_manager.h` - **Commands**: `0x60` (START_SOCKS), `0x61` (STOP_SOCKS) - **Thread Model**: One reader thread per active connection - **Socket Timeout**: 60 seconds for idle connections --- ## 📡 Communication Protocol Cazalla uses a custom binary protocol for efficient communication with Mythic. ### Message Structure #### Agent → Mythic ``` [UUID:36] [Action:1] [Body:N] ``` - **UUID**: 36-byte agent identifier (ASCII) - **Action**: 1-byte action code (e.g., `0x80` for GET_TASKING, `0x81` for POST_RESPONSE) - **Body**: Variable-length payload #### Mythic → Agent ``` [Action:1] [Body:N] ``` - **Action**: 1-byte action code - **Body**: Variable-length payload (tasks, SOCKS data, etc.) ### Action Codes | Code | Direction | Description | |------|-----------|-------------| | `0x80` | Agent → Mythic | GET_TASKING (request new tasks) | | `0x81` | Agent → Mythic | POST_RESPONSE (send task output) | | `0xF5` | Bidirectional | SOCKS data block | ### Task Structure Tasks sent to the agent include: ``` [TaskUUID:36] [CommandID:1] [Parameters:N] ``` Example command IDs: - `0x01`: Shell command - `0x10`: List directory - `0x60`: Start SOCKS - `0x61`: Stop SOCKS ### Encoding All binary data is base64-encoded for transport over HTTP/HTTPS. --- ## ⚙️ Configuration ### Agent Build Parameters When building from Mythic UI: - **Callback Host**: C2 server address - **Callback Port**: C2 server port (default: 443) - **User Agent**: HTTP User-Agent string - **Sleep**: Initial beacon interval in seconds (default: 10) - **Jitter**: Random delay percentage (0-100) ### Compile-Time Options Edit `Config.h` before building: ```c #define INITIAL_SLEEP_MS 10000 // Default sleep: 10 seconds #define SOCKS_ACTIVE_SLEEP_MS 100 // Sleep when SOCKS active: 100ms #define SOCKS_TIMEOUT_SEC 60 // Socket read timeout ``` ### Debug Mode Enable verbose logging by defining `DEBUG_SOCKS` during compilation: ```bash CFLAGS="-DDEBUG_SOCKS" make ``` This enables: - `[MAINDBG]`: Main loop and sleep adjustments - `[CMDDBG]`: Command parsing - `[SOCKSDBG]`: Connection lifecycle - `[SLEEPDBG]`: Dynamic sleep changes --- ## 🔧 Development ### Project Structure ``` Cazalla/ ├── agent_code/cazalla/ # C source code │ ├── main.c # Entry point │ ├── cazalla.c/h # Main loop │ ├── comandos.c/h # Command handlers │ ├── paquete.c/h # Packet creation │ ├── transporte.c/h # HTTP transport (WinHTTP) │ ├── socks_manager.c/h # SOCKS proxy logic │ ├── checkin.c/h # Initial check-in │ └── Makefile # Build configuration ├── agent_functions/ # Python command definitions │ ├── ls.py, cd.py, pwd.py # File system commands │ ├── shell.py, sleep.py # Execution control │ ├── socks.py # SOCKS proxy command │ └── builder.py # Payload builder ├── translator/ # Mythic ↔ Agent translation │ ├── translator.py # Main translator │ ├── commands_from_c2.py # Mythic JSON → Binary │ └── commands_from_implant.py # Binary → Mythic JSON └── browser_scripts/ # Mythic UI enhancements ├── ls.js # Directory listing formatter └── ps.js # Process list formatter ``` ### Adding New Commands 1. **Define command in Python** (`agent_functions/my_command.py`): ```python from mythic_container.MythicCommandBase import * class MyCommandArguments(TaskArguments): def __init__(self, command_line, **kwargs): super().__init__(command_line, **kwargs) self.args = [ CommandParameter(name="arg1", type=ParameterType.String) ] class MyCommandCommand(CommandBase): cmd = "my_command" needs_admin = False help_cmd = "my_command " description = "Does something useful" version = 1 argument_class = MyCommandArguments async def create_go_tasking(self, taskData: PTTaskMessageAllData): response = PTTaskCreateTaskingMessageResponse( TaskID=taskData.Task.ID, Success=True, ) return response async def process_response(self, task: PTTaskMessageAllData, response: any): resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) return resp ``` 2. **Add to translator** (`translator/commands_from_c2.py`): ```python elif task_command == "my_command": task_data.append(0x99) # Command ID arg1 = task.get("parameters", {}).get("arg1", "") task_data += len(arg1).to_bytes(4, 'big') task_data += arg1.encode('utf-8') ``` 3. **Implement handler in C** (`comandos.c`): ```c BOOL myCommandHandler(PAnalizador argumentos) { SIZE_T tamanoUuid = 36; PCHAR taskUuid = getString(argumentos, &tamanoUuid); SIZE_T arg1Size = 0; PCHAR arg1 = getString(argumentos, &arg1Size); // Do something with arg1 // Send response PPaquete respuesta = nuevoPaquete(POST_RESPONSE, TRUE); addString(respuesta, taskUuid, FALSE); PackageAddFormatPrintf(respuesta, "Command executed: %s\n", arg1); Analizador* resp = mandarPaquete(respuesta); liberarPaquete(respuesta); if (resp) liberarAnalizador(resp); return TRUE; } ``` 4. **Register in command dispatcher** (`comandos.c`): ```c case 0x99: // MY_COMMAND myCommandHandler(argumentos); break; ``` --- ## 🐛 Troubleshooting ### Agent Won't Check In - Verify C2 profile settings (host, port, endpoint) - Check network connectivity from target to C2 server - Review Mythic logs: `sudo docker logs mythic_server` - Enable debug logging in agent and rebuild ### SOCKS Proxy Not Working **Port not accessible:** ```bash # Check if port is open sudo netstat -tlnp | grep 7002 # Ensure Mythic config allows external binding grep DYNAMIC_PORTS_BIND_LOCALHOST_ONLY ~/Mythic/.env # Should be "false" for external access ``` **Proxy times out:** - Verify agent is active and not sleeping - Check translator logs: `sudo docker logs cazalla_translator` - Ensure `server_id` validation in `socks_manager.c` allows Mythic's IDs **Data not flowing:** - Enable `DEBUG_SOCKS` and rebuild agent - Check for `0xF5` block in agent logs - Verify translator is encoding/decoding SOCKS blocks correctly ### Compilation Errors **`inet_pton` not found (MinGW):** - Use `inet_addr` instead (Windows-native) - Already fixed in current version **Missing headers:** ```bash # Install MinGW dependencies in Docker apt-get update && apt-get install -y mingw-w64 ``` ### Task Stays in "Processing" State **Commands like `exit`, `socks start/stop`:** - Ensure handler sends `POST_RESPONSE` with task UUID - Mark task as completed in `create_go_tasking` or `process_response` - For `exit`, mark completed immediately (agent terminates) --- ## 📚 References - [Mythic Documentation](https://docs.mythic-c2.net/) - [Building a Mythic Agent in C](https://red-team-sncf.github.io/how-to-create-your-own-mythic-agent-in-c.html) - [SOCKS5 Protocol (RFC 1928)](https://www.rfc-editor.org/rfc/rfc1928) - [Mythic Translator Pattern](https://docs.mythic-c2.net/customizing/payload-type-development/translation-containers) --- ## 📄 License Cazalla is licensed under the **BSD 3-Clause License**. See [LICENSE.md](LICENSE.md) for details. --- ## 👥 Credits **Developed by:** Kaseya OFSTeam Special thanks to: - The Mythic C2 team for the excellent framework - The SNCF Red Team for the foundational C agent tutorial - The open-source security community ---
**Made with ☕ and 💻 by the Kaseya OFSTeam**