Kassandra is a custom Mythic C2 agent written in Rust, packaged as a Python payload-type container. It targets Windows x86_64, cross-compiled from Linux via x86_64-pc-windows-gnu.
This public release does not include every private obfuscation / defense-evasion technique. Some components are simplified intentionally. The full private build remains controlled red-team use only.
From the Mythic install directory:
cd /path/to/Mythic
sudo ./mythic-cli install github https://github.com/PatchRequest/KassandraOr from a local folder:
sudo ./mythic-cli install folder /path/to/KassandraCase note: mythic-cli may create InstalledServices/Kassandra while Docker Compose expects lowercase kassandra. Rename if needed:
sudo mv InstalledServices/Kassandra InstalledServices/kassandra
sudo docker compose build kassandra && sudo docker compose up -d kassandraBusyWork evasion (BusyWork)
Replaces fixed-cadence sleep() with real, varied work (compute, memory, WinAPI, registry, crypto, …) so callback intervals do not look like pure idle-then-act beacons.
| API | Role |
|---|---|
idle() |
One full-intensity burst between tasking rounds + short jittered yield. Main callback-interval surface. |
churn() |
Always Low, COMPUTE | MEMORY only — light noise at feature boundaries (not on every HTTP POST). |
startup_delay() |
One burst at configured intensity before first check-in. |
- Operator-selectable levels:
off/low/medium/high/ultra - Real program data is fed in via
feed()(UUID, host, paths, outputs, …) - C2 transport path does not run BusyWork — chunked uploads/downloads issue many POSTs; heavy work stays in
idle()so Medium/High remain usable without starving tasking - Intensity ladder lives in BusyWork (
bump/windows-0.61); levels must stay a real volume ladder (no flattening.min(N)caps)
Indirect syscalls (CallGhost)
Hell’s Hall + NASM trampoline was replaced with CallGhost:
syscall!(indirect, NtFoo, /* args */);Halo’s Gate SSN resolution, SSN caching, used across:
- Check-in (host / user / PID)
- Process list & selfclone
- Reflective loader / mem wipe / local Nt helpers
- Self-delete
- BOF loader injection primitives
Sets a restrictive process DACL (deny Everyone generic-all; allow System + owner) so casual handle opens against the implant process fail. Failures are silent (no eprintln).
Loader code is not linked into the agent binary:
- Standalone
bof_loader.dll/dot_loader.dllbuilt in Docker →/opt/loaders/ - Agent downloads loaders from C2, stores them XOR-encrypted in memory (
loader_cache) - Reflective load →
execute_bof/execute_dot→ wipe (mem_wipe)
| Piece | Notes |
|---|---|
| BOF | Forked/renamed coffee-ldr style loader |
| .NET | clroxide-based dot-loader |
| Python | Still subprocess worker (--worker-py) |
loadLoader |
Pre-stage loaders (temporal separation from execution) |
Docker catalog-builder stage compiles tools from pinned upstream commits into /opt/kassandra_catalog + manifest.json.
| Source | Type | Prefix |
|---|---|---|
| TrustedSec CS-SA-BOF | BOF | tsec_ |
| Outflank C2-Tool-Collection | BOF | outflank_ |
| Flangvik SharpCollection | .NET | sharp_ |
listRemote [filter]— server-side only (no agent round-trip)executeRemote -tool_name <name> [-parameters …]— container registers the file and rewrites the task toexecuteBOF/executeDOT
listRemote kerb
executeRemote -tool_name tsec_whoami
executeRemote -tool_name sharp_seatbelt -parameters "-group=system"
Priority dispatch in transport.rs:
- Tailscale (feature) — embedded tsnet / WireGuard via Go FFI; HTTP or raw TCP inside the tunnel; optional DoH
- S3 — SigV4, bootstrap → per-execution IAM creds, optional AES-256-CBC + HMAC-SHA256 (EKE)
- HTTP — Mythic HTTP profile; body
base64(uuid ‖ json)
Translation container KassandraTranslator is a JSON pass-through (mythic_encrypts = false).
- SOCKS via Mythic
- Pivot listeners (
start_pivot/stop_pivot/list_pivot)
Filesystem (ls/rm/mkdir/mv/cp/touch/pwd), upload/download, process list (ps / psw), screenshot, selfdelete, selfclone, ping, exit.
| Parameter | Type | Default | Description |
|---|---|---|---|
output |
exe / dll | exe | Output format |
chunk_size |
string | 4096 | Upload/download chunk size |
busywork_intensity |
off / low / medium / high / ultra | medium | BusyWork intensity for idle / startup |
no_console |
bool | true | windows_subsystem = windows |
debug_log |
bool | false | Lab only: lifecycle log → %TEMP%\kassandra_debug.log (cargo feature debug_log) |
tailscale_protocol |
http / tcp | http | Protocol inside WireGuard |
doh |
off / cloudflare / google / custom | off | DoH for Tailscale DNS |
doh_url |
string | — | Custom DoH URL when doh=custom |
Production defaults: no_console=true, busywork=medium, debug_log=false.
Lab: prefer debug_log=true and busywork=off or low while debugging tasking.
| Feature | Effect |
|---|---|
tailscale |
Tailscale transport + link Go FFI |
no_console |
Hide console window |
debug_log |
Enable dlog! file logging (otherwise compile-time no-op) |
checkin (CallGhost syscalls for host/user/pid)
→ main loop:
get_tasking → handleTask → idle() BusyWork
Reflective path:
loadLoader / on-demand download
→ XOR cache → reflective_loader → execute_bof / execute_dot → mem wipe
Related repos:
Payload_Type/Kassandra/
Dockerfile # catalog-builder + runtime
build_catalog.sh
main.py
translator/translator.py
Kassandra/
agent_functions/ # Mythic commands + builder.py
agent_code/kassandra/ # Rust implant
src/ # main, tasking, transport, features, …
loaders/ # bof-loader, dot-loader (cdylib)
tailscale_ffi/ # Go tsnet wrapper
Ideas baked into the current public tree:
- Evasion without starving C2 — heavy BusyWork only between rounds (
idle); lightchurnat boundaries; never on raw HTTP I/O. - Loaders out of the implant — reflective DLLs staged from C2; optional
loadLoaderfor OPSEC timing. - Catalog as container content — operators run tools without manual uploads; agent only sees normal BOF/DOT tasks.
- Syscalls via a maintained crate — CallGhost instead of a bespoke Hell’s Hall + ASM stack.
- Silent production build — no debug file/stderr unless
debug_logis explicitly enabled at build time. - Self-protect by default — DACL lockdown on EXE and DLL entry (lab builds should not permanently disable this).
Series on patchi.fyi:
- Architecture Overview
- Hell's Hall Syscalls (historical; agent now uses CallGhost)
- S3 Transport
- In-Memory Execution
- Process Hardening
Educational and authorized red-team use only. Do not use without proper authorization.
Thanks to @Yeeb1 for the awss3 S3 C2 profile, Tailscale C2, and agent improvements.
Thanks to MalDevAcademy, VX-Underground, @ZkClown, and Ze_Asimovitch for training, archives, and inspiration in the red-team community.
