Bof and assemblies completed

This commit is contained in:
marcos.luna
2025-12-16 14:22:51 +01:00
parent e45375cbd5
commit 9351102878
18 changed files with 372 additions and 544 deletions
@@ -45,7 +45,6 @@ Complete documentation for all Cazalla agent commands, organized by category.
- [`inline_execute`](inline_execute.md) - Execute Beacon Object Files (BOFs)
- [`inline_execute_assembly`](inline_execute_assembly.md) - Execute .NET assemblies in-process
- [`execute_assembly`](execute_assembly.md) - Execute .NET assemblies in remote processes
## Control Commands
@@ -1,109 +0,0 @@
# execute_assembly - Execute .NET Assembly in Remote Process
Execute a .NET Assembly in a remote process and retrieve its output.
## Description
The `execute_assembly` command converts a .NET assembly to shellcode using Donut and injects it into a remote process (or the current process if no target is specified). The assembly is executed in the target process and its output is captured and returned.
## Syntax
```
execute_assembly -Assembly <assembly_file> -Arguments <args>
```
## Parameters
- `-Assembly` or `assembly_name` (required): Name of an already uploaded .NET assembly (e.g., `SharpUp.exe`)
- `assembly_file` (required for new uploads): A new .NET assembly file to upload and execute
- `-Arguments` or `assembly_arguments` (required): Arguments to pass to the assembly
## Examples
```
# Execute assembly with arguments
execute_assembly -Assembly SharpUp.exe -Arguments "audit"
# Execute Seatbelt with all checks
execute_assembly -Assembly Seatbelt.exe -Arguments "all"
# Execute SharpHound for domain enumeration
execute_assembly -Assembly SharpHound.exe -Arguments "-c All -d domain.local"
```
## Features
- **Shellcode Conversion**: Automatically converts .NET assemblies to shellcode using Donut
- **Process Injection**: Injects shellcode into a target process (defaults to current process)
- **Output Capture**: Captures and returns assembly output
- **No File System**: Assembly is executed entirely in memory without writing to disk
## How It Works
1. The command retrieves the .NET assembly from Mythic
2. The assembly is converted to shellcode using Donut
3. A subtask is created to call `inject_shellcode` with the generated shellcode
4. The shellcode is injected into the target process
5. The .NET assembly is loaded and executed in the target process
6. Output is captured and returned to Mythic
## Output
```
[execute_assembly] Converting .NET Assembly to Shellcode...
[execute_assembly] Shellcode generated: 123456 bytes
[execute_assembly] Injecting shellcode into process...
[Assembly Output]
SharpUp execution started...
[*] Checking for insecure file permissions...
[+] Found: C:\Program Files\Vulnerable Service\service.exe
```
## OPSEC Considerations
- **HIGH OPSEC RISK**: Process injection is heavily monitored by EDR/XDR solutions
- **Shellcode Injection**: Donut shellcode injection may trigger behavioral detections
- **Process Create Artifact**: Creates a "Process Create" artifact
- **Memory Scanning**: Injected shellcode may be scanned by EDR memory protection
- **API Monitoring**: Process injection APIs (VirtualAllocEx, WriteProcessMemory, CreateRemoteThread) are monitored
- **Donut Detection**: Donut shellcode patterns may be detected by advanced security solutions
## Technical Details
### Donut Integration
The command uses Donut to convert .NET assemblies to position-independent shellcode:
- Automatically handles .NET assembly loading
- Supports .NET Framework and .NET Core assemblies
- Generates position-independent shellcode
- Handles assembly dependencies
### Process Injection
The shellcode injection process:
1. Shellcode is generated from the .NET assembly
2. Shellcode is registered as a temporary file in Mythic
3. `inject_shellcode` command is called via subtask
4. Shellcode is injected into the target process
5. Assembly executes and output is captured
## Error Handling
The command handles various error scenarios:
- **Assembly Not Found**: Returns error if assembly file cannot be retrieved
- **Donut Conversion Failure**: Returns error if assembly cannot be converted to shellcode
- **Injection Failure**: Returns error if shellcode cannot be injected
- **Execution Failure**: Returns error if assembly fails to execute
## Related
- [`inline_execute_assembly`](inline_execute_assembly.md) - Execute .NET assemblies in-process (better OPSEC)
- [`inline_execute`](inline_execute.md) - Execute BOFs directly
- [Artifacts Support](../features.md#artifacts-support)
---
**Command Category:** Execution & Control
**Requires Admin:** No (unless injecting into protected process)
**MITRE ATT&CK:** [T1055 - Process Injection](https://attack.mitre.org/techniques/T1055/), [T1620 - Reflective Code Loading](https://attack.mitre.org/techniques/T1620/)
@@ -53,23 +53,26 @@ inline_execute -BOF custom_bof.x64.o -Arguments int32:5678
## Output
The command returns the output captured from the BOF via `BeaconPrintf` or `BeaconOutput`:
```
[inline_execute] BOF execution requested
[inline_execute] File ID: abc123...
[inline_execute] Arguments: int32:1234
[BOF Output]
Module Name: ntdll.dll
Base Address: 0x7ffa12340000
Size: 0x1f0000
```
If the BOF produces no output, the command will indicate successful execution.
## OPSEC Considerations
- **Process Create Artifact**: BOF execution creates a "Process Create" artifact that is logged
- **Memory Allocation**: BOFs allocate executable memory which may be detected by EDR solutions
- **API Hooking**: Some EDR solutions monitor API calls that BOFs make
- **Symbol Resolution**: External symbol resolution (LoadLibraryA, GetProcAddress) may be logged
- **No New Process**: Unlike `shell` or `execute_assembly`, BOFs execute in-process, reducing some detection vectors
- **MEDIUM OPSEC RISK**: In-process execution reduces some detection vectors compared to process spawning
- **Process Create Artifact**: BOF execution creates a "Process Create" artifact that is logged in Mythic
- **Memory Allocation**: BOFs allocate executable memory (PAGE_EXECUTE_READWRITE) which may be detected by EDR solutions
- **API Monitoring**: External symbol resolution (LoadLibraryA, GetProcAddress) may be logged by EDR/XDR
- **Memory Scanning**: Allocated executable memory may be scanned by EDR memory protection features
- **No New Process**: Unlike `shell`, BOFs execute in-process, reducing some detection vectors
- **Thread Isolation**: BOFs execute in a separate thread with a 30-second timeout to prevent agent crashes
## Technical Details
@@ -82,16 +85,32 @@ The COFF loader implementation:
- Resolves external symbols via LoadLibraryA/GetProcAddress
- Maps sections with PAGE_EXECUTE_READWRITE permissions
### Thread Isolation
BOFs are executed in a separate thread to prevent agent crashes:
- **Timeout**: 30-second timeout for BOF execution
- **Thread Termination**: If BOF hangs, the thread is terminated after timeout
- **Output Capture**: Output is captured even if BOF hangs or times out
- **Agent Stability**: Main agent thread continues to function even if BOF crashes
### Beacon API Compatibility
The following Beacon API functions are supported:
- `BeaconPrintf` - Formatted output
- `BeaconOutput` - Raw output
- `BeaconPrintf` - Formatted output (captured and returned)
- `BeaconOutput` - Raw output (captured and returned)
- `BeaconDataParse` - Parse input data
- `BeaconDataInt`, `BeaconDataShort`, `BeaconDataExtract` - Data extraction
- `BeaconUseToken`, `BeaconRevertToken` - Token manipulation
- `BeaconIsAdmin` - Admin check
### Argument Serialization
Arguments are serialized using the Packer class format:
- Each argument is prefixed with its size (4 bytes, little-endian)
- Arguments are packed sequentially: `[size:4][data][size:4][data]...`
- The total buffer size is prepended to the argument buffer
- Boolean values are converted to integers (0 or 1) before serialization
## Error Handling
The command handles various error scenarios:
@@ -103,7 +122,6 @@ The command handles various error scenarios:
## Related
- [`inline_execute_assembly`](inline_execute_assembly.md) - Execute .NET assemblies in-process
- [`execute_assembly`](execute_assembly.md) - Execute .NET assemblies in remote processes
- [Artifacts Support](../features.md#artifacts-support)
---
@@ -45,32 +45,40 @@ inline_execute_assembly -Assembly SharpHound.exe -Arguments "-c All" --patchexit
## How It Works
1. The command creates a subtask that calls `inline_execute` with the Inline-EA BOF
2. The .NET assembly is passed to the BOF as raw bytes
3. The BOF loads the assembly into memory using .NET CLR APIs
4. Optional bypasses (AMSI, ETW) are applied if requested
5. The assembly's entry point is executed with the provided arguments
6. Output is captured and returned to Mythic
1. The command retrieves the .NET assembly from Mythic
2. The command searches for the Inline-EA BOF (`inline-ea.x64.o`) in Mythic's file store
3. A subtask is created that calls `inline_execute` with the Inline-EA BOF
4. The .NET assembly is passed to the BOF as raw bytes (hex-encoded)
5. The BOF loads the assembly into memory using .NET CLR APIs
6. Optional bypasses (AMSI, ETW) are applied if requested via flags
7. The assembly's entry point is executed with the provided arguments
8. Output is captured via `BeaconPrintf` and returned to the parent task through a completion callback
9. The completion callback aggregates the output and displays it in the main command
## Output
The command returns the output from the .NET assembly execution:
```
[inline_execute_assembly] Assembly execution requested
[BOF Output from Inline-EA]
SharpUp execution started...
[*] Checking for insecure file permissions...
[*] Checking for unquoted service paths...
[+] Found: C:\Program Files\Vulnerable Service\service.exe
[*] Completed Privesc Checks in 17 seconds
```
The output is captured from the Inline-EA BOF execution and displayed directly in the main command (not as a subtask).
## OPSEC Considerations
- **Process Create Artifact**: Assembly execution creates a "Process Create" artifact
- **MEDIUM OPSEC RISK**: In-process execution provides better OPSEC than process spawning (no process injection)
- **Process Create Artifact**: Assembly execution creates a "Process Create" artifact that is logged in Mythic
- **CLR Loading**: Loading .NET assemblies into memory may be detected by EDR solutions
- **AMSI Bypass**: Patching clr.dll for AMSI bypass may trigger behavioral detections
- **ETW Bypass**: EAT hooking may be detected by advanced EDR solutions
- **No New Process**: Executes in-process, reducing some detection vectors compared to `execute_assembly`
- **Memory Allocation**: Allocates executable memory for the assembly, which may be scanned
- **AMSI Bypass**: Patching `clr.dll` for AMSI bypass may trigger behavioral detections (more evasive than patching `amsi.dll`)
- **ETW Bypass**: EAT hooking `advapi32.dll!EventWrite` may be detected by advanced EDR solutions
- **No New Process**: Executes in-process, reducing some detection vectors compared to process spawning
- **Memory Allocation**: Allocates executable memory for the assembly, which may be scanned by EDR
- **Thread Isolation**: BOF execution runs in a separate thread with timeout protection
## Technical Details
@@ -84,22 +92,25 @@ This command uses the Inline-EA BOF developed by @EricEsquivel:
### Bypass Options
- **--patchexit**: Patches `System.Environment.Exit` to prevent the assembly from terminating the agent process
- **--amsi**: Bypasses AMSI by patching `clr.dll` instead of `amsi.dll` (more evasive)
- **--etw**: Bypasses ETW by hooking `advapi32.dll!EventWrite` via Export Address Table (EAT) hooking
- **--patchexit**: Patches `System.Environment.Exit` to prevent the assembly from terminating the agent process. Default: `false`
- **--amsi**: Bypasses AMSI by patching `clr.dll` instead of `amsi.dll` (more evasive than traditional AMSI bypasses). Default: `false`
- **--etw**: Bypasses ETW by hooking `advapi32.dll!EventWrite` via Export Address Table (EAT) hooking. Default: `false`
**Note**: Boolean flags (`--amsi`, `--etw`, `--patchexit`) are automatically converted to integers (0 or 1) for the BOF.
## Error Handling
The command handles various error scenarios:
- **Assembly Not Found**: Returns error if assembly file cannot be retrieved from Mythic
- **BOF Not Found**: Returns error if Inline-EA BOF (`inline-ea.x64.o`) is not found in Mythic's file store
- **BOF Execution Failure**: Returns error if Inline-EA BOF cannot be executed
- **Assembly Load Failure**: Returns error if .NET assembly cannot be loaded
- **Bypass Failure**: May fail silently if bypasses cannot be applied
- **Timeout**: If BOF execution hangs, it will timeout after 30 seconds and output will still be captured
## Related
- [`inline_execute`](inline_execute.md) - Execute BOFs directly
- [`execute_assembly`](execute_assembly.md) - Execute .NET assemblies in remote processes
- [Artifacts Support](../features.md#artifacts-support)
---