Skip to content

10. Mythic

BaddKharma edited this page May 2, 2026 · 59 revisions

📡 Mythic

Home > Mythic

Modular, multi-operator, web-driven C2 framework. The default redStack configuration ships with the HTTP profile and Apollo agent pre-installed; add more containers from the official catalog as needed.

On this page: Considerations · Configuration · Initial Beacon · Troubleshooting · See Also.

At a glance
Hostname mythic (private VPC only)
Web UI https://mythic:7443 (open from the Windows workstation via Guacamole)
UI login mythic_admin / lab password
SSH admin + lab password (Guacamole > Mythic (SSH))
URI prefix /cdn/media/stream/ (stripped before forward to Mythic)
Default agent Apollo (.NET, Windows)
Default profile HTTP
Time to first beacon ~5 minutes once the lab is verified
Full docs docs.mythic-c2.net

Note

Mythic is built around a Docker container per agent and per profile. The core stack runs ~8 containers; each agent type (Apollo, Athena, Poseidon, etc.) and each profile (HTTP, DNS, websocket, etc.) adds another. This is what makes it modular: enabling DNS callbacks is a mythic-cli install away.


• Considerations

- When Mythic is the right pick

Reach for Mythic when any of these matter:

  • Multi-operator engagement: Mythic was built for teams. Operator accounts, callback assignment, task review, file browser sharing, all native. Sliver supports multiplayer too but is CLI-driven; Havoc's multi-operator story is weaker.
  • Visual / UI-driven workflow: Web UI in a browser. Easier for newcomers than sliver-client or the Havoc Katana client. Easier to demo or screen-share.
  • Cross-platform agents: Apollo (Windows .NET) is what redStack ships, but the Mythic ecosystem includes Poseidon (macOS/Linux), Athena (.NET / Linux / macOS), Medusa (Python), Hannibal (Linux), Freyja (Go cross-platform), and others. Add via mythic-cli install github <agent-repo>.
  • Built-in tasking history: Every operator command, payload spawn, and callback event is recorded with operator attribution. Useful for training reviews.

- When to skip Mythic

  • Quick one-off shells: sliver-client is faster for a single operator who just needs a short reverse shell.
  • Evasion-focused work: Apollo is well-known to AV vendors. For modern evasion, Havoc demons (with their indirect-syscall and sleep-obfuscation features) are stronger out of the box.
  • Resource-constrained deploy: The Mythic Docker stack is the heaviest single component in redStack. If you bumped instance types down to save money, Mythic is the first thing to feel it.

- Sizing tradeoffs

Default t3.medium (2 vCPU, 4 GB RAM, 30 GB disk):

  • Comfortable for the core 8-container stack + Apollo + HTTP.
  • Tight if you add more than 2-3 additional agents or profiles.
  • If you intend to install everything from the Mythic catalog (Apollo + Poseidon + Athena + DNS + websocket + etc.), bump to t3.large via mythic_instance_type in tfvars.

Disk: 30 GB is enough for the core stack + a couple of extra agents. Each additional agent container is ~500 MB pulled. Bump root volume size if you plan to test many agent types.

- What ships pre-installed

Component Where
Mythic core /opt/Mythic/
HTTP profile /opt/Mythic/InstalledServices/http/
Apollo agent /opt/Mythic/InstalledServices/apollo/
Admin password /opt/Mythic/.env (key MYTHIC_ADMIN_PASSWORD)
systemd unit /etc/systemd/system/mythic.service (auto-start enabled if enable_mythic_autostart = true in tfvars)

The HTTP profile is pre-configured with the redStack X-Request-ID token at boot time so agents you generate Just Work with the redirector.

- Operations model

Mythic is designed to outlive a single operator session. The Postgres database persists callbacks, payloads, tasking history, and operator accounts in a Docker volume. If you terraform destroy, that volume is wiped. If you mythic-cli stop && mythic-cli start, state survives.

For longer engagements where you want to preserve callbacks across sessions, see Cost Management > Stop Between Sessions; the Mythic DB volume rides along with the stopped instance.


• Configuration

- What runs where

