# 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) - [Reverse Port Forwarding (RPFWD) Support](#-reverse-port-forwarding-rpfwd-support) - [Communication Protocol](#communication-protocol) - [Configuration](#configuration) - [Process Browser Integration](#process-browser-integration) - [Artifacts Support](#artifacts-support) - [Credentials Support](#credentials-support) - [File Downloads Support](#file-downloads-support) - [File Uploads Support](#file-uploads-support) - [Keylogging Support](#%EF%B8%8F-keylogging-support) - [Token Support](#-token-support) - [Context Tracking](#-context-tracking) - [OPSEC Checking](#️-opsec-checking) - [Logging & Syslog](#-logging--syslog) - [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 - **Channel Encryption**: Optional AES-256-CBC encryption with HMAC-SHA256 for secure communication - **Process Browser Support**: Integrated with Mythic's Process Browser for unified process management across multiple callbacks - **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. --- ## πŸ”¨ Customizing Cazalla If you've forked Cazalla or made local changes and want to use your customized version, you need to configure Mythic to use local builds instead of remote images. ### Making Changes Work By default, Mythic may use pre-built remote images for faster deployment. However, if you've made local changes to the agent code, translator, or any Python files, you need to configure Mythic to use your local build context. #### Configure Build Variables After installing Cazalla, Mythic will add these variables to your `~/Mythic/.env` file: ```bash # Use local build context instead of remote image CAZALLA_USE_BUILD_CONTEXT="true" # Use direct mount instead of Docker volume (recommended for development) CAZALLA_USE_VOLUME="false" # Optional: Remote image URL (only used if USE_BUILD_CONTEXT is false) CAZALLA_REMOTE_IMAGE="ghcr.io/your-org/cazalla:v1.0.0" ``` #### Variables Explanation - **`CAZALLA_USE_BUILD_CONTEXT`**: - Set to `"true"` to build from your local `Dockerfile` and include your local changes - Set to `"false"` (default) to use the pre-built remote image - **Important**: You must set this to `"true"` if you've modified any files! - **`CAZALLA_USE_VOLUME`**: - Set to `"false"` (default) to mount the local folder directly into the container - Set to `"true"` to use a Docker volume instead - Direct mount is better for development as changes are immediately visible - **`CAZALLA_REMOTE_IMAGE`** (optional): - Specifies a pre-built remote image URL - Only used when `CAZALLA_USE_BUILD_CONTEXT="false"` #### Apply Changes After modifying these variables, rebuild the container: ```bash cd ~/Mythic sudo ./mythic-cli build cazalla ``` #### Verifying Your Changes 1. Make your code changes 2. Set `CAZALLA_USE_BUILD_CONTEXT="true"` in `~/Mythic/.env` 3. Run `sudo ./mythic-cli build cazalla` 4. Check logs: `sudo docker logs cazalla_translator` If changes still don't appear: - Verify the `Dockerfile` copies your modified files (see line 39: `COPY ./ /Mythic/cazalla/`) - Check that file paths in the Dockerfile match your directory structure - Ensure you're editing files in the correct location (inside `Payload_Type/cazalla/`) #### Example: Customizing Agent Code ```bash # 1. Edit agent C code vim Payload_Type/cazalla/cazalla/agent_code/cazalla/comandos.c # 2. Ensure build context is enabled echo 'CAZALLA_USE_BUILD_CONTEXT="true"' >> ~/Mythic/.env # 3. Rebuild the container cd ~/Mythic sudo ./mythic-cli build cazalla # 4. Rebuild a payload from the UI # Your changes will now be included in the compiled agent ``` For more information, see the [Mythic documentation on customizing public agents](https://docs.mythic-c2.net/customizing/customizing-public-agent). --- ## πŸ› οΈ 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` | | `cat` | Read file contents (with automatic credential detection) | `cat C:\path\to\file.txt` | | `download` | Download file from target to Mythic server | `download C:\path\to\file.txt` | | `upload` | Upload file from Mythic server to target | `upload C:\path\to\destination.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` | | `inline_execute` | Execute a Beacon Object File (BOF) in the current process thread | `inline_execute -BOF whoami.x64.o -Arguments int32:1234` | | `inline_execute_assembly` | Execute a .NET Assembly in the current process using Inline-EA BOF | `inline_execute_assembly -Assembly SharpUp.exe -Arguments "audit" --patchexit --amsi --etw` | ### System Information | Command | Description | Example | |---------|-------------|---------| | `ps` | List running processes with Process Browser support | `ps` | | `browser_info` | Identify installed browsers and default browser | `browser_info` | | `browser_dump` | Dump cookies (display only), passwords, and bookmarks from browsers (Chrome, Firefox) | `browser_dump chrome` | | `samdump` | Dump NTLM password hashes from SAM database (registry/files/remote methods) | `samdump [method] [params]` | | `screenshot` | Capture full-screen screenshot (Mythic screenshot UI) | `screenshot` | | `keylog_start` | Start keystroke logging | `keylog_start` | | `keylog_stop` | Stop keystroke logging | `keylog_stop` | | `whoami` | Get current user context (thread token if impersonated, otherwise process token) | `whoami` | ### Token Operations | Command | Description | Example | |---------|-------------|---------| | `list_tokens` | List all available tokens from running processes | `list_tokens` | | `steal_token` | Steal and impersonate token from a target process | `steal_token ` | | `make_token` | Create a new token using credentials and impersonate it | `make_token domain username password [logon_type]` | | `rev2self` | Revert token impersonation back to original token | `rev2self` | ### Process Management | Command | Description | Example | |---------|-------------|---------| | `kill` | Terminate a process by PID (Process Browser supported) | `kill ` | **Note**: The `ps` command integrates with Mythic's Process Browser, allowing unified process management across multiple callbacks. Process lists are automatically synchronized and viewable from the Process Browser UI. The `kill` command also supports Process Browser integration, allowing you to terminate processes directly from the Process Browser UI. ### Network Operations | Command | Description | Example | |---------|-------------|---------| | `socks` | Start/stop SOCKS proxy | `socks {"action":"start","port":7002}` | | `rpfwd` | Start/stop reverse port forwarding | `rpfwd {"action":"start","port":8080,"remote_host":"127.0.0.1","remote_port":80}` | --- ## 🌐 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 --- ## πŸ”„ Reverse Port Forwarding (RPFWD) Support Cazalla includes reverse port forwarding (RPFWD) support, allowing you to tunnel incoming connections from the agent to a remote destination through Mythic. ### How It Works 1. **Agent opens a listener** on a local port (e.g., `8080` on the agent host) 2. **External client connects** to the agent's listener port 3. **Agent sends connection data** to Mythic via RPFWD protocol 4. **Mythic connects** to the configured remote destination (`remote_host:remote_port`) 5. **Bidirectional relay** between client ↔ Agent ↔ Mythic ↔ Remote destination This is the **reverse** of a normal forward port: instead of connecting from Mythic to a remote service through the agent, connections originate from external clients to the agent and are tunneled to a remote destination. ### Commands ```bash # Start reverse port forward on agent port 8080, forwarding to 127.0.0.1:80 rpfwd {"action":"start","port":8080,"remote_host":"127.0.0.1","remote_port":80} # Stop reverse port forward rpfwd {"action":"stop","port":8080} ``` ### Use Cases - **Access internal services**: Expose internal services (e.g., database, web server) by having the agent listen on a port - **Bypass firewall restrictions**: When you can't connect from Mythic but can connect to the agent - **Service tunneling**: Tunnel arbitrary TCP services through the agent ### Testing RPFWD **Important**: The agent listens on **its own host**, not on the Mythic server. To test: ```bash # From another machine or from the agent host itself: nc -nzv 8080 # Or from the agent host: nc -nzv 127.0.0.1 8080 ``` **Port Requirements**: - **Non-privileged ports (>=1024)**: Recommended for normal users (e.g., `8080`, `4444`, `5555`) - **Privileged ports (<1024)**: Require administrator privileges on Windows (e.g., `80`, `443`, `445`) - If bind fails with `WSAError=10013`, the port requires admin privileges or is already in use ### Example Scenarios #### Scenario 1: Expose Internal Web Server ```bash # Agent is on internal network with a web server at 192.168.1.100:80 # Start RPFWD to tunnel external connections to the internal server rpfwd {"action":"start","port":8080,"remote_host":"192.168.1.100","remote_port":80} # Now, connecting to agent:8080 will forward to 192.168.1.100:80 curl http://:8080 ``` #### Scenario 2: Tunnel Database Access ```bash # Tunnel database connections through the agent rpfwd {"action":"start","port":3306,"remote_host":"10.0.0.50","remote_port":3306} # Connect to MySQL through the agent (from another machine) mysql -h -P 3306 -u user -p ``` ### Technical Details #### Binary Protocol (0xF2 RPFWD Block) Agent and translator communicate RPFWD data using a custom binary block: ``` [0xF2] [ext_len:4] [server_id:4] [exit:1] [b64_len:4] [base64_data:N] [port:4] ``` - `0xF2`: RPFWD 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 (connection data) - `port`: Local port on agent (optional, for connection tracking) #### Agent Implementation - **File**: `rpfwd_manager.c` / `rpfwd_manager.h` - **Commands**: `0x62` (START_RPFWD), `0x63` (STOP_RPFWD) - **Thread Model**: One listener thread + one reader thread per active connection - **Socket Management**: Automatic cleanup of closed connections #### Artifacts - **Network Connection**: Automatically reported when RPFWD listener starts on a port --- ## πŸ“‘ 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 | | `0xF2` | Bidirectional | RPFWD data block | | `0xF0` | Agent β†’ Mythic | Callback context data (cwd, impersonation_context, etc.) | ### 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 - `0x62`: Start RPFWD - `0x63`: Stop RPFWD ### Encoding All binary data is base64-encoded for transport over HTTP/HTTPS. ### Channel Encryption (Optional) When encryption is enabled via the `AESPSK` build parameter: - **Encryption Format**: `[IV:16 bytes][AES-256-CBC Ciphertext][HMAC-SHA256:32 bytes]` - **Agent Side**: Encrypts all outgoing messages before base64 encoding - **Translator Side**: Decrypts all incoming messages after base64 decoding - **Key Management**: 256-bit AES key embedded at build time, unique per payload This provides end-to-end encryption independent of the transport layer (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) - **Encryption**: Channel encryption settings (optional) - **AESPSK**: Enable AES-256-CBC encryption with HMAC-SHA256 - When enabled, all agent ↔ Mythic communication is encrypted end-to-end - The encryption key is automatically generated by Mythic and embedded in the payload ### 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 ``` ### Channel Encryption Cazalla supports optional AES-256-CBC encryption with HMAC-SHA256 for secure agent-to-Mythic communication. This provides an additional layer of security beyond HTTPS. #### How It Works 1. **Mythic generates** a random 256-bit AES key during payload creation 2. **Key is embedded** in the agent binary at build time 3. **All messages** are encrypted using AES-256-CBC mode with a random IV per message 4. **HMAC-SHA256** is calculated over the IV + ciphertext for integrity verification 5. **Format**: `[IV:16 bytes][Ciphertext:N bytes][HMAC:32 bytes]` #### Enabling Encryption Encryption is enabled automatically when building with the `AESPSK` parameter in Mythic's UI: 1. Navigate to **Payloads** β†’ **Create Payload** 2. Select **Cazalla** as the payload type 3. In the build parameters, configure **AESPSK**: - Set `crypto_type` to `aes256_hmac` - Mythic will automatically generate an `enc_key` 4. Click **Build** The encryption key is unique per payload and is shared between the agent and translator. #### Encryption Status You can verify encryption is enabled by checking the build output: - Look for: `βœ“ Encryption ENABLED: crypto_type=aes256_hmac, enc_key present` - The translator logs will show encryption/decryption operations #### Security Considerations - **Key Management**: Each payload has a unique encryption key managed by Mythic - **IV Randomization**: A new random IV is generated for each encrypted message - **HMAC Verification**: All encrypted messages include HMAC for integrity validation - **Defense in Depth**: Encryption works alongside HTTPS for layered security ### 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 --- ## πŸ“Š Process Browser Integration Cazalla fully integrates with Mythic's Process Browser feature, providing unified process management across multiple callbacks on the same host. Both `ps` and `kill` commands support Process Browser integration. ### Features - **Unified Process Lists**: All process listings from different callbacks on the same host are aggregated - **Process Hierarchy**: View process parent-child relationships when parent process IDs are available - **Rich Process Data**: Includes process name, PID, PPID, architecture, user account, and session ID - **Automatic Synchronization**: Process lists are automatically synchronized with Mythic's Process Browser UI - **Process Actions**: Kill processes directly from the Process Browser UI - **Cache Management**: Process lists automatically clear stale entries using `update_deleted=True` flag ### Process Browser UI Access the Process Browser in Mythic: 1. Navigate to a callback in the Mythic UI 2. Click the **PROCESSES** tab (next to the **CALLBACK** tab) 3. View all processes from all callbacks on that host 4. Use the UI buttons for process actions: - **Kill**: Terminate a process directly from the Process Browser (uses `kill` command) - **Steal Token**: Steal token from a process (uses `steal_token` command) - **List Tokens**: List tokens from a process (uses `list_tokens` command) ### Implementation Details #### `ps` Command The `ps` command implements the `process_browser:list` supported UI feature: - Process data is automatically converted to Mythic's Process Browser JSON format - The translator detects process list responses and formats them accordingly - All processes are marked with `update_deleted=True` to clear stale entries from cache - Process information includes: - `process_id`: Process identifier (required) - `name`: Process name (required) - `parent_process_id`: Parent process ID (optional) - `architecture`: Process architecture (x64/x86) - `user`: User account running the process - `session_id`: Windows session ID #### `kill` Command The `kill` command implements the `process_browser:kill` supported UI feature: - Accepts `pid` or `process_id` parameter (from Process Browser) - Automatically verifies process existence before termination - Protects critical system processes (PIDs 0, 4, 8) - Reports "Process Termination" artifact with PID - Provides detailed error messages for different failure scenarios #### Process Browser Parameters When using Process Browser UI actions, the following parameters are automatically passed: - `host`: Host name (from Process Browser) - `process_id`: Process ID (from Process Browser, takes precedence over `pid`) - `architecture`: Process architecture (from Process Browser) For more information, see the [Mythic Process Browser documentation](https://docs.mythic-c2.net/customizing/hooking-features/process_list). --- ## 🎨 Artifacts Support Cazalla automatically reports artifacts created during command execution, allowing Mythic to track artifacts like process creation, file writes, and other system modifications. ### Features - **Automatic Artifact Detection**: Shell commands automatically report Process Create artifacts - **Process Create Tracking**: Every `shell` command execution creates an artifact showing the command line - **Artifact Management**: Artifacts appear in Mythic's Artifacts page (click the fingerprint icon) - **Extensible**: Easy to add artifact reporting for other commands (File Write, Network Connection, etc.) - **API Call**: Reported for: - `screenshot` - GDI Screen Capture (GetDC, CreateCompatibleDC, CreateCompatibleBitmap, BitBlt, GetDIBits) - `keylog_start` - Keyboard Hook (GetAsyncKeyState, GetForegroundWindow, GetWindowTextA, GetUserNameA) - **Network Connection**: Reported for: - `rpfwd start` - Reverse port forward listener started on port ### How It Works 1. **Agent Execution**: When a command like `shell whoami` is executed, the agent: - Executes the command via `_popen()` - Captures the output - Includes the command string in the response payload 2. **Translator Detection**: The translator detects the command in the response: - Looks for the artifact marker (`0xFF`) in the response - Extracts the command string - Creates a `Process Create` artifact entry 3. **Mythic Integration**: The artifact is automatically: - Added to the response JSON - Tracked in Mythic's Artifacts page - Associated with the task and callback ### Example Artifact Response When you execute `shell whoami`, the response includes: ```json { "task_id": "...", "user_output": "CETP-WIN11-01\\localuser", "artifacts": [ { "base_artifact": "Process Create", "artifact": "whoami", "needs_cleanup": false, "resolved": false } ] } ``` ### Viewing Artifacts 1. Navigate to your callback in the Mythic UI 2. Click the **Artifacts** icon (fingerprint) in the top navigation 3. View all artifacts created by all commands across all callbacks 4. Filter by artifact type, needs cleanup, resolved status, etc. ### Supported Artifact Types Currently supported: - **Process Create**: Automatically reported for all `shell` commands - **File Write**: Automatically reported for: - `cp` (copy) - reports destination file path - `mkdir` (create directory) - reports created directory path - `upload` - reports destination file path when uploading files - **File Delete**: Automatically reported for: - `rm` (delete) - reports deleted file/directory path - **File Read**: Automatically reported for: - `download` - reports file path when downloading files - **Process Termination**: Automatically reported for: - `kill` - reports terminated process PID (e.g., "Process Termination: PID 1234") - **API Call**: Reported for: - `screenshot` - GDI Screen Capture (GetDC, CreateCompatibleDC, CreateCompatibleBitmap, BitBlt, GetDIBits) - `keylog_start` - Keyboard Hook (GetAsyncKeyState, GetForegroundWindow, GetWindowTextA, GetUserNameA) **Note**: The following commands don't require artifacts as they are read-only or don't modify system state: - `ls`, `cd`, `pwd` - read-only file system operations - `ps` - already integrated with Process Browser - `sleep`, `exit` - don't modify system state - `cat` - read-only file operation (doesn't create artifacts, but may report credentials) Future support can be added for: - **Network Connection**: When network operations occur (e.g., for `socks` proxy connections) - **Note**: Currently implemented for `rpfwd` - **Registry Modification**: When registry keys are modified (e.g., `reg_set`, `reg_delete`) - **Process Inject**: When processes are injected into (e.g., `inject` command) ### Implementation Details The artifact system uses: - **Agent Side Helper** (`paquete.c`): `addArtifact()` function to easily add artifacts to any command response - **Agent Side** (command handlers): Call `addArtifact(paquete, "Artifact Type", "artifact value")` after adding response output - **Translator Side** (`commands_from_implant.py`): Automatically detects, parses, and creates artifact JSON for all artifact types - **Helper Function**: `create_artifact()` in the translator provides a clean API for creating artifacts ### Extending Artifacts for Other Commands To add artifact support to other commands, use the `addArtifact()` helper function: 1. **Include the header** in your C file: ```c #include "paquete.h" ``` 2. **Add artifact in your command handler**: ```c // After adding the response output addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE); // Add artifact using the helper function addArtifact(respuestaTarea, "Artifact Type", "artifact value"); ``` 3. **The translator automatically detects and creates the artifact** - no changes needed! Example implementations: - `shell`: Process Create artifact with command - `cp`: File Write artifact with destination path - `mkdir`: File Write artifact with directory path - `upload`: File Write artifact with destination file path - `rm`: File Delete artifact with deleted path - `download`: File Read artifact with downloaded file path - `screenshot`: API Call artifact for screen capture APIs - `keylog_start`: API Call artifact for keyboard hook APIs - `rpfwd start`: Network Connection artifact for reverse port forward listener ### Best Practices for New Commands **When developing new commands, always consider artifact and credential reporting:** #### Artifacts βœ… **Commands that SHOULD report artifacts:** - Any command that creates, modifies, or deletes files (`cp`, `mkdir`, `rm`, `upload`, `download`) - Any command that executes processes (`shell`, `execute`, `inject`) - Any command that modifies registry (`reg_set`, `reg_delete`) - Any command that creates network connections (`socks`, `rpfwd`, custom network commands) - Any command that modifies system configuration ❌ **Commands that DON'T need artifacts:** - Read-only operations (`ls`, `cd`, `pwd`, `cat`, `read`) - these don't modify system state - Information gathering commands (`ps`, `whoami`, `hostname`) - unless they create processes - Commands that only change local state (`sleep`, `exit`) **Rule of thumb**: If the command modifies system state or creates forensic evidence, it should report an artifact. #### Credentials βœ… **Commands that SHOULD report credentials:** - Commands that extract credentials from system memory (LSASS dumps, SAM, etc.) - Commands that read configuration files containing credentials (`cat`, file readers) - Commands that extract authentication data (certificates, keys, tickets, cookies) - Commands that parse credential databases (browsers, password managers, etc.) - Commands that intercept authentication traffic - Any command that discovers passwords, hashes, or other authentication material **Note on `cat`/file reading commands**: While read-only operations don't need artifacts, they SHOULD analyze content and report discovered credentials using `addCredential()`. The `cat` command is a perfect example - it automatically detects and reports: - Format `username:password` (e.g., `marcos:password123`) - Format `dominio\usuario:password` (e.g., `test\marcos:password`, extracts realm="test", account="marcos") - Format `usuario@dominio:password` (e.g., `marcos@tes.com:password`, extracts realm="tes.com", account="marcos") - Passwords in format `password=value` or `password:value` - HTTP URLs with embedded credentials: `http://user:pass@host` - NTLM hashes (format `aad3b435b51404ee:hash` or `:32hexchars`) **How to add credentials in your command:** ```c // After discovering credentials, add them to the response addCredential(respuestaTarea, "plaintext", "DOMAIN", "password123", "username"); addCredential(respuestaTarea, "hash", "", "aad3b435b51404ee...", "Administrator"); // For domain accounts with formato dominio\usuario: // Extract domain as realm, username as account addCredential(respuestaTarea, "plaintext", "DOMAIN", "password", "username"); // For format usuario@dominio, extract domain as realm: addCredential(respuestaTarea, "plaintext", "tes.com", "password", "marcos"); ``` For more information, see the [Mythic Artifacts documentation](https://docs.mythic-c2.net/customizing/hooking-features/artifacts). --- ## πŸ”‘ Credentials Support Cazalla supports reporting discovered credentials to Mythic's credential store, allowing you to track and manage credentials discovered during operations. ### Features - **Automatic Credential Detection**: Commands can report discovered credentials using the `addCredential()` helper - **Multiple Credential Types**: Supports `plaintext`, `hash`, `certificate`, `key`, `ticket`, and `cookie` - **Credential Management**: Credentials appear in Mythic's Credentials page (click the key icon) - **Associated with Tasks**: Credentials are linked to the task and callback that discovered them ### How It Works 1. **Agent Execution**: When a command discovers credentials (e.g., dumping LSASS, extracting hashes), it: - Calls `addCredential()` with the credential details - Includes credential data in the response payload 2. **Translator Detection**: The translator detects credentials in the response: - Looks for the credential marker (`0xFE`) in the response - Extracts credential type, realm, credential value, and account - Creates credential entries in the JSON response 3. **Mythic Integration**: Credentials are automatically: - Added to the response JSON - Tracked in Mythic's Credentials page - Associated with the task and callback ### Example Credential Response When you execute a command that discovers credentials, the response includes: ```json { "task_id": "...", "user_output": "Credentials extracted successfully", "credentials": [ { "credential_type": "plaintext", "realm": "spooky.local", "credential": "SuperS3Cr37", "account": "itsafeature" }, { "credential_type": "hash", "realm": "", "credential": "aad3b435b51404eeaad3b435b51404ee:...", "account": "Administrator" } ] } ``` ### Supported Credential Types According to [Mythic Credentials documentation](https://docs.mythic-c2.net/customizing/hooking-features/credentials), the following types are supported: - **plaintext**: Plain text passwords - **hash**: Password hashes (NTLM, SHA1, etc.) - **certificate**: Certificates - **key**: Cryptographic keys - **ticket**: Kerberos tickets - **cookie**: Web cookies/session tokens ### Viewing Credentials 1. Navigate to your callback in the Mythic UI 2. Click the **CREDENTIALS** icon (key) in the top navigation 3. View all credentials discovered by all commands across all callbacks 4. Filter by credential type, realm, account, etc. ### Implementation Details The credential system uses: - **Agent Side Helper** (`paquete.c`): `addCredential()` function to easily add credentials to any command response - **Agent Side** (command handlers): Call `addCredential(paquete, "credential_type", "realm", "credential", "account")` after adding response output - **Translator Side** (`commands_from_implant.py`): Automatically detects, parses, and creates credential JSON - **Format**: `[0xFE marker][type_len:4][type][realm_len:4][realm][credential_len:4][credential][account_len:4][account]` ### Using Credentials in Commands To add credential reporting to a command: ```c // After extracting credentials, add them to the response addCredential(respuestaTarea, "plaintext", "DOMAIN", "password123", "username"); addCredential(respuestaTarea, "hash", "", "aad3b435b51404ee...", "Administrator"); // For local accounts, realm can be empty string addCredential(respuestaTarea, "hash", "", "ntlm_hash_here", "LOCALUSER"); ``` **Example use cases:** - LSASS dumping tools β†’ `hash` credentials - Credential extraction commands β†’ `plaintext` or `hash` credentials - Certificate extraction β†’ `certificate` credentials - Kerberos ticket extraction β†’ `ticket` credentials - Browser credential extraction β†’ `plaintext` or `cookie` credentials - **`cat` command** β†’ Automatically detects and reports credentials found in file contents: - Passwords in format `password=value` or `password:value` - HTTP URLs with embedded credentials: `http://user:pass@host` - NTLM hashes (format `aad3b435b51404ee:hash` or `:32hexchars`) - Extracts usernames when found in the same line **Note**: Commands that only READ files (like `cat`) should NOT add artifacts since they don't modify system state. However, they CAN analyze content and report discovered credentials using `addCredential()`. **Example for `cat` command:** ```c // Read file contents // ... read file code ... // If credentials are discovered in the file content, report them: if (found_password) { addCredential(respuestaTarea, "plaintext", "", "password123", "username"); } // Do NOT add artifacts for read-only operations: // addArtifact(respuestaTarea, "File Write", file_path); // ❌ WRONG - file wasn't written ``` For more information, see the [Mythic Credentials documentation](https://docs.mythic-c2.net/customizing/hooking-features/credentials). --- ## πŸ“₯ File Downloads Support Cazalla supports downloading files from the target to the Mythic server using chunked transfers, following [Mythic's File Downloads specification](https://docs.mythic-c2.net/customizing/hooking-features/download). ### Features - **Chunked File Transfers**: Large files are automatically split into chunks (512KB default) for efficient transfer - **Automatic Registration**: Files are automatically registered with Mythic before transfer - **Progress Tracking**: Mythic tracks download progress (chunks received/total chunks) - **File Read Artifacts**: Automatically reports File Read artifacts when files are downloaded - **Full Path Tracking**: Reports full file paths for proper tracking in Mythic's file browser ### How It Works 1. **Command Execution**: When you execute `download C:\path\to\file.txt`, the agent: - Opens the file for reading - Calculates file size and number of chunks needed - Sends a registration message to Mythic with file metadata (`total_chunks`, `full_path`, `chunk_size`) - Receives a `file_id` from Mythic - Reads and sends file data in chunks (base64-encoded) - Reports a File Read artifact when complete 2. **Mythic Integration**: The download is automatically: - Registered in Mythic's file browser - Tracked with progress (chunks received/total) - Available for download from the Mythic UI once all chunks are received ### Using the Download Command ```bash # Download a file from the target download C:\Users\localuser\Downloads\file.txt # Downloads are chunked automatically - Mythic will show progress: # "0 / 5 Chunks Received" β†’ "5 / 5 Chunks Received" (complete) ``` ### Download Process 1. **Registration**: Agent sends file metadata to Mythic - `full_path`: Full path to the file - `total_chunks`: Number of chunks needed - `chunk_size`: Size of each chunk (512KB default) 2. **File ID**: Mythic responds with a unique `file_id` for this download 3. **Chunk Transfer**: Agent sends each chunk sequentially: - Chunk number (1-based) - `file_id` to associate with registration - Base64-encoded chunk data 4. **Completion**: Once all chunks are received, the file appears in Mythic's file browser ### Example Download Flow ``` Agent: [download] Registrando descarga: C:\Users\file.txt (1024000 bytes, 2 chunks) Mythic: Response with file_id: "uuid-here" Agent: [download] Enviando chunk 1/2 (512000 bytes) Agent: [download] Enviando chunk 2/2 (512000 bytes) Agent: [download] Descarga completada: C:\Users\file.txt (1024000 bytes) Mythic: File available in file browser ``` ### Implementation Details The download system uses: - **Chunk Size**: 512KB per chunk (configurable in code) - **File Size Limit**: Supports files up to 2GB (can be extended) - **Base64 Encoding**: Chunk data is base64-encoded before transmission - **Artifact Reporting**: Automatically reports "File Read" artifact with file path ### Error Handling The download command handles various error scenarios: - **File Not Found**: Returns error message if file cannot be opened - **File Too Large**: Returns error if file exceeds 2GB limit - **Empty Files**: Properly handles empty files (0 bytes) - **Access Denied**: Returns Windows error code if access is denied ### Viewing Downloaded Files 1. Navigate to your callback in the Mythic UI 2. Click the **Files** icon (file browser) in the top navigation 3. View all downloaded files with their metadata 4. Download files to your local system For more information, see the [Mythic File Downloads documentation](https://docs.mythic-c2.net/customizing/hooking-features/download). --- ## πŸ“€ File Uploads Support Cazalla supports uploading files from the Mythic server to the target using chunked transfers, following [Mythic's File Upload specification](https://docs.mythic-c2.net/customizing/hooking-features/action-upload). ### Features - **Chunked File Transfers**: Large files are automatically split into chunks (512KB default) for efficient transfer - **Automatic Path Normalization**: Automatically handles path formatting (normalizes double backslashes) - **Smart Path Handling**: Automatically appends filename when path is a directory or doesn't have a file extension - **File Browser Integration**: Fully integrated with Mythic's File Browser UI - upload files directly from the browser - **Progress Tracking**: Mythic tracks upload progress (chunks sent/total chunks) - **File Write Artifacts**: Automatically reports File Write artifacts when files are uploaded - **Parent Directory Creation**: Automatically creates parent directories if they don't exist ### How It Works 1. **Command Execution**: When you execute `upload C:\path\to\destination.txt`, the agent: - Receives the `file_id` and destination path from Mythic - Normalizes the destination path (handles double backslashes, directories, etc.) - Creates the destination file - Requests file chunks from Mythic sequentially - Receives base64-encoded chunk data from Mythic - Decodes and writes chunks to the destination file - Reports a File Write artifact when complete 2. **Mythic Integration**: The upload is automatically: - Tracked with progress in Mythic's UI - Registered as a File Write artifact - Visible in Mythic's Artifacts page ### Using the Upload Command #### From Command Line ```bash # Upload a file to the target # Select file from Mythic UI file selector, then specify destination path upload C:\Users\localuser\Downloads\file.txt # If path is a directory, filename is automatically appended upload C:\Users\localuser\Downloads # β†’ Automatically becomes: C:\Users\localuser\Downloads\ # Uploads are chunked automatically - Mythic will show progress ``` #### From File Browser UI The `upload` command is fully integrated with Mythic's File Browser: 1. Navigate to **Files** icon in the top navigation 2. Browse to the target directory where you want to upload 3. Click the **Upload** button (or right-click on a directory) 4. Select the file from your local system 5. The agent automatically detects if the path is a directory and appends the filename **Note**: When uploading from the File Browser, you can specify: - A full file path: `C:\Users\localuser\Downloads\file.txt` β†’ Uploads to exact path - A directory path: `C:\Users\localuser\Downloads` β†’ Automatically appends filename from source file ### Upload Process 1. **Request**: Agent sends upload request to Mythic for each chunk: - `file_id`: Unique identifier for the file to upload - `chunk_num`: Automatically incremented (1, 2, 3, ...) - `chunk_size`: Size requested per chunk (512KB default) - `full_path`: Destination path on the target 2. **Response**: Mythic responds with chunk data: - `total_chunks`: Total number of chunks for the file - `chunk_num`: Current chunk number - `chunk_data`: Base64-encoded chunk data 3. **Writing**: Agent decodes and writes each chunk sequentially 4. **Completion**: Once all chunks are received and written, the file is complete ### Example Upload Flow ``` Mythic: Task created with file_id and path Agent: [upload] Iniciando upload: C:\Users\file.txt (2 chunks) Agent: [upload] Solicitando chunk requesting chunk 1 Mythic: Response with chunk 1/2 (512KB base64 data) Agent: [upload] Chunk 1/2 escrito: 512000 bytes Agent: [upload] Solicitando chunk requesting chunk 2 Mythic: Response with chunk 2/2 (512KB base64 data) Agent: [upload] Chunk 2/2 escrito: 512000 bytes Agent: [upload] Upload completado: C:\Users\file.txt (1024000 bytes) Mythic: File Write artifact created ``` ### Path Handling The upload command includes smart path handling with multiple detection methods: - **Normalization**: Automatically normalizes double backslashes (`C:\\\\Users` β†’ `C:\Users`) - **Invalid Character Cleaning**: Removes null bytes, carriage returns, newlines, and other invalid characters - **Directory Detection**: Multiple heuristics to detect directories: - Path ends with `\` or `/` β†’ Treated as directory, filename appended - Path has no file extension in the last component β†’ Treated as directory, filename appended - Path is a drive letter (e.g., `C:`) β†’ Treated as directory, filename appended - Path exists and is a directory β†’ Treated as directory, error reported if no filename - **Full Path Resolution**: Uses `GetFullPathNameA` to resolve relative paths to absolute paths - **Parent Directory Creation**: Automatically creates parent directories if they don't exist - **Error Handling**: Clear error messages for: - Invalid paths (Error 123: invalid filename syntax) - Directory without filename specified - Access denied errors - Path not found errors ### Implementation Details The upload system uses: - **Chunk Size**: 512KB per chunk (configurable in code) - **Base64 Decoding**: Chunk data is automatically decoded from base64 before writing - **Sequential Requests**: Agent requests chunks one at a time (1, 2, 3, ...) - **Artifact Reporting**: Automatically reports "File Write" artifact with file path ### Error Handling The upload command handles various error scenarios: - **Invalid Path (Error 123)**: Returns error if path contains invalid characters or malformed syntax - Automatically cleans null bytes, control characters, and invalid path characters - Handles UNC paths (`\\server\share`) correctly - **Directory as Path**: Detects and reports clear error if path is a directory without filename - Error message: "El path es un directorio existente. Especifique un nombre de archivo" - **Access Denied**: Returns Windows error code if file cannot be created/written - **Path Not Found**: Automatically creates parent directories, or returns error if creation fails ### Viewing Upload Artifacts 1. Navigate to your callback in the Mythic UI 2. Click the **Artifacts** icon (fingerprint) in the top navigation 3. Filter by "File Write" artifact type 4. View all files that were uploaded, including file paths and timestamps ### File Browser Integration The `upload` command supports Mythic's File Browser UI feature (`file_browser:upload`): - **Seamless Integration**: Upload files directly from the File Browser interface - **Smart Path Resolution**: Automatically handles directory paths from File Browser - **Progress Tracking**: Real-time progress visible in Mythic UI - **Artifact Tracking**: All uploads automatically logged as "File Write" artifacts **How it works**: 1. File Browser sends `path` parameter with directory path (e.g., `C:\Users\localuser\Downloads`) 2. Python `upload.py` detects the path is a directory (no file extension) 3. Retrieves the original filename from the `file_id` via Mythic RPC 4. Automatically appends filename to directory path 5. Sends complete path to agent: `C:\Users\localuser\Downloads\config.json` For more information, see the [Mythic File Upload documentation](https://docs.mythic-c2.net/customizing/hooking-features/action-upload) and [File Browser documentation](https://docs.mythic-c2.net/customizing/hooking-features/file-browser). --- ## ⌨️ Keylogging Support Cazalla supports capturing keystrokes from the target system and reporting them to Mythic's Keylogs feature, following [Mythic's Keylog specification](https://docs.mythic-c2.net/customizing/hooking-features/keylog). ### Features - **Window-Aware Keylogging**: Captures keystrokes along with the active window title - **User Context**: Includes the username in each keylog entry - **Process-Agnostic**: Works with any application (Notepad, browsers, terminals, etc.) - **Automatic Buffering**: Buffers keystrokes and sends them periodically (every 3 seconds or 128 bytes) - **Background Thread**: Runs as a separate thread, allowing other commands to execute while keylogging - **API Call Artifacts**: Automatically reports API Call artifacts when keylogging starts ### How It Works 1. **Start Keylogging**: When you execute `keylog_start`, the agent: - Starts a background thread that monitors keyboard input - Uses `GetAsyncKeyState` to detect key presses - Captures the active window title using `GetForegroundWindow` and `GetWindowTextA` - Captures the current username using `GetUserNameA` - Buffers keystrokes and sends them every 3 seconds or when buffer reaches 128 bytes 2. **Keylog Transmission**: The keylogger periodically sends captured keystrokes: - Each transmission includes: user, window title, and captured keystrokes - Format follows Mythic's keylog specification - Keylogs appear in Mythic's Keylogs UI automatically 3. **Stop Keylogging**: When you execute `keylog_stop`, the agent: - Stops the background keylogging thread - Sends a final acknowledgment response ### Using the Keylog Commands ```bash # Start keylogging keylog_start # Stop keylogging keylog_stop ``` ### Keylog Process 1. **Start**: Agent creates a background thread that: - Polls keyboard state every 20ms - Detects key presses using `GetAsyncKeyState` - Captures printable ASCII characters and special keys (Backspace, Tab, Enter) - Gets the active window title and username on each send cycle 2. **Buffer & Send**: Keystrokes are buffered and sent when: - Buffer reaches 128 bytes, OR - 3 seconds have passed since last send (if buffer has data) 3. **Format**: Each keylog entry contains: - `user`: Current Windows username (e.g., "localuser") - `window_title`: Title of the active window (e.g., "*hello, this is a test - Notepad") - `keystrokes`: Actual captured keystrokes 4. **Stop**: Background thread is terminated gracefully ### Example Keylog Flow ``` Agent: [keylog] Started # User types in Notepad... Agent: [KEYLOG] Detectado keylog para user='localuser', window='*hello, this is a test - Notepad' Mythic: Keylog appears in Keylogs tab # More typing... Agent: [KEYLOG] Detectado keylog para user='localuser', window='*hello, this is a test - Notepad' Mythic: Additional keystrokes added to keylog entry Agent: [keylog] Stopped ``` ### Universal Process Support The keylogger works with **any Windows application** because it: - Uses `GetForegroundWindow()` to get the currently active window - Captures keystrokes system-wide using `GetAsyncKeyState` - Doesn't require injection into specific processes **This means it works for:** - βœ… Text editors (Notepad, VS Code, etc.) - βœ… Browsers (Chrome, Firefox, Edge) - βœ… Terminal windows (cmd.exe, PowerShell) - βœ… Any application that receives keyboard input - βœ… Secure input fields (though characters may appear as visible in the buffer) ### Implementation Details The keylogging system uses: - **Polling Method**: `GetAsyncKeyState` to detect key presses (low-level approach) - **Window Detection**: `GetForegroundWindow` + `GetWindowTextA` to identify active windows - **User Detection**: `GetUserNameA` to get current Windows username - **Thread Safety**: Runs in a separate thread, allowing concurrent command execution - **Buffer Management**: 2048-byte buffer to store keystrokes before transmission - **Artifact Reporting**: Automatically reports "API Call" artifact when keylogging starts ### Error Handling The keylog commands handle various scenarios: - **Already Running**: If keylogger is already active, `keylog_start` returns success without creating duplicate threads - **Not Running**: If keylogger is not running, `keylog_stop` returns success (no-op) - **Thread Cleanup**: Thread is properly terminated and handles are closed when stopping ### Viewing Keylogs 1. Navigate to your callback in the Mythic UI 2. Click the **KEYLOGS** tab in the top navigation 3. View all captured keystrokes grouped by: - Task and callback - User and host - Window title - Timestamp 4. Use "View Window Together" to see all keystrokes from a specific window session 5. Filter keylogs by user, window, or time range ### Artifact Support The `keylog_start` command automatically reports an **API Call** artifact: - **Type**: API Call - **Value**: "Keyboard Hook: GetAsyncKeyState, GetForegroundWindow, GetWindowTextA, GetUserNameA" - **Purpose**: Tracks that keylogging APIs were used on the system This artifact appears in Mythic's Artifacts page when keylogging is started. For more information, see the [Mythic Keylog documentation](https://docs.mythic-c2.net/customizing/hooking-features/keylog). --- ## πŸ” Token Support Cazalla supports Windows token manipulation and impersonation, following [Mythic's Token specification](https://docs.mythic-c2.net/customizing/hooking-features/tokens). ### Features - **Token Listing**: Enumerate all viewable tokens from running processes - **Token Theft**: Steal tokens from processes to impersonate different users - **Token Creation**: Create new tokens using credentials (domain, username, password) - **Token Impersonation**: Impersonate tokens for subsequent tasking - **Token Revert**: Revert to original token when done impersonating - **Token Tasking**: Use stolen/created tokens for executing commands with different privileges - **SeDebugPrivilege**: Automatically enables `SeDebugPrivilege` for accessing system processes - **Mythic Integration**: Tokens are tracked in Mythic's Token UI and can be selected for tasking ### How It Works Cazalla implements token functionality following Mythic's token specification: 1. **Token Listing** (`list_tokens`): - Enumerates all running processes - Opens each process token with `OpenProcessToken` - Extracts user information, session ID, and process details - Reports tokens to Mythic using the `tokens` key in `post_response` - Tokens are viewable in Mythic's **Search β†’ Tokens** page - Displays token information including: Token ID, PID, Process name, User, and Session 2. **Token Theft** (`steal_token `): - Opens the target process with appropriate access rights - Opens and duplicates the process token - Impersonates the token using `ImpersonateLoggedOnUser` - Registers the token as a `callback_token` for use in subsequent tasking - Reports a "Token Impersonation" artifact - The token becomes available in the Mythic UI for tasking 3. **Token Creation** (`make_token domain username password [logon_type]`): - Creates a new token using `LogonUserA` with provided credentials - Impersonates the newly created token - Registers the token as a `callback_token` for use in tasking - Reports a "Token Creation" artifact - Default `logon_type` is `9` (LOGON32_LOGON_NEW_CREDENTIALS) if not specified 4. **Token Revert** (`rev2self`): - Calls `RevertToSelf()` to revert to the original process token - Closes the impersonated token handle - Useful after completing operations with an impersonated token 5. **Token Tasking**: - When a token is registered as a `callback_token`, it appears in the Mythic UI - You can select a token from the dropdown when issuing tasks - The translator automatically includes the `token_id` in task messages - Commands executed with a selected token run under that token's security context ### Using Token Commands #### List Available Tokens ```bash # List all viewable tokens from running processes list_tokens ``` Output format: ``` Token ID: 1 | PID: 76 | Process: smss.exe | User: NT AUTHORITY\SYSTEM | Session: 0 Token ID: 2 | PID: 116 | Process: csrss.exe | User: NT AUTHORITY\SYSTEM | Session: 0 Token ID: 16 | PID: 1060 | Process: svchost.exe | User: NT AUTHORITY\SYSTEM | Session: 1 ... ``` #### Steal Token from a Process ```bash # Steal token from PID 1060 (SYSTEM process) steal_token 1060 ``` After stealing a token: - The agent impersonates the token immediately - The token is registered in Mythic as a `callback_token` - You can verify impersonation with `whoami` - Subsequent commands will run with that token's privileges (if selected in Mythic UI) #### Create Token with Credentials ```bash # Create token for domain user make_token DOMAIN username password # Create token with specific logon type # Logon types: 2=Interactive, 3=Network, 9=NewCredentials (default) make_token DOMAIN username password 9 ``` #### Verify Token Impersonation ```bash # Check current user context (before stealing token) whoami # Output: CETP-WIN11-01\localuser # Steal token from SYSTEM process steal_token 1060 # Check current user context (after stealing token) whoami # Output: NT AUTHORITY\SYSTEM # Revert to original token rev2self # Check current user context (after reverting) whoami # Output: CETP-WIN11-01\localuser ``` #### Using Tokens for Tasking 1. Execute `list_tokens` to see available tokens 2. Execute `steal_token ` to steal a token (or use `make_token` to create one) 3. In the Mythic UI, a dropdown appears next to the tasking bar 4. Select a token from the dropdown before issuing commands 5. Commands will execute with the selected token's security context **Note**: Token selection in Mythic UI is handled automatically by the framework. The translator includes the `token_id` in the task message when a token is selected. ### Session Considerations - **Session 0**: System services and processes run in Session 0 - **Session 2+**: User sessions start from Session 2 - Some processes may only be accessible if running with administrator privileges - The `EnableSeDebugPrivilege` function is called automatically to access protected processes ### Implementation Details The token system uses: - **SeDebugPrivilege**: Automatically enabled for accessing system processes - **OpenProcessToken**: Opens process tokens with appropriate access rights - **DuplicateTokenEx**: Duplicates tokens for impersonation - **ImpersonateLoggedOnUser**: Impersonates tokens on the current thread - **RevertToSelf**: Reverts to the original process token - **Process Enumeration**: Uses `CreateToolhelp32Snapshot` to enumerate processes - **Token Information**: Uses `GetTokenInformation` and `LookupAccountSidA` to extract user info ### Error Handling Token operations handle various scenarios: - **Access Denied**: Falls back to `PROCESS_QUERY_LIMITED_INFORMATION` if full access fails - **Protected Processes**: Some system processes may require elevated privileges - **Invalid PID**: Validates PID and rejects PIDs 0 and 2 (reserved) - **Token Opening**: Attempts multiple access rights combinations if initial attempt fails - **Privilege Escalation**: Automatically enables `SeDebugPrivilege` when needed ### Viewing Tokens 1. Execute `list_tokens` to enumerate tokens 2. Navigate to **Search β†’ Tokens** in the Mythic UI 3. View all tokens with details: - Token ID (agent-generated unique identifier) - Host (computer name) - User (account name) - Process ID - Session ID - Process name (from `list_tokens` output) 4. Tokens registered as `callback_tokens` (via `steal_token` or `make_token`) appear in the tasking dropdown ### Artifact Support Token commands automatically report artifacts: - **`steal_token`**: Reports "Token Impersonation" artifact with PID and user information - **`make_token`**: Reports "Token Creation" artifact with domain, username, and logon type These artifacts appear in Mythic's Artifacts page when token operations are performed. ### Verification Tips 1. **Before and After**: Use `whoami` before and after `steal_token` to verify impersonation 2. **Session 0 vs Session 2**: Tokens from Session 0 processes are accessible with administrator privileges 3. **Process Names**: Use `list_tokens` to see process names alongside PIDs 4. **Token ID**: The `token_id` in `list_tokens` output can be used to identify tokens, but for tasking, Mythic uses the token registered via `callback_tokens` ### Security Considerations - **Token Impersonation**: Allows executing commands with different privileges - **SeDebugPrivilege**: Required for accessing system process tokens - **Token Theft**: Can be detected by security monitoring tools - **Session Isolation**: Tokens from different sessions may have different access rights - **Token Lifetime**: Impersonated tokens remain active until `rev2self` is called For more information, see the [Mythic Tokens documentation](https://docs.mythic-c2.net/customizing/hooking-features/tokens). --- ## πŸ“Š Context Tracking Cazalla supports **Context Tracking** to display dynamic callback context information (like current working directory and impersonation context) as tabs in the Mythic UI. This feature enhances the operator experience by providing immediate visibility into the agent's current state. ### Overview Context Tracking allows Mythic to display callback-specific information as dynamic tabs above the tasking area. These tabs update automatically as the agent's context changes, providing real-time visibility into: - **Current Working Directory (`cwd`)**: The agent's current directory - **Impersonation Context (`impersonation_context`)**: The currently impersonated user (if any) ### How It Works 1. **Initial Check-in**: The agent automatically includes `cwd` and `impersonation_context` in the initial check-in message 2. **Dynamic Updates**: Commands that change the context (like `cd`, `steal_token`, `rev2self`) automatically update and report the new context 3. **UI Display**: Mythic displays these fields as dynamic tabs above the tasking area ### Supported Context Fields #### Current Working Directory (`cwd`) - **Updated by**: `cd` command - **Initial value**: Automatically set during check-in with the process's current directory - **Display**: Shows the current directory path (e.g., `C:\Users\localuser\Downloads`) #### Impersonation Context (`impersonation_context`) - **Updated by**: `steal_token`, `make_token`, `rev2self` - **Initial value**: Automatically set during check-in with the process's current user (format: `DOMAIN\username`) - **Display**: Shows the currently impersonated user (e.g., `NT AUTHORITY\SYSTEM`) ### Commands That Update Context #### `cd` Command ```bash # Change directory - automatically updates cwd context cd {"path":"C:\\Windows"} ``` After executing `cd`, the `cwd` tab in Mythic UI will update to show the new directory. #### `steal_token` Command ```bash # Steal token from a process - automatically updates impersonation_context steal_token 1060 ``` After stealing a token, the `impersonation_context` tab will show the impersonated user (e.g., `NT AUTHORITY\SYSTEM`). #### `make_token` Command ```bash # Create token with credentials - automatically updates impersonation_context make_token DOMAIN username password ``` After creating a token, the `impersonation_context` tab will show the new user context. #### `rev2self` Command ```bash # Revert to original token - clears impersonation_context rev2self ``` After reverting, the `impersonation_context` tab will be cleared (or show the original user). ### Technical Implementation #### Binary Protocol Context updates are sent using a special marker in task responses: ``` [0xF0 marker][field_name_len:4][field_name][field_value_len:4][field_value]... ``` - **Marker**: `0xF0` indicates callback context data - **Field Name**: Name of the context field (e.g., `cwd`, `impersonation_context`) - **Field Value**: The actual value to update Multiple fields can be sent in a single response by repeating the pattern. #### Check-in Format During initial check-in, context fields are included directly in the check-in message and added to the root JSON: ```json { "action": "checkin", "uuid": "...", "host": "...", "cwd": "C:\\Users\\localuser", "impersonation_context": "CETP-WIN11-01\\localuser", ... } ``` #### Task Response Format In task responses, context updates are included in the `callback` key: ```json { "action": "post_response", "responses": [{ "task_id": "...", "completed": true, "callback": { "cwd": "C:\\Windows", "impersonation_context": "NT AUTHORITY\\SYSTEM" }, "user_output": "..." }] } ``` ### UI Configuration Context tabs are automatically displayed in the Mythic UI when context data is available. You can configure their appearance in Mythic settings: 1. Navigate to **Settings** β†’ **Tasking Context Tabs** 2. Select which fields to display (`cwd`, `impersonation_context`) 3. Configure colors and styling if desired ### Example Usage ```bash # 1. Agent checks in - tabs appear showing initial context # Tab: "Dir: C:\Users\localuser\Downloads" # Tab: "User: CETP-WIN11-01\localuser" # 2. Change directory cd {"path":"C:\\Windows"} # Tab updates: "Dir: C:\Windows" # 3. Steal SYSTEM token steal_token 1060 # Tab updates: "User: NT AUTHORITY\SYSTEM" # 4. Revert token rev2self # Tab updates: "User: CETP-WIN11-01\localuser" ``` ### Debugging To verify context tracking is working: 1. **Check agent logs** for messages like: ``` Checkin: AΓ±adido cwd inicial: C:\Users\localuser Checkin: AΓ±adido impersonation_context inicial: CETP-WIN11-01\localuser [steal_token] Contexto de impersonaciΓ³n actualizado: NT AUTHORITY\SYSTEM ``` 2. **Check translator logs** for messages like: ``` [CHECKIN] Callback context: cwd = 'C:\Users\localuser' [CHECKIN] Callback context: impersonation_context = 'CETP-WIN11-01\localuser' [CALLBACK_CONTEXT] cwd = 'C:\Windows' [CALLBACK_CONTEXT] impersonation_context = 'NT AUTHORITY\SYSTEM' ``` 3. **Verify in Mythic UI**: Context tabs should appear above the tasking area and update automatically. For more information, see the [Mythic Context Tracking documentation](https://docs.mythic-c2.net/customizing/hooking-features/context-tracking). --- ## πŸ›‘οΈ OPSEC Checking Cazalla includes comprehensive **OPSEC Checking** functionality that provides operational security warnings and blocking for commands based on their detection risks. This feature helps operators make informed decisions and prevents accidental OPSEC violations. ### Overview OPSEC Checking is implemented using two types of checks: 1. **`opsec_pre`**: Runs **before** task creation (`create_tasking`). Can block the task if it detects high-risk operations. 2. **`opsec_post`**: Runs **after** task creation but **before** the agent picks up the task. Provides final warnings about artifacts that will be created. ### How It Works #### OPSEC Pre-Check (`opsec_pre`) The `opsec_pre` function evaluates the command parameters before creating the task: - **Blocking**: Can set `OpsecPreBlocked=True` to prevent task execution - **Warning**: Can provide detailed warnings without blocking - **Bypass Roles**: Defines who can approve blocked tasks: - `operator`: Any operator can bypass - `other_operator`: Requires approval from a different operator - `lead`: Only operation lead can approve **Example Flow:** ``` 1. Operator creates task: shell whoami 2. opsec_pre detects "whoami" has safer alternative 3. Task is BLOCKED with message explaining why 4. Another operator must approve to proceed ``` #### OPSEC Post-Check (`opsec_post`) The `opsec_post` function runs after task creation but before agent execution: - **Artifact Review**: Warns about artifacts that will be created - **Final Warning**: Last chance to cancel before agent picks up task - **Context-Aware**: Can review artifacts generated by `create_tasking` **Example Flow:** ``` 1. opsec_pre passes (or is bypassed) 2. create_tasking executes 3. opsec_post reviews artifacts 4. Task is submitted to agent (if approved) ``` ### Commands with OPSEC Checking #### High-Risk Commands (Blocking) | Command | Blocking Conditions | Bypass Role | |---------|---------------------|-------------| | `shell` | Commands with safer Cazalla alternatives (`whoami`, `tasklist`, `powershell`, etc.) | `other_operator` | | `steal_token` | Critical system processes (PID 4) | `other_operator` | | `kill` | Critical system processes (PID 0, 4, 8) | `other_operator` | | `keylog_start` | Always blocked (extremely detectable) | `lead` | | `rm` | Critical system files/directories (System32, SysWOW64, Windows, Boot) | `other_operator` | #### Warning-Only Commands | Command | Warning Type | Bypass Role | |---------|-------------|-------------| | `screenshot` | Screen capture detection | `operator` | | `rpfwd` | Network activity monitoring | `operator` | | `socks` | High-volume network traffic | `operator` | | `download` | Sensitive file access | `operator` | | `upload` | Executable/script uploads | `operator` | | `make_token` | Authentication event logging | `operator` | | `rev2self` | Token reversion | `operator` | | `list_tokens` | Token enumeration | `operator` | | `cat` | Sensitive file reading | `operator` | | `rm` | File deletion (blocks for system files) | `other_operator` if blocked, `operator` if warning | | `cp` | File copying (sensitive files) | `operator` | ### Example Messages #### Blocking Message (shell whoami) ``` 🚨 OPSEC BLOCKED - Command Has Safer Alternative This command contains operations that have safer built-in alternatives in Cazalla: 🚨 whoami: Use Cazalla's 'whoami' command instead (no cmd.exe spawn) ⚠️ cmd.exe spawn: This command would spawn cmd.exe (highly detectable) πŸ’‘ SAFER ALTERNATIVES: β†’ Use: 'whoami' (Cazalla built-in, no cmd.exe) ⚠️ TO PROCEED: You need approval from another operator. This command is blocked to prevent accidental OPSEC violations. ``` #### Warning Message (download) ``` ⚠️ OPSEC WARNING - File Download Detected File downloads are monitored by: β€’ EDR/XDR solutions β€’ Data loss prevention (DLP) systems β€’ File access monitoring tools β€’ Network monitoring (large file transfers) Target File: C:\Windows\System32\config\SAM 🚨 SENSITIVE FILE DETECTED: 🚨 sam: SAM database - Credential extraction heavily monitored πŸ” DETECTION RISKS: β€’ File access events (if auditing enabled) β€’ Large file transfers (network monitoring) β€’ Sensitive file patterns (DLP detection) β€’ Unusual file access patterns βœ… This is a WARNING only - command will proceed. Ensure you understand the detection risks before continuing. ``` ### OPSEC Checking Logic #### Conditional Blocking OPSEC checking is **intelligent and conditional**: - **Blocking**: Only blocks when there's a clear safer alternative or critical risk - **Warning**: Provides informative warnings for moderate risks - **Context-Aware**: Considers command parameters (PID, file paths, etc.) #### Example: `shell` Command ```python # Blocks if command contains: - "whoami" β†’ Use Cazalla's 'whoami' instead - "tasklist" β†’ Use Cazalla's 'ps' instead - "powershell" β†’ Highly monitored, use alternatives # Warns if command contains: - "netstat" β†’ Network enumeration, proceed with caution - "ipconfig" β†’ Network queries, proceed with caution ``` ### Bypass Roles | Role | Description | Use Case | |------|-------------|----------| | `operator` | Any operator can bypass | Low-risk warnings | | `other_operator` | Requires different operator approval | High-risk operations | | `lead` | Only operation lead can approve | Critical operations (keyloggers) | ### Benefits 1. **Prevents Accidents**: Blocks dangerous commands with safer alternatives 2. **Informs Operators**: Provides detailed risk information 3. **Improves OPSEC**: Reduces accidental detection 4. **Educational**: Teaches operators about detection risks 5. **Context-Aware**: Adapts to specific command parameters ### Technical Implementation OPSEC checking is implemented in each command's Python definition: ```python async def opsec_pre(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPreTaskMessageResponse: """ OPSEC check before creating the task. """ # Analyze command parameters command = taskData.args.get_arg("command") or "" # Determine if blocking is needed blocked = False if "dangerous_pattern" in command: blocked = True # Build informative message message = "⚠️ OPSEC WARNING - ...\n\n" message += "Detailed explanation...\n" return PTTTaskOPSECPreTaskMessageResponse( TaskID=taskData.Task.ID, Success=True, OpsecPreBlocked=blocked, OpsecPreBypassRole="other_operator" if blocked else "operator", OpsecPreMessage=message ) async def opsec_post(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPostTaskMessageResponse: """ OPSEC check after creating the task. """ # Review artifacts that will be created message = "⚠️ OPSEC POST-CHECK - Artifacts\n\n" message += "Artifacts that will be created...\n" return PTTTaskOPSECPostTaskMessageResponse( TaskID=taskData.Task.ID, Success=True, OpsecPostBlocked=False, # Usually don't block in post OpsecPostBypassRole="operator", OpsecPostMessage=message ) ``` For more information, see the [Mythic OPSEC Checking documentation](https://docs.mythic-c2.net/customizing/payload-type-development/opsec-checking). --- ## πŸ“Š Logging & Syslog Cazalla includes a complete logging system that records all Mythic events and sends them to a central syslog server. ### Features - βœ… **Logs ALL events** automatically (callbacks, tasks, responses, credentials, keylogs, files, artifacts, payloads) - βœ… **Does not modify the agent** (avoids detections) - βœ… **Runs on the server**, not on the target - βœ… **Structured JSON format** for easy parsing - βœ… **One file per day** (no rotation, all files are kept) - βœ… **Simple configuration** via configuration file ### Quick Configuration 1. **Edit the configuration file:** ```bash nano Payload_Type/cazalla/logger/syslog.conf ``` 2. **Configure the syslog server IP:** ```bash SYSLOG_SERVER=10.8.20.50 # Host IP or syslog server IP SYSLOG_PORT=514 SYSLOG_FACILITY=16 ``` 3. **Rebuild and restart:** ```bash cd /opt/mythic sudo ./mythic-cli build cazalla sudo ./mythic-cli restart cazalla ``` ### Verification ```bash # Verify logger is active sudo docker logs cazalla | grep -i "syslog\|Logger initialized" # View logs in real-time sudo tail -f /var/log/cazalla.log ``` ### Log Locations - **Syslog (host)**: `/var/log/cazalla.log` - **Local logs (container)**: `/tmp/cazalla_mythic_YYYY-MM-DD.log` ### Complete Documentation For more details on configuration, troubleshooting, and advanced usage, see: - [Logger Documentation](Payload_Type/cazalla/logger/README.md) - Complete technical documentation - [Agent Wiki - Logging](documentation-payload/Cazalla/logging.md) - User guide --- ## πŸ”§ 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 β”‚ β”œβ”€β”€ rpfwd_manager.c/h # Reverse port forwarding logic β”‚ β”œβ”€β”€ procesos.c/h # Process listing (with Process Browser support) β”‚ β”œβ”€β”€ crypto.c/h # AES-256-CBC encryption with HMAC-SHA256 β”‚ β”œβ”€β”€ 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 β”‚ β”œβ”€β”€ ps.py # Process listing (Process Browser enabled) β”‚ β”œβ”€β”€ socks.py # SOCKS proxy command β”‚ β”œβ”€β”€ rpfwd.py # Reverse port forwarding command β”‚ └── builder.py # Payload builder (with encryption support) β”œβ”€β”€ translator/ # Mythic ↔ Agent translation β”‚ β”œβ”€β”€ translator.py # Main translator (with encryption support) β”‚ β”œβ”€β”€ commands_from_c2.py # Mythic JSON β†’ Binary β”‚ └── commands_from_implant.py # Binary β†’ Mythic JSON (Process Browser parser) └── browser_scripts/ # Mythic UI enhancements β”œβ”€β”€ ls.js # Directory listing formatter └── ps.js # Process list formatter ``` ### Adding New Commands **Important**: When developing new commands, always consider: 1. **Artifact reporting**: Commands that modify system state (create processes, write files, modify registry, create network connections, etc.) should include artifact reporting using the `addArtifact()` helper function. See [Artifacts Support](#artifacts-support) for details. 2. **Credential reporting**: Commands that discover or extract credentials (passwords, hashes, certificates, keys, tickets, cookies) should report them using the `addCredential()` helper function. Commands that read files should analyze content for credentials and report any found. See [Credentials Support](#credentials-support) for details and examples. 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`): **Remember to add artifacts if the command modifies system state!** After adding the response output, use `addArtifact()` to report the action: ```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); // IMPORTANT: Add artifact if this command modifies system state // Examples: // - If creating/modifying files: addArtifact(respuesta, "File Write", file_path); // - If creating processes: addArtifact(respuesta, "Process Create", command); // - If modifying registry: addArtifact(respuesta, "Registry Write", reg_key); // - If creating network connections: addArtifact(respuesta, "Network Connection", connection_info); // IMPORTANT: Add credentials if this command discovers or extracts credentials // Examples: // - Plaintext password: addCredential(respuesta, "plaintext", "DOMAIN", "password123", "username"); // - Hash: addCredential(respuesta, "hash", "", "aad3b435b51404ee...", "Administrator"); // - Domain account (dominio\usuario): addCredential(respuesta, "plaintext", "DOMAIN", "password", "username"); // - Format usuario@dominio: addCredential(respuesta, "plaintext", "domain.com", "password", "username"); // - Certificate: addCredential(respuesta, "certificate", "", "cert_data", "account_name"); // - For file reading commands, analyze content and report found credentials (see cat command example) 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) ### Process Browser Not Showing Processes **Processes not appearing in Process Browser:** - Verify `ps` command executed successfully (check callback output) - Check translator logs: `sudo docker logs cazalla_translator | grep PROCESS_BROWSER` - Ensure `supported_ui_features = ["process_browser:list"]` is set in `ps.py` - Verify processes are being parsed correctly (translator should show "Parseados X procesos") - Rebuild translator if changes were made: `sudo ./mythic-cli build cazalla` **Processes showing as "UNKNOWN - MISSING DATA":** - This usually indicates processes that couldn't be accessed (protected/system processes) - Check if the issue persists after rebuilding the agent - Some processes may legitimately lack certain information (e.g., system processes) ### Encryption Issues **Encryption not working:** - Verify `AESPSK` parameter is configured in build parameters - Check build output for: `βœ“ Encryption ENABLED` - Review translator logs for encryption/decryption errors: `sudo docker logs cazalla_translator | grep CRYPTO` - Ensure encryption key is present in both agent and translator (auto-configured by Mythic) **"HMAC verification failed" errors:** - Usually indicates key mismatch between agent and translator - Rebuild the payload to regenerate the encryption key - Check that both agent and translator are using the same payload UUID --- ## πŸ“š References - [Mythic Documentation](https://docs.mythic-c2.net/) - [Mythic Process Browser](https://docs.mythic-c2.net/customizing/hooking-features/process_list) - [Mythic Customizing Public Agents](https://docs.mythic-c2.net/customizing/customizing-public-agent) - [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**