diff --git a/README.md b/README.md index 784fa90..454eb09 100644 --- a/README.md +++ b/README.md @@ -1,287 +1,302 @@ -# Cazalla - Basic Mythic Implant in C - -Cazalla is a basic Windows implant written in C, designed to interface with the Mythic C2 framework. - -This project was developed based on the article [How to build your own Mythic agent in C](https://red-team-sncf.github.io/how-to-create-your-own-mythic-agent-in-c.html) and serves as an initial version of an implant with room for future improvements. - -Cazalla is developed by the OFSTeam at Kaseya. - -## Supported Commands - -Commands are organized by category for better clarity and extensibility. - -### πŸ“ File System Commands -| Command | Description | Status | -|---------|--------------------------|---------| -| `cd` | Change working directory | βœ… | -| `ls` | List directory contents | βœ… | -| `pwd` | Print working directory | βœ… | -| `cp` | Copy an existing file | βœ… | -| `mkdir` | Create a new directory | βœ… | -| `rm` | Delete file/directory | βœ… | - -### πŸ–₯️ Console Commands -| Command | Description | Status | -|---------|-------------------------------------|--------| -| `shell`| Execute arbitrary shell command | βœ… | - -### πŸ”„ Execution Control -| Command | Description | Status | -|---------|-------------------|--------| -| `exit` | Exit the implant | βœ… | -| `sleep`| Modify sleep time | βœ… | - -### 🧠 System Inspection -| Command | Description | Status | -|---------|-----------------------|--------| -| `ps` | List running processes| βœ… | - -> πŸ”§ To add a new command, see the [Creating New Commands](#creating-new-commands) section below. - ---- - -## Install Cazalla - -Once Mythic is installed and running, use the following command to install Cazalla: - -```sh -./mythic-cli install github -``` - -## Communication Protocol - -### HEADER - Implant to C2 - -| Key | Key Len (bytes) | Type | -|---------|-------------------|------------| -| UUID | 36 | Str (char*)| -| Action | 1 | UInt32 | - -### HEADER - C2 to Implant - -| Key | Key Len (bytes) | Type | -|---------|-------------------|------------| -| Action | 1 | Int32 | - -UUID | BODY - -#### Checkin - Implant to C2 - -Expected: - -```json -{ - "action": "checkin", - "uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15", - "ip": "127.0.0.1", - "os": "win", - "arch": "x64", - "hostname": "PC", - "user": "bob", - "domain": "domain.com", - "pid": 123, - "processname": "malware.exe" -} -``` - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| UUID | 36 | Str (char*) | -| Size IP | 4 | Uint32 | -| IP | Size IP | Str (char*) | -| Size OS | 4 | Uint32 | -| OS | Size OS | Str (char*) | -| Architecture | 1 | Int | -| Size Hostname | 4 | Uint32 | -| HostName | Size Hostname | Str (char*) | -| Size Username | 4 | Uint32 | -| Username | Size Username | Str (char*) | -| Size Domain | 4 | Uint32 | -| Domain | Size Domain | Str (char*) | -| PID | 4 | Uint32 | -| Size Process | 4 | Uint32 | -| Process Name | Size Process Name | Str (char*) | -| Size ExternIP | 4 | Uint32 | -| Extern IP | Size Extern IP | Str (char*) | - -### Checkin - C2 to Implant - -| Key | Key Len (bytes) | Type | -|----------|-------------------|-------------| -| New UUID | 36 | Str (char*) | -| Status | 1 | Byte | - -### GetTasking - Implant to C2 - -Expected: - -```json -{ - "action": "get_tasking", - "tasking_size": 1 -} -``` - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Number tasks | 4 | Uint32 | - -### GetTasking - C2 to Implant - -Expected: - -```json -{ - "action": "get_tasking", - "tasks": [ - { - "command": "command name", - "parameters": "command param string", - "timestamp": 1578706611.324671, - "id": "task uuid" - } - ] -} -``` - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| NumberOfTasks | 4 | Uint32 | -| Size Of Task1 | 4 | Uint32 | -| Task1 CMD | 1 | Int | -| Task1 UUID | 36 | Str (char*) | -| Task1 LenPara1| 4 | Uint32 | -| Task1 Param1 | LenParam1 Task1 | Str(char*) | - -### Post Response Header - Implant to C2 - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Number Resp | 4 | Uint32 | - -### Post Response Header - C2 to Implant - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Number Resp | 4 | Uint32 | - -### Post Response Classic Output Return - Implant to C2 - -Expected: - -```json -{ - "action": "post_response", - "responses": [ - { - "task_id": "uuid of task", - ... response message - } - ] -} -``` - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| UUID Resp 1 | 36 | Str (char*) | -| Size Output R1| 4 | Uint32 | -| Output R1 | Size Output | Bytes | -| Status R1 | 1 | Int | - -### Post Response Classic Output Return - C2 to Implant - -Expected: - -```json -{ - "action": "post_response", - "responses": [ - { - "task_id": UUID, - "status": "success" or "error", - "error": "error message if it exists" - } - ] -} -``` - -| Key | Key Len (bytes) | Type | -|---------------|-------------------|-------------| -| Status Resp1 | 1 | Int | - -## Creating New Commands - -### πŸ“¦ Mythic Side (Python) - -To add a new command in Mythic, create a `.py` file inside the agent's command folder (e.g., `shell.py`). A basic structure includes: - -- TaskArguments class -- CommandBase class - -Example: `shell.py` - -```python -class ShellArguments(TaskArguments): - def __init__(self, command_line, **kwargs): - ... - self.args = [ - CommandParameter(name="command", type=ParameterType.String, ...) - ] - -class ShellCommand(CommandBase): - cmd = "shell" - ... - async def create_tasking(self, task: MythicTask): - ... - - async def process_response(self, task, response): - ... - -``` -### 🧠 C2 Side (Python - `commands_from_c2.py`) - -Update the commands dictionary with a unique hex code and input type: - -```python -commands = { - ... - "newcmd": {"hex_code": 0xAB, "input_type": "string"} -} -``` -Update `responseTasking` to handle serialization of the new command’s parameters. - -### πŸ’» Implant Side (C) - -Update the following files: - -`comandos.h` -```c -#define NEWCMD_CMD 0xAB -BOOL ejecutarNuevoCmd(PAnalizador argumentos); -``` -`comandos.c` -Add your command logic in `handleGetTasking()`: -```c -else if (tarea == NEWCMD_CMD) { - ejecutarNuevoCmd(analizadorTarea); -} -``` -`nuevo_cmd.c` and `nuevo_cmd.h` -Create your new command implementation. -```c -BOOL ejecutarNuevoCmd(PAnalizador argumentos) { - // handle parsing and execution here -} -``` -Don’t forget to add the source file to the build and include its header where needed. - -## Future Development - -Planned improvements: - -- Full implementation of pwd -- Additional file system and process control commands -- File upload/download -- Persistence and evasion mechanisms - -Made with β˜• by the Kaseya OFSTeam \ No newline at end of file +# Cazalla - Basic Mythic Implant in C + +Cazalla is a basic Windows implant written in C, designed to interface with the Mythic C2 framework. + +This project was developed based on the article [How to build your own Mythic agent in C](https://red-team-sncf.github.io/how-to-create-your-own-mythic-agent-in-c.html) and serves as an initial version of an implant with room for future improvements. + +Cazalla is developed by the OFSTeam at Kaseya. + +## Supported Commands + +Commands are organized by category for better clarity and extensibility. + +### πŸ“ File System Commands +| Command | Description | Status | +|---------|--------------------------|---------| +| `cd` | Change working directory | βœ… | +| `ls` | List directory contents | βœ… | +| `pwd` | Print working directory | βœ… | +| `cp` | Copy an existing file | βœ… | +| `mkdir` | Create a new directory | βœ… | +| `rm` | Delete file/directory | βœ… | + +### πŸ–₯️ Console Commands +| Command | Description | Status | +|---------|-------------------------------------|--------| +| `shell`| Execute arbitrary shell command | βœ… | + +### πŸ”„ Execution Control +| Command | Description | Status | +|---------|-------------------|--------| +| `exit` | Exit the implant | βœ… | +| `sleep`| Modify sleep time | βœ… | + +### 🧠 System Inspection +| Command | Description | Status | +|---------|-----------------------|--------| +| `ps` | List running processes| βœ… | + +> πŸ”§ To add a new command, see the [Creating New Commands](#creating-new-commands) section below. + +--- + +## Install Cazalla + +Once Mythic is installed and running, use the following command to install Cazalla: + +```sh +./mythic-cli install github +``` + +## Communication Protocol + +### HEADER - Implant to C2 + +| Key | Key Len (bytes) | Type | +|---------|-------------------|------------| +| UUID | 36 | Str (char*)| +| Action | 1 | UInt32 | + +### HEADER - C2 to Implant + +| Key | Key Len (bytes) | Type | +|---------|-------------------|------------| +| Action | 1 | Int32 | + +UUID | BODY + +#### Checkin - Implant to C2 + +Expected: + +```json +{ + "action": "checkin", + "uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15", + "ip": "127.0.0.1", + "os": "win", + "arch": "x64", + "hostname": "PC", + "user": "bob", + "domain": "domain.com", + "pid": 123, + "processname": "malware.exe" +} +``` + +| Key | Key Len (bytes) | Type | +|---------------|-------------------|-------------| +| UUID | 36 | Str (char*) | +| Size IP | 4 | Uint32 | +| IP | Size IP | Str (char*) | +| Size OS | 4 | Uint32 | +| OS | Size OS | Str (char*) | +| Architecture | 1 | Int | +| Size Hostname | 4 | Uint32 | +| HostName | Size Hostname | Str (char*) | +| Size Username | 4 | Uint32 | +| Username | Size Username | Str (char*) | +| Size Domain | 4 | Uint32 | +| Domain | Size Domain | Str (char*) | +| PID | 4 | Uint32 | +| Size Process | 4 | Uint32 | +| Process Name | Size Process Name | Str (char*) | +| Size ExternIP | 4 | Uint32 | +| Extern IP | Size Extern IP | Str (char*) | + +### Checkin - C2 to Implant + +| Key | Key Len (bytes) | Type | +|----------|-------------------|-------------| +| New UUID | 36 | Str (char*) | +| Status | 1 | Byte | + +### GetTasking - Implant to C2 + +Expected: + +```json +{ + "action": "get_tasking", + "tasking_size": 1 +} +``` + +| Key | Key Len (bytes) | Type | +|---------------|-------------------|-------------| +| Number tasks | 4 | Uint32 | + +### GetTasking - C2 to Implant + +Expected: + +```json +{ + "action": "get_tasking", + "tasks": [ + { + "command": "command name", + "parameters": "command param string", + "timestamp": 1578706611.324671, + "id": "task uuid" + } + ] +} +``` + +| Key | Key Len (bytes) | Type | +|---------------|-------------------|-------------| +| NumberOfTasks | 4 | Uint32 | +| Size Of Task1 | 4 | Uint32 | +| Task1 CMD | 1 | Int | +| Task1 UUID | 36 | Str (char*) | +| Task1 LenPara1| 4 | Uint32 | +| Task1 Param1 | LenParam1 Task1 | Str(char*) | + +### Post Response Header - Implant to C2 + +| Key | Key Len (bytes) | Type | +|---------------|-------------------|-------------| +| Number Resp | 4 | Uint32 | + +### Post Response Header - C2 to Implant + +| Key | Key Len (bytes) | Type | +|---------------|-------------------|-------------| +| Number Resp | 4 | Uint32 | + +### Post Response Classic Output Return - Implant to C2 + +Expected: + +```json +{ + "action": "post_response", + "responses": [ + { + "task_id": "uuid of task", + ... response message + } + ] +} +``` + +| Key | Key Len (bytes) | Type | +|---------------|-------------------|-------------| +| UUID Resp 1 | 36 | Str (char*) | +| Size Output R1| 4 | Uint32 | +| Output R1 | Size Output | Bytes | +| Status R1 | 1 | Int | + +### Post Response Classic Output Return - C2 to Implant + +Expected: + +```json +{ + "action": "post_response", + "responses": [ + { + "task_id": UUID, + "status": "success" or "error", + "error": "error message if it exists" + } + ] +} +``` + +| Key | Key Len (bytes) | Type | +|---------------|-------------------|-------------| +| Status Resp1 | 1 | Int | + +## Creating New Commands + +### πŸ“¦ Mythic Side (Python) + +To add a new command in Mythic, create a `.py` file inside the agent's command folder (e.g., `shell.py`). A basic structure includes: + +- TaskArguments class +- CommandBase class + +Example: `shell.py` + +```python +class ShellArguments(TaskArguments): + def __init__(self, command_line, **kwargs): + ... + self.args = [ + CommandParameter(name="command", type=ParameterType.String, ...) + ] + +class ShellCommand(CommandBase): + cmd = "shell" + ... + async def create_tasking(self, task: MythicTask): + ... + + async def process_response(self, task, response): + ... + +``` +### 🧠 C2 Side (Python - `commands_from_c2.py`) + +Update the commands dictionary with a unique hex code and input type: + +```python +commands = { + ... + "newcmd": {"hex_code": 0xAB, "input_type": "string"} +} +``` +Update `responseTasking` to handle serialization of the new command’s parameters. + +### πŸ’» Implant Side (C) + +Update the following files: + +`comandos.h` +```c +#define NEWCMD_CMD 0xAB +BOOL ejecutarNuevoCmd(PAnalizador argumentos); +``` +`comandos.c` +Add your command logic in `handleGetTasking()`: +```c +else if (tarea == NEWCMD_CMD) { + ejecutarNuevoCmd(analizadorTarea); +} +``` +`nuevo_cmd.c` and `nuevo_cmd.h` +Create your new command implementation. +```c +BOOL ejecutarNuevoCmd(PAnalizador argumentos) { + // handle parsing and execution here +} +``` +Don’t forget to add the source file to the build and include its header where needed. + +## Future Development + +### Planned improvements: + +#### Improvements to perform ASAP: + +- Proxy + +https://github.com/jeeschr/basic-proxy-server/blob/master/proxy.c + +- BOFexecute +- rportfwd + +https://github.com/fidian/tcp-port-forward/blob/master/portforward.c +https://www.reddit.com/r/C_Programming/s/bWOTxm6phn + + +#### Improvements tier 2: + +- Persistence and evasion mechanisms +- Full implementation of pwd +- Additional file system and process control commands +- File upload/download + +Made with β˜• and monster by the Kaseya OFSTeam \ No newline at end of file