mythic (Debian 12) [t3.medium, EBS gp3 30 GB]
├── /opt/Mythic/                       Mythic install root
│   ├── mythic-cli                     The control binary (status, start, stop, install, logs)
│   ├── .env                           Generated config (admin password, ports, etc.)
│   ├── docker-compose.yml             Compose stack
│   ├── InstalledServices/             One subdir per profile / agent (http, apollo, ...)
│   └── postgres-docker/               Persistent DB volume
├── /etc/systemd/system/mythic.service systemd auto-start unit
└── /etc/hosts                         pre-populated with all lab hostnames

- mythic-cli quick reference

All commands run from /opt/Mythic/ as root.

Command What it does
sudo ./mythic-cli status Shows all containers, their state (running / stopped / restarting), and resource usage
sudo ./mythic-cli start Boots the entire Mythic stack
sudo ./mythic-cli stop Gracefully shuts down all containers (state persists)
sudo ./mythic-cli logs <container> Tail logs for a specific container (e.g. mythic_server, mythic_nginx)
sudo ./mythic-cli install github <url> Install a new profile or agent from a GitHub repo
sudo ./mythic-cli uninstall <service> Remove an installed profile / agent
sudo ./mythic-cli config Print current config from .env

- Adding more agents

Common additions from the official catalog:

cd /opt/Mythic

# Linux / macOS / Windows cross-platform Go agent
sudo ./mythic-cli install github https://github.com/MythicAgents/freyja

# Linux ELF agent
sudo ./mythic-cli install github https://github.com/MythicAgents/hannibal

# Python agent (in-memory)
sudo ./mythic-cli install github https://github.com/MythicAgents/medusa

# After installs, restart so the UI picks them up
sudo ./mythic-cli stop
sleep 5
sudo ./mythic-cli start

Browse the full catalog at github.com/MythicAgents. Each agent's README documents its build parameters and supported OS.

- Adding more C2 profiles

# DNS C2
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/dns

# Websocket C2
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/websocket

[!IMPORTANT] If you add profiles other than HTTP, the redStack Apache redirector won't proxy them out of the box. The redirector is only configured for HTTP-on-port-80-from-Mythic. DNS and websocket profiles need separate ingress paths (DNS resolver on the redirector, additional WebSocket VirtualHost, etc.). Out of scope for redStack default; possible to add manually.

- HTTP profile customization

The default HTTP profile is configured at boot via mythic_setup.sh. Key generation parameters:

  • X-Request-ID header: required for all callbacks. Value is the c2_header_value from tfvars (auto-generated if empty). Embedded in payloads at generate time.
  • URI prefix: /cdn/media/stream/. Configurable via mythic_uri_prefix in tfvars. Stripped by the redirector before forwarding.
  • Callback ports: 80 (HTTP, internal forwarding from redirector). The redirector terminates SSL on 443 publicly.

To customize after deploy: open the Mythic UI > Installed Services > C2 Profiles > http > edit profile config. Restart the profile (the Start/Stop buttons in the UI).

- Resetting between sessions

# Wipe ALL state (callbacks, payloads, tasking history)
cd /opt/Mythic
sudo ./mythic-cli stop
sudo docker volume prune -f
sudo ./mythic-cli start

This survives a terraform destroy && apply cycle automatically (since destroy wipes the EBS volume entirely). Use the docker volume prune only when you want to reset within a running session.

- Web UI access from outside the Windows workstation

By default Mythic UI is reachable only at https://mythic:7443 from inside the lab (because Mythic has no public IP and the Windows hostname-resolution magic). If you want to reach it from your host laptop:

# SSH tunnel via Guacamole
ssh -i rs-rsa-key.pem -L 7443:mythic:7443 admin@<GUAC_PUBLIC_IP>
# Then open https://localhost:7443/ in your laptop browser

Same applies for mythic-cli ops if you want to drive Mythic remotely instead of via Guacamole SSH.


• Initial Beacon

The walkthrough to confirm Mythic is wired correctly. Assumes Verify is complete and the Redirector cert step is done (open mode).

- Step 1: Verify Pre-Installed Profiles and Agents

ssh admin@mythic
cd /opt/Mythic
sudo ./mythic-cli status

Look for apollo and http under Installed Services. Both should show running.

If either is missing:

