Detect and remove Realm C2 implants.
dispel is a host-based detection tool that finds Realm command-and-control implants on compromised systems. It scans running processes, live process memory, network connections, persistence mechanisms, and runtime behavior to identify the Realm C2 agent (imix) with high confidence and zero false positives.
Detects implants even when the binary has been deleted from disk, renamed to look like a system service, or loaded entirely from memory.
Single static binary. No dependencies. Drop it on a box and run it.
# Build
cargo build --release
# Scan everything
./dispel scan
# Scan only in-memory indicators
./dispel scan --layer memory
# JSON output for automation
./dispel scan --json
# Incident response report with forensic details
./dispel scan --ir
# Detect, quarantine, and kill implants (dry run first)
./dispel kill --dry-run
./dispel kill
# Continuous monitoring (10s interval)
./dispel watch --interval 10| Layer | What it detects |
|---|---|
| proc | Scans live process binaries for Realm signatures using Aho-Corasick multi-pattern matching. Checks known install paths (/tmp/imix, /bin/imix, etc.). Flags deleted executables and high thread counts. |
| memory | Reads live process memory via /proc/pid/mem (Linux) or ReadProcessMemory (Windows) to find Realm signatures in running processes — even after the binary is deleted from disk. Detects anonymous RWX memory regions, memfd-based fileless execution, process masquerading (exe vs argv[0] mismatch), shared libraries loaded from /tmp or /dev/shm, suspicious environment variables (IMIX_*), private executable regions, and injected threads with start addresses in non-image memory. |
| net | Identifies Realm gRPC service paths (/c2.C2/ClaimTasks, /c2.C2/ReverseShell, etc.) in traffic. Detects DNS tunneling via base32-encoded subdomains. Flags high-entropy prefixes (X25519 pubkey + XChaCha20 nonce). Monitors for beaconing patterns. |
| persist | Finds beacon ID files (UUID v4 at known paths). Checks systemd units, sysvinit scripts, and Windows registry/services for Realm service names. Detects timestomped binaries. |
| behavior | Identifies shell processes with socket-redirected file descriptors (reverse shells). Flags recent /etc/shadow access (credential harvesting). |
Every finding has a tier that reflects how conclusive it is:
| Tier | Weight | Meaning | Examples |
|---|---|---|---|
| T3 | 5 | Conclusive | gRPC paths like /c2.C2/ClaimTasks, Eldritch functions like _terminate_this_process_clowntown |
| Behavioral | 4 | Suspicious runtime behavior | Reverse shell indicators, shadow file access |
| T2 | 3 | Strong indicator | imix-v, eldritch::, ChachaCodec strings |
| T1 | 1 | Definitive artifact | Binary at /tmp/imix, service named imix |
Scores are summed to produce a severity:
- CLEAN (0) — No indicators
- SUSPECT (1-4) — Low-confidence, worth investigating
- DETECTED (5+) — High-confidence Realm C2 presence
Exit codes: 0 = clean, 1 = suspect, 2 = detected.
dispel detects Realm C2 through signatures extracted from the spellshift/realm source code:
- 8 gRPC service paths from the C2 proto definition (
/c2.C2/ClaimTasks,/c2.C2/ReverseShell, etc.) - 5 Eldritch distinctive functions (
_terminate_this_process_clowntown,dll_inject,dll_reflect,reverse_shell_pty,reverse_shell_repl) - 6 Eldritch agent API functions (
report_credential,set_callback_interval, etc.) - 6 Eldritch report module paths (
report::file,report::ntlm_hash, etc.) - 3 offensive capability names (
create_portal,ssh_exec,ssh_copy) - 8 Tier 2 string indicators (
imix-v,eldritch::,ChachaCodec,KIND_NTLM_HASH, etc.)
All signatures are scanned simultaneously using an Aho-Corasick automaton for efficient multi-pattern matching over memory-mapped binaries.
| Platform | Process Scanning | Memory | Network | Persistence | Behavior | Kill |
|---|---|---|---|---|---|---|
| Linux | Full | Full | Full | Full | Full | Full |
| Windows | Full | Full | Full | Full | Stub | — |
| BSD | Stub | — | Stub | Partial | Stub | — |
| macOS | Build only | — | Build only | Build only | Build only | — |
Generate a forensic report with --ir:
./dispel scan --irFor each detected implant, the IR report includes:
- SHA256 hash, file size, owner, permissions, timestamps
- Extracted C2 callback URIs compiled into the binary
- Running process details (PID, parent, user, cmdline, cwd, start time, environment)
- Active network connections attributed to the implant
- Persistence mechanisms (beacon IDs, services, systemd units)
- One-liner summary for Slack/triage
JSON output combines scan results and IR data:
./dispel scan --ir --jsonDetect, quarantine, and remove implants in one step (Linux only):
# Preview what would happen
./dispel kill --dry-run
# Execute: quarantine binary, kill processes, remove persistence
./dispel kill
# Custom quarantine directory
./dispel kill --quarantine-dir /evidence/quarantineDefault quarantine location: /var/lib/dispel/quarantine/. Quarantined binaries are named <sha256prefix>_<basename> for deduplication.
Build for Linux from macOS (requires zig and cargo-zigbuild):
cargo zigbuild --release --target x86_64-unknown-linux-gnuSuppress known-good findings with an allowlist file:
# Allow known infrastructure
ip 192.168.1.10
ip 10.0.0.5
proc sshd
proc systemd-resolved
./dispel scan --allowlist /etc/dispel/allowlist.confContinuous monitoring with deduplication (findings suppressed for 300s after first report):
# Human-readable alerts
./dispel watch --interval 10
# JSON lines for log ingestion
./dispel watch --interval 10 --json
# Diff against a known-good baseline
./dispel scan --json > baseline.json
./dispel watch --baseline baseline.jsonMIT

