Update README.md
This commit is contained in:
@@ -1,287 +1,302 @@
|
|||||||
# Cazalla - Basic Mythic Implant in C
|
# Cazalla - Basic Mythic Implant in C
|
||||||
|
|
||||||
Cazalla is a basic Windows implant written in C, designed to interface with the Mythic C2 framework.
|
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.
|
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.
|
Cazalla is developed by the OFSTeam at Kaseya.
|
||||||
|
|
||||||
## Supported Commands
|
## Supported Commands
|
||||||
|
|
||||||
Commands are organized by category for better clarity and extensibility.
|
Commands are organized by category for better clarity and extensibility.
|
||||||
|
|
||||||
### 📁 File System Commands
|
### 📁 File System Commands
|
||||||
| Command | Description | Status |
|
| Command | Description | Status |
|
||||||
|---------|--------------------------|---------|
|
|---------|--------------------------|---------|
|
||||||
| `cd` | Change working directory | ✅ |
|
| `cd` | Change working directory | ✅ |
|
||||||
| `ls` | List directory contents | ✅ |
|
| `ls` | List directory contents | ✅ |
|
||||||
| `pwd` | Print working directory | ✅ |
|
| `pwd` | Print working directory | ✅ |
|
||||||
| `cp` | Copy an existing file | ✅ |
|
| `cp` | Copy an existing file | ✅ |
|
||||||
| `mkdir` | Create a new directory | ✅ |
|
| `mkdir` | Create a new directory | ✅ |
|
||||||
| `rm` | Delete file/directory | ✅ |
|
| `rm` | Delete file/directory | ✅ |
|
||||||
|
|
||||||
### 🖥️ Console Commands
|
### 🖥️ Console Commands
|
||||||
| Command | Description | Status |
|
| Command | Description | Status |
|
||||||
|---------|-------------------------------------|--------|
|
|---------|-------------------------------------|--------|
|
||||||
| `shell`| Execute arbitrary shell command | ✅ |
|
| `shell`| Execute arbitrary shell command | ✅ |
|
||||||
|
|
||||||
### 🔄 Execution Control
|
### 🔄 Execution Control
|
||||||
| Command | Description | Status |
|
| Command | Description | Status |
|
||||||
|---------|-------------------|--------|
|
|---------|-------------------|--------|
|
||||||
| `exit` | Exit the implant | ✅ |
|
| `exit` | Exit the implant | ✅ |
|
||||||
| `sleep`| Modify sleep time | ✅ |
|
| `sleep`| Modify sleep time | ✅ |
|
||||||
|
|
||||||
### 🧠 System Inspection
|
### 🧠 System Inspection
|
||||||
| Command | Description | Status |
|
| Command | Description | Status |
|
||||||
|---------|-----------------------|--------|
|
|---------|-----------------------|--------|
|
||||||
| `ps` | List running processes| ✅ |
|
| `ps` | List running processes| ✅ |
|
||||||
|
|
||||||
> 🔧 To add a new command, see the [Creating New Commands](#creating-new-commands) section below.
|
> 🔧 To add a new command, see the [Creating New Commands](#creating-new-commands) section below.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Install Cazalla
|
## Install Cazalla
|
||||||
|
|
||||||
Once Mythic is installed and running, use the following command to install Cazalla:
|
Once Mythic is installed and running, use the following command to install Cazalla:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./mythic-cli install github <repository-url>
|
./mythic-cli install github <repository-url>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Communication Protocol
|
## Communication Protocol
|
||||||
|
|
||||||
### HEADER - Implant to C2
|
### HEADER - Implant to C2
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------|-------------------|------------|
|
|---------|-------------------|------------|
|
||||||
| UUID | 36 | Str (char*)|
|
| UUID | 36 | Str (char*)|
|
||||||
| Action | 1 | UInt32 |
|
| Action | 1 | UInt32 |
|
||||||
|
|
||||||
### HEADER - C2 to Implant
|
### HEADER - C2 to Implant
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------|-------------------|------------|
|
|---------|-------------------|------------|
|
||||||
| Action | 1 | Int32 |
|
| Action | 1 | Int32 |
|
||||||
|
|
||||||
UUID | BODY
|
UUID | BODY
|
||||||
|
|
||||||
#### Checkin - Implant to C2
|
#### Checkin - Implant to C2
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "checkin",
|
"action": "checkin",
|
||||||
"uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15",
|
"uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15",
|
||||||
"ip": "127.0.0.1",
|
"ip": "127.0.0.1",
|
||||||
"os": "win",
|
"os": "win",
|
||||||
"arch": "x64",
|
"arch": "x64",
|
||||||
"hostname": "PC",
|
"hostname": "PC",
|
||||||
"user": "bob",
|
"user": "bob",
|
||||||
"domain": "domain.com",
|
"domain": "domain.com",
|
||||||
"pid": 123,
|
"pid": 123,
|
||||||
"processname": "malware.exe"
|
"processname": "malware.exe"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| UUID | 36 | Str (char*) |
|
| UUID | 36 | Str (char*) |
|
||||||
| Size IP | 4 | Uint32 |
|
| Size IP | 4 | Uint32 |
|
||||||
| IP | Size IP | Str (char*) |
|
| IP | Size IP | Str (char*) |
|
||||||
| Size OS | 4 | Uint32 |
|
| Size OS | 4 | Uint32 |
|
||||||
| OS | Size OS | Str (char*) |
|
| OS | Size OS | Str (char*) |
|
||||||
| Architecture | 1 | Int |
|
| Architecture | 1 | Int |
|
||||||
| Size Hostname | 4 | Uint32 |
|
| Size Hostname | 4 | Uint32 |
|
||||||
| HostName | Size Hostname | Str (char*) |
|
| HostName | Size Hostname | Str (char*) |
|
||||||
| Size Username | 4 | Uint32 |
|
| Size Username | 4 | Uint32 |
|
||||||
| Username | Size Username | Str (char*) |
|
| Username | Size Username | Str (char*) |
|
||||||
| Size Domain | 4 | Uint32 |
|
| Size Domain | 4 | Uint32 |
|
||||||
| Domain | Size Domain | Str (char*) |
|
| Domain | Size Domain | Str (char*) |
|
||||||
| PID | 4 | Uint32 |
|
| PID | 4 | Uint32 |
|
||||||
| Size Process | 4 | Uint32 |
|
| Size Process | 4 | Uint32 |
|
||||||
| Process Name | Size Process Name | Str (char*) |
|
| Process Name | Size Process Name | Str (char*) |
|
||||||
| Size ExternIP | 4 | Uint32 |
|
| Size ExternIP | 4 | Uint32 |
|
||||||
| Extern IP | Size Extern IP | Str (char*) |
|
| Extern IP | Size Extern IP | Str (char*) |
|
||||||
|
|
||||||
### Checkin - C2 to Implant
|
### Checkin - C2 to Implant
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|----------|-------------------|-------------|
|
|----------|-------------------|-------------|
|
||||||
| New UUID | 36 | Str (char*) |
|
| New UUID | 36 | Str (char*) |
|
||||||
| Status | 1 | Byte |
|
| Status | 1 | Byte |
|
||||||
|
|
||||||
### GetTasking - Implant to C2
|
### GetTasking - Implant to C2
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "get_tasking",
|
"action": "get_tasking",
|
||||||
"tasking_size": 1
|
"tasking_size": 1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Number tasks | 4 | Uint32 |
|
| Number tasks | 4 | Uint32 |
|
||||||
|
|
||||||
### GetTasking - C2 to Implant
|
### GetTasking - C2 to Implant
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "get_tasking",
|
"action": "get_tasking",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"command": "command name",
|
"command": "command name",
|
||||||
"parameters": "command param string",
|
"parameters": "command param string",
|
||||||
"timestamp": 1578706611.324671,
|
"timestamp": 1578706611.324671,
|
||||||
"id": "task uuid"
|
"id": "task uuid"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| NumberOfTasks | 4 | Uint32 |
|
| NumberOfTasks | 4 | Uint32 |
|
||||||
| Size Of Task1 | 4 | Uint32 |
|
| Size Of Task1 | 4 | Uint32 |
|
||||||
| Task1 CMD | 1 | Int |
|
| Task1 CMD | 1 | Int |
|
||||||
| Task1 UUID | 36 | Str (char*) |
|
| Task1 UUID | 36 | Str (char*) |
|
||||||
| Task1 LenPara1| 4 | Uint32 |
|
| Task1 LenPara1| 4 | Uint32 |
|
||||||
| Task1 Param1 | LenParam1 Task1 | Str(char*) |
|
| Task1 Param1 | LenParam1 Task1 | Str(char*) |
|
||||||
|
|
||||||
### Post Response Header - Implant to C2
|
### Post Response Header - Implant to C2
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Number Resp | 4 | Uint32 |
|
| Number Resp | 4 | Uint32 |
|
||||||
|
|
||||||
### Post Response Header - C2 to Implant
|
### Post Response Header - C2 to Implant
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Number Resp | 4 | Uint32 |
|
| Number Resp | 4 | Uint32 |
|
||||||
|
|
||||||
### Post Response Classic Output Return - Implant to C2
|
### Post Response Classic Output Return - Implant to C2
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "post_response",
|
"action": "post_response",
|
||||||
"responses": [
|
"responses": [
|
||||||
{
|
{
|
||||||
"task_id": "uuid of task",
|
"task_id": "uuid of task",
|
||||||
... response message
|
... response message
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| UUID Resp 1 | 36 | Str (char*) |
|
| UUID Resp 1 | 36 | Str (char*) |
|
||||||
| Size Output R1| 4 | Uint32 |
|
| Size Output R1| 4 | Uint32 |
|
||||||
| Output R1 | Size Output | Bytes |
|
| Output R1 | Size Output | Bytes |
|
||||||
| Status R1 | 1 | Int |
|
| Status R1 | 1 | Int |
|
||||||
|
|
||||||
### Post Response Classic Output Return - C2 to Implant
|
### Post Response Classic Output Return - C2 to Implant
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "post_response",
|
"action": "post_response",
|
||||||
"responses": [
|
"responses": [
|
||||||
{
|
{
|
||||||
"task_id": UUID,
|
"task_id": UUID,
|
||||||
"status": "success" or "error",
|
"status": "success" or "error",
|
||||||
"error": "error message if it exists"
|
"error": "error message if it exists"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Status Resp1 | 1 | Int |
|
| Status Resp1 | 1 | Int |
|
||||||
|
|
||||||
## Creating New Commands
|
## Creating New Commands
|
||||||
|
|
||||||
### 📦 Mythic Side (Python)
|
### 📦 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:
|
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
|
- TaskArguments class
|
||||||
- CommandBase class
|
- CommandBase class
|
||||||
|
|
||||||
Example: `shell.py`
|
Example: `shell.py`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class ShellArguments(TaskArguments):
|
class ShellArguments(TaskArguments):
|
||||||
def __init__(self, command_line, **kwargs):
|
def __init__(self, command_line, **kwargs):
|
||||||
...
|
...
|
||||||
self.args = [
|
self.args = [
|
||||||
CommandParameter(name="command", type=ParameterType.String, ...)
|
CommandParameter(name="command", type=ParameterType.String, ...)
|
||||||
]
|
]
|
||||||
|
|
||||||
class ShellCommand(CommandBase):
|
class ShellCommand(CommandBase):
|
||||||
cmd = "shell"
|
cmd = "shell"
|
||||||
...
|
...
|
||||||
async def create_tasking(self, task: MythicTask):
|
async def create_tasking(self, task: MythicTask):
|
||||||
...
|
...
|
||||||
|
|
||||||
async def process_response(self, task, response):
|
async def process_response(self, task, response):
|
||||||
...
|
...
|
||||||
|
|
||||||
```
|
```
|
||||||
### 🧠 C2 Side (Python - `commands_from_c2.py`)
|
### 🧠 C2 Side (Python - `commands_from_c2.py`)
|
||||||
|
|
||||||
Update the commands dictionary with a unique hex code and input type:
|
Update the commands dictionary with a unique hex code and input type:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
commands = {
|
commands = {
|
||||||
...
|
...
|
||||||
"newcmd": {"hex_code": 0xAB, "input_type": "string"}
|
"newcmd": {"hex_code": 0xAB, "input_type": "string"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Update `responseTasking` to handle serialization of the new command’s parameters.
|
Update `responseTasking` to handle serialization of the new command’s parameters.
|
||||||
|
|
||||||
### 💻 Implant Side (C)
|
### 💻 Implant Side (C)
|
||||||
|
|
||||||
Update the following files:
|
Update the following files:
|
||||||
|
|
||||||
`comandos.h`
|
`comandos.h`
|
||||||
```c
|
```c
|
||||||
#define NEWCMD_CMD 0xAB
|
#define NEWCMD_CMD 0xAB
|
||||||
BOOL ejecutarNuevoCmd(PAnalizador argumentos);
|
BOOL ejecutarNuevoCmd(PAnalizador argumentos);
|
||||||
```
|
```
|
||||||
`comandos.c`
|
`comandos.c`
|
||||||
Add your command logic in `handleGetTasking()`:
|
Add your command logic in `handleGetTasking()`:
|
||||||
```c
|
```c
|
||||||
else if (tarea == NEWCMD_CMD) {
|
else if (tarea == NEWCMD_CMD) {
|
||||||
ejecutarNuevoCmd(analizadorTarea);
|
ejecutarNuevoCmd(analizadorTarea);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
`nuevo_cmd.c` and `nuevo_cmd.h`
|
`nuevo_cmd.c` and `nuevo_cmd.h`
|
||||||
Create your new command implementation.
|
Create your new command implementation.
|
||||||
```c
|
```c
|
||||||
BOOL ejecutarNuevoCmd(PAnalizador argumentos) {
|
BOOL ejecutarNuevoCmd(PAnalizador argumentos) {
|
||||||
// handle parsing and execution here
|
// handle parsing and execution here
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Don’t forget to add the source file to the build and include its header where needed.
|
Don’t forget to add the source file to the build and include its header where needed.
|
||||||
|
|
||||||
## Future Development
|
## Future Development
|
||||||
|
|
||||||
Planned improvements:
|
### Planned improvements:
|
||||||
|
|
||||||
- Full implementation of pwd
|
#### Improvements to perform ASAP:
|
||||||
- Additional file system and process control commands
|
|
||||||
- File upload/download
|
- Proxy
|
||||||
- Persistence and evasion mechanisms
|
|
||||||
|
https://github.com/jeeschr/basic-proxy-server/blob/master/proxy.c
|
||||||
Made with ☕ by the Kaseya OFSTeam
|
|
||||||
|
- 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
|
||||||
Reference in New Issue
Block a user