cd /opt/Mythic
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/http
sudo ./mythic-cli install github https://github.com/MythicAgents/apollo
sudo ./mythic-cli stop && sleep 10 && sudo ./mythic-cli start

[IMAGE PLACEHOLDER]: Screenshot of mythic-cli status output showing all core containers + apollo + http in the running state.

Checkpoint: apollo and http both show running.

- Step 2: Verify HTTP C2 Profile is Accepting Connections

From the Windows workstation (via Guacamole RDP), open Chromium and navigate to https://mythic:7443.

  • Login: mythic_admin
  • Password: retrieve with sudo cat /opt/Mythic/.env | grep MYTHIC_ADMIN_PASSWORD on the Mythic server (or use the lab password from terraform output deployment_info)

Once logged in, navigate to Installed Services > C2 Profiles. The http profile row should show:

  • Container Status: Online
  • C2 Server Status: Accepting Connections

If it shows Stopped, click the Start Profile button.

[IMAGE PLACEHOLDER]: Screenshot of the Mythic UI Installed Services > C2 tab with http showing "Accepting Connections."

Checkpoint: HTTP profile online and listening.

- Step 3: Generate the Apollo Agent

In the left sidebar, click Create Payload. Five-step wizard:

3.1 Target OS: Windows.

3.2 Configure Payload: Select Apollo.

Build Parameter Value
Output Format WinExe

3.3 Select Commands: Select all, or at minimum shell, download, upload, screenshot, ps.

3.4 Select C2 Profiles: In the dropdown, pick http and click + INCLUDE PROFILE. Configure:

Field Value
callback_host https://yourdomain.tld (open mode) or https://<REDIR_PUBLIC_IP> (closed mode)
callback_port 443
callback_interval 10 (seconds)
callback_jitter 20 (percent)
post_uri cdn/media/stream/update (no leading /)
headers Add row: KEY X-Request-ID, VALUE <token from terraform output deployment_info>
encrypted_exchange_check Leave enabled (default)

3.5 Build: Click Next, name it (e.g. apollo-training), click Create Payload.

Wait 30-60 seconds. The popup confirms when done. Navigate to Payloads in the sidebar and click the green download arrow.

[GIF PLACEHOLDER]: Screen recording of the full payload wizard from Target OS through Build click and download. ~30 seconds.

Checkpoint: apollo.exe downloaded to C:\Users\Administrator\Downloads\.

- Step 4: Execute on the Windows Operator

Mythic UI runs in the Windows workstation browser, so the agent is already on the right host. From File Explorer, navigate to C:\Users\Administrator\Downloads\ and double-click apollo.exe.

[!WARNING] Windows Defender is disabled by default on the lab Windows workstation specifically so unobfuscated agents can run during this walkthrough. If you re-enabled Defender (to test evasion), the binary will be quarantined immediately. Either re-disable it (Set-MpPreference -DisableRealtimeMonitoring $true) or generate the agent with obfuscation.

In the Mythic UI, click the phone icon (top nav) to open Active Callbacks. A row appears within ~10 seconds: windows host, Administrator user, private IP.

[IMAGE PLACEHOLDER]: Screenshot of the Mythic Active Callbacks table with a fresh windows row populated.

Checkpoint: First Mythic callback received.

- Step 5: Confirm the Full Path

Click the callback's ID button to open the tasking pane. Run:

shell whoami

Expected output: windows\administrator.

In another terminal, tail the redirector access log to confirm traffic is flowing through the redirector:

ssh admin@redirector
sudo tail -f /var/log/apache2/redirector-ssl-access.log

You should see regular GET/POST requests to /cdn/media/stream/status and /cdn/media/stream/update. If you see them, the entire chain (Apollo agent → DNS → redirector cert + header check + URI route → VPC peering → Mythic HTTP listener → tasking response back) is working end-to-end.

[GIF PLACEHOLDER]: Side-by-side terminal: Mythic UI tasking pane on the left running shell whoami, redirector ssl-access.log tail on the right showing the matching POST request. ~15 seconds.

Checkpoint: Lab is fully operational for Mythic. Move to Sliver or Havoc for the other C2 walkthroughs, or Kali for AD enum / attack tooling.


• Troubleshooting

- mythic-cli status shows containers in Restarting loop

Most common cause: missing SSL cert for mythic_nginx.

