From df8e824f5f0841d76dc7857503c998d960dd4ef2 Mon Sep 17 00:00:00 2001 From: "marcos.luna" Date: Wed, 29 Oct 2025 13:42:28 +0100 Subject: [PATCH] Artifacts created --- .../agent_code/cazalla/SistemadeFicheros.c | 9 + .../cazalla/agent_code/cazalla/consola.c | 4 + .../cazalla/agent_code/cazalla/paquete.c | 21 ++ .../cazalla/agent_code/cazalla/paquete.h | 4 + .../cazalla/cazalla/agent_functions/shell.py | 23 ++ .../translator/commands_from_implant.py | 90 ++++++ README.md | 277 +++++++++++++++++- 7 files changed, 424 insertions(+), 4 deletions(-) diff --git a/Payload_Type/cazalla/cazalla/agent_code/cazalla/SistemadeFicheros.c b/Payload_Type/cazalla/cazalla/agent_code/cazalla/SistemadeFicheros.c index 14c836d..b11bdc7 100644 --- a/Payload_Type/cazalla/cazalla/agent_code/cazalla/SistemadeFicheros.c +++ b/Payload_Type/cazalla/cazalla/agent_code/cazalla/SistemadeFicheros.c @@ -261,6 +261,9 @@ VOID CopiarFichero(PAnalizador argumentos) { addString(respuestaTarea, tareaUuid, FALSE); addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE); + + // Add File Write artifact for the destination file + addArtifact(respuestaTarea, "File Write", nuevoFichero); mandarPaquete(respuestaTarea); liberarPaquete(salida); @@ -318,6 +321,9 @@ VOID CrearRuta(PAnalizador argumentos){ addString(respuestaTarea, tareaUuid, FALSE); addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE); + + // Add File Write artifact for the created directory + addArtifact(respuestaTarea, "File Write", directorio); mandarPaquete(respuestaTarea); liberarPaquete(salida); @@ -425,6 +431,9 @@ VOID EliminarRuta(PAnalizador argumentos){ addString(respuestaTarea, tareaUuid, FALSE); addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE); + + // Add File Write artifact for the deleted file/directory + addArtifact(respuestaTarea, "File Write", ruta); mandarPaquete(respuestaTarea); liberarPaquete(salida); diff --git a/Payload_Type/cazalla/cazalla/agent_code/cazalla/consola.c b/Payload_Type/cazalla/cazalla/agent_code/cazalla/consola.c index b48c8d4..a326882 100644 --- a/Payload_Type/cazalla/cazalla/agent_code/cazalla/consola.c +++ b/Payload_Type/cazalla/cazalla/agent_code/cazalla/consola.c @@ -29,7 +29,11 @@ BOOL ejecutarConsola(PAnalizador argumentos) { addString(salida, ruta, FALSE); } + // Add output to response addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE); + + // Add Process Create artifact using the helper function + addArtifact(respuestaTarea, "Process Create", comando); _pclose(fp); Analizador* respuestaAnalizador = mandarPaquete(respuestaTarea); diff --git a/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.c b/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.c index fa58251..ebf545c 100644 --- a/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.c +++ b/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.c @@ -639,4 +639,25 @@ VOID paqueteCompletado(PCHAR taskUuid, PPaquete datosOpcionales) { // Cleanup liberarPaquete(respuesta); if (resp) liberarAnalizador(resp); +} + +// Helper function to add artifacts to response packages +// Format: [0xFF marker][artifact_type_len:4][artifact_type][artifact_value_len:4][artifact_value] +VOID addArtifact(PPaquete paquete, PCHAR artifact_type, PCHAR artifact_value) { + if (!paquete || !artifact_type || !artifact_value) { + return; + } + + // Artifact marker + addByte(paquete, 0xFF); + + // Artifact type length and value + SIZE_T type_len = strlen(artifact_type); + addInt32(paquete, (UINT32)type_len); + addString(paquete, artifact_type, FALSE); + + // Artifact value length and value + SIZE_T value_len = strlen(artifact_value); + addInt32(paquete, (UINT32)value_len); + addString(paquete, artifact_value, FALSE); } \ No newline at end of file diff --git a/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.h b/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.h index 47c5fc3..76aba6a 100644 --- a/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.h +++ b/Payload_Type/cazalla/cazalla/agent_code/cazalla/paquete.h @@ -31,4 +31,8 @@ BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia); /* Formatted append helper */ BOOL PackageAddFormatPrintf(PPaquete package, BOOL copySize, char* fmt, ...); +/* Artifact helper: adds artifact marker and data to response package */ +/* Format: [0xFF marker][artifact_type_len:4][artifact_type][artifact_value_len:4][artifact_value] */ +VOID addArtifact(PPaquete paquete, PCHAR artifact_type, PCHAR artifact_value); + #endif \ No newline at end of file diff --git a/Payload_Type/cazalla/cazalla/agent_functions/shell.py b/Payload_Type/cazalla/cazalla/agent_functions/shell.py index 9123cd5..4009c92 100644 --- a/Payload_Type/cazalla/cazalla/agent_functions/shell.py +++ b/Payload_Type/cazalla/cazalla/agent_functions/shell.py @@ -1,5 +1,6 @@ from mythic_container.MythicCommandBase import * from mythic_container.MythicRPC import * +import json class ShellArguments(TaskArguments): @@ -40,5 +41,27 @@ class ShellCommand(CommandBase): return task async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: + """ + Process response from agent and add artifacts for Process Create. + + According to Mythic documentation: + https://docs.mythic-c2.net/customizing/hooking-features/artifacts + + Artifacts should be added to the response JSON with an 'artifacts' array. + However, the current Mythic API doesn't allow commands to directly modify + the translator's JSON response. Instead, we could: + + 1. Use MythicRPC to create artifacts after the response (current limitation) + 2. Modify the agent to send command context in responses + 3. Have the translator detect shell commands automatically + + For now, artifacts are prepared in the translator but need command context. + """ resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) + + # TODO: Add artifacts via MythicRPC or modify translator to detect shell commands + # command = task.args.get_arg("command") + # if command: + # # Could use MythicRPC CreateArtifact here if available + return resp \ No newline at end of file diff --git a/Payload_Type/cazalla/translator/commands_from_implant.py b/Payload_Type/cazalla/translator/commands_from_implant.py index 2a836df..a40a491 100644 --- a/Payload_Type/cazalla/translator/commands_from_implant.py +++ b/Payload_Type/cazalla/translator/commands_from_implant.py @@ -1,6 +1,7 @@ from translator.utils import * import ipaddress import json +import re def checkIn(data): @@ -86,6 +87,27 @@ def getTasking(data): return dataJson +def create_artifact(base_artifact, artifact_value, needs_cleanup=False, resolved=False): + """ + Helper function to create an artifact entry according to Mythic documentation. + + Args: + base_artifact: Type of artifact (e.g., "Process Create", "File Write") + artifact_value: The actual artifact (e.g., "cmd.exe /c whoami", "/path/to/file") + needs_cleanup: Whether this artifact needs cleanup later + resolved: Whether this artifact has been cleaned up + + Returns: + Dictionary representing an artifact entry + """ + return { + "base_artifact": base_artifact, + "artifact": artifact_value, + "needs_cleanup": needs_cleanup, + "resolved": resolved + } + + def parse_process_list(output_text): """ Parsea el texto tab-separated de procesos al formato JSON del Process Browser. @@ -155,6 +177,57 @@ def postResponse(data): output, data = getBytesWithSize(data) print(f"Tamaño después de extraer UUID: {len(data)} bytes") + + # Parse artifacts: format [0xFF][type_len:4][type][value_len:4][value] + artifacts_data = [] + remaining_data = data + + while len(remaining_data) >= 5: # At least: marker (1) + type_len (4) + if remaining_data[0] == 0xFF: + # Artifact marker found + offset = 1 + + # Extract artifact type + if len(remaining_data) < offset + 4: + break + type_len = int.from_bytes(remaining_data[offset:offset+4], 'big') + offset += 4 + + if type_len == 0 or len(remaining_data) < offset + type_len: + break + + try: + artifact_type = remaining_data[offset:offset+type_len].decode('cp850') + offset += type_len + except: + break + + # Extract artifact value + if len(remaining_data) < offset + 4: + break + value_len = int.from_bytes(remaining_data[offset:offset+4], 'big') + offset += 4 + + if value_len == 0 or len(remaining_data) < offset + value_len: + break + + try: + artifact_value = remaining_data[offset:offset+value_len].decode('cp850') + offset += value_len + + artifacts_data.append({ + "type": artifact_type, + "value": artifact_value + }) + print(f"[ARTIFACTS] Detectado artifact: {artifact_type} = {artifact_value[:50]}") + + # Continue parsing for multiple artifacts + remaining_data = remaining_data[offset:] + except: + break + else: + # No more artifacts + break try: decoded_output = output.decode('cp850') @@ -207,6 +280,23 @@ def postResponse(data): if is_process_list and len(processes) > 0: jsonTask["processes"] = processes print(f"[PROCESS_BROWSER] Respuesta convertida al formato Process Browser con {len(processes)} procesos") + + # Support for artifacts: create artifacts from parsed data + artifacts = [] + + # Process all detected artifacts + for artifact_info in artifacts_data: + artifacts.append(create_artifact( + artifact_info["type"], + artifact_info["value"], + needs_cleanup=False, # Can be made configurable per artifact type + resolved=False + )) + + # Add artifacts array if we have any + if len(artifacts) > 0: + jsonTask["artifacts"] = artifacts + print(f"[ARTIFACTS] Total de artifacts agregados: {len(artifacts)}") resTaks.append(jsonTask) diff --git a/README.md b/README.md index 164cc9b..f84bd8b 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ - [SOCKS Proxy Support](#socks-proxy-support) - [Communication Protocol](#communication-protocol) - [Configuration](#configuration) +- [Process Browser Integration](#process-browser-integration) +- [Artifacts Support](#artifacts-support) - [Development](#development) - [Troubleshooting](#troubleshooting) - [Credits](#credits) @@ -42,6 +44,8 @@ This project was inspired by the article [How to build your own Mythic agent in - **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 @@ -188,7 +192,9 @@ For more information, see the [Mythic documentation on customizing public agents | Command | Description | Example | |---------|-------------|---------| -| `ps` | List running processes | `ps` | +| `ps` | List running processes with Process Browser support | `ps` | + +**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. ### Network Operations @@ -361,6 +367,16 @@ Example command IDs: 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 @@ -374,6 +390,10 @@ When building from Mythic UI: - **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 @@ -385,6 +405,44 @@ Edit `Config.h` before building: #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: @@ -401,6 +459,174 @@ This enables: --- +## 📊 Process Browser Integration + +Cazalla's `ps` command fully integrates with Mythic's Process Browser feature, providing unified process management across multiple callbacks on the same host. + +### 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 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 additional actions (inject, kill, etc.) if implemented + +### Implementation Details + +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 +- 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 + +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.) + +### 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 + - `rm` (delete) - reports deleted file/directory path + +**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 + +Future support can be added for: +- **File Read**: When files are downloaded/read (e.g., `download` command) +- **File Write**: For file upload operations (e.g., `upload` command) +- **Network Connection**: When network operations occur (e.g., for `socks` proxy connections) +- **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 +- `rm`: File Write artifact with deleted path + +### Best Practices for New Commands + +**When developing new commands, always consider artifact reporting:** + +✅ **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`, custom network commands) +- Any command that modifies system configuration + +❌ **Commands that DON'T need artifacts:** +- Read-only operations (`ls`, `cd`, `pwd`, `cat`, `read`) +- 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. + +For more information, see the [Mythic Artifacts documentation](https://docs.mythic-c2.net/customizing/hooking-features/artifacts). + +--- + ## 🔧 Development ### Project Structure @@ -414,17 +640,20 @@ Cazalla/ │ ├── paquete.c/h # Packet creation │ ├── transporte.c/h # HTTP transport (WinHTTP) │ ├── socks_manager.c/h # SOCKS proxy 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 -│ └── builder.py # Payload builder +│ └── builder.py # Payload builder (with encryption support) ├── translator/ # Mythic ↔ Agent translation -│ ├── translator.py # Main translator +│ ├── translator.py # Main translator (with encryption support) │ ├── commands_from_c2.py # Mythic JSON → Binary -│ └── commands_from_implant.py # Binary → Mythic JSON +│ └── 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 @@ -432,6 +661,8 @@ Cazalla/ ### Adding New Commands +**Important**: When developing new commands, always consider whether the command should report artifacts. 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. + 1. **Define command in Python** (`agent_functions/my_command.py`): ```python @@ -476,6 +707,8 @@ elif task_command == "my_command": 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; @@ -491,6 +724,13 @@ BOOL myCommandHandler(PAnalizador argumentos) { 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); + Analizador* resp = mandarPaquete(respuesta); liberarPaquete(respuesta); if (resp) liberarAnalizador(resp); @@ -559,11 +799,40 @@ apt-get update && apt-get install -y mingw-w64 - 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)