Skip to content

10. Mythic

BaddKharma edited this page May 6, 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

Mythic's web UI is accessed from the Windows operator workstation browser only (https://mythic:7443). Mythic has no public IP and the hostname mythic resolves via the Windows hosts file. All payload generation, callback monitoring, and tasking happens through the Windows workstation's Chromium browser accessed via Guacamole RDP or MobaXterm.

[!NOTE] Payload customization (headers, URI prefixes, profiles) is supported and encouraged for operators who want to explore profile configuration. That customization is out of scope for this wiki's walkthroughs, which focus on confirming the default redStack configuration works end-to-end. The HTTP profile and Apollo agent ship pre-configured and ready to use.


Initial Beacon

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

- Step 1: Verify Pre-Installed Profiles and Agents

In Guacamole, open the Mythic (SSH) connection (or use the MobaXterm bookmark from the Windows operator workstation). Then:

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 (Direct Access) or https://<REDIR_PUBLIC_IP> (Tunneled Access)
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 Guacamole tab, open the Redirector (SSH) connection and tail the access log to confirm traffic is flowing through the 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