cd /opt/Mythic
sudo ./mythic-cli logs mythic_nginx

If you see cannot load certificate "/etc/ssl/private/mythic-cert.crt": No such file or directory, generate the cert manually:

sudo openssl req -x509 -newkey rsa:4096 \
  -keyout /etc/ssl/private/mythic-cert.key \
  -out /etc/ssl/private/mythic-cert.crt \
  -days 365 -nodes -subj "/CN=mythic"

cd /opt/Mythic
sudo ./mythic-cli restart

- Web UI returns "connection refused" or hangs

Mythic's container stack takes ~5-10 minutes to come up after cloud-init starts. During that window, https://mythic:7443 will fail. Wait, retry. If still failing after 15 minutes:

cd /opt/Mythic
sudo ./mythic-cli status
sudo ./mythic-cli logs mythic_server
sudo ./mythic-cli logs mythic_nginx

Look for repeated errors. Common: Postgres still initializing on first boot (give it another 5 min), Docker images still pulling (docker images to verify), or port conflict (sudo netstat -tlnp | grep 7443).

- Login fails with mythic_admin / lab password

Two possible causes:

  1. Mythic generated its own admin password and you didn't read it: The lab password works because cloud-init writes it to MYTHIC_ADMIN_PASSWORD in .env before Mythic boots. If that injection failed, Mythic falls back to a random password.

    sudo cat /opt/Mythic/.env | grep MYTHIC_ADMIN_PASSWORD
  2. You're using the wrong username: It's mythic_admin, not admin (which is the SSH user) or mythic (which is the hostname).

- Apollo build hangs or fails

The Apollo container compiles the agent on demand. First build can take 60-90 seconds; subsequent builds 30-45 seconds.

If it hangs > 3 minutes:

sudo ./mythic-cli logs apollo

Look for compilation errors. Most common: missing build parameter (Mythic UI flagged but not enforced), or out-of-memory on t3.medium if Mythic stack is busy. Bump to t3.large and retry.

- Callback never arrives

In order:

  1. Listener is running: Mythic UI > Installed Services > C2 Profiles > http shows "Accepting Connections."
  2. Network path is clear: From the redirector: curl -k -H "X-Request-ID: <token>" -A "Mozilla/5.0..." https://yourdomain.tld/cdn/media/stream/test. Should return Mythic's 404 (since /test isn't a real callback path). 200-with-decoy means the header check failed.
  3. Agent build parameters match: In the Apollo agent build, the headers field MUST include X-Request-ID: <token>, and post_uri must start with the configured URI prefix (cdn/media/stream/...). Mismatch = decoy page.
  4. Defender / AV on Windows: Open Event Viewer, check for Defender quarantine events. The agent never executes.
  5. Agent is wedged at startup: Run apollo.exe from a cmd prompt and watch for errors / silent exit. If silent, build with Debug output format to get verbose logs.

See Troubleshooting > Agent Won't Callback for the full checklist applying to all C2s.

- Mythic auto-start didn't work after instance reboot

enable_mythic_autostart should be true in tfvars (default). Check the systemd unit:

sudo systemctl status mythic.service

If disabled or failed:

sudo systemctl enable mythic.service
sudo systemctl start mythic.service

- "Out of disk space" during agent build

Mythic generates payloads in /opt/Mythic/InstalledServices/<agent>/.../tmp/. Repeated builds without cleanup fill disk.

# Check disk
df -h /

# If /opt is full, prune Docker
sudo docker system prune -af
sudo docker volume prune -f

# If still full, bump root volume size in tfvars and re-apply

- After upgrade, "schema mismatch" or DB errors

Mythic uses Alembic for DB migrations. After installing a new agent or profile that bumps the schema, the migration runs on next start. If interrupted:

cd /opt/Mythic
sudo ./mythic-cli stop
sudo docker volume rm mythic_mythic_postgres_volume
sudo ./mythic-cli start

Warning: removing the volume wipes ALL Mythic state (callbacks, payloads, operators). Only do this if state is recoverable elsewhere or you're starting fresh.


• See Also


← Previous: Redirector


"The price of reliability is the pursuit of the utmost simplicity."

C. A. R. Hoare, Turing lecture (1980)

Clone this wiki locally