Repository navigation
10. 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.
| 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.
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. More approachable for newcomers than
sliver-clientor the Havoc Katana client. Better for demos 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.
-
Quick one-off shells:
sliver-clientis faster for a single operator who 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.
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.largeviamythic_instance_typein 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.
| 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 work with the redirector out of the box.
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.
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
All commands run from /opt/Mythic/ as root.
| Command | What it does |
|---|---|
sudo ./mythic-cli status |
Show all containers and their state |
sudo ./mythic-cli start |
Boot the entire Mythic stack |
sudo ./mythic-cli stop |
Shut down all containers (state persists) |
sudo ./mythic-cli logs <container> |
Tail logs for a specific container (e.g. mythic_server, mythic_nginx) |
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.
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.
Note
Payload customization (headers, URI prefixes, profiles) is supported and encouraged. It 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.
The walkthrough to confirm Mythic is wired correctly. Assumes Verify is complete and the Redirector cert step is done (Direct Access).
[!WARNING] Defender is disabled on the lab Windows workstation by default so unobfuscated agents can run. If you re-enabled it for evasion testing, the agent will be quarantined immediately. Either disable Defender (
Set-MpPreference -DisableRealtimeMonitoring $true) or generate the agent with obfuscation.
In Guacamole, open the Mythic (SSH) connection (or use the MobaXterm bookmark from the Windows operator workstation). Then:
cd /opt/Mythic
sudo ./mythic-cli statusLook 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

[Figure 10.3.1: mythic-cli status output showing all core containers plus apollo and http in the running state]
✅ Checkpoint: apollo and http both show running.
From the Windows workstation (via Guacamole RDP), open Chromium and navigate to https://mythic:7443.
-
Login:
mythic_admin -
Password: lab password from
deployment_info.txt
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.

[Figure 10.3.2: Mythic Installed Services → C2 tab with the http profile showing Accepting Connections]
✅ Checkpoint: HTTP profile online and listening.
In the left sidebar, click Create Payload. Five-step wizard:
-
Target OS: Select Windows.
-
Configure Payload: Select Apollo. Set Output Format to
WinExe. -
Select Commands: The default selection includes the core set (
shell,upload,ps,run, and others). That is enough to confirm the lab is working. The left panel lists additional commands you can move into the payload if you want to experiment with specific capabilities. -
Select C2 Profiles: Pick http from the dropdown and click + INCLUDE PROFILE. Configure:
Field Value callback_hostDirect Access: https://yourdomain.tld| Tunneled Access:https://<tun0-ip>callback_port443callback_interval10(seconds)callback_jitter20(percent)post_uricdn/media/stream/update(no leading/)User-AgentLeave as pre-populated. This is what Apollo beacon traffic masquerades as in transit. headersClick + Custom..., set KEY to X-Request-ID, set VALUE to the token fromterraform output deployment_info. This is the redirector's gate key; requests without it get the decoy page.encrypted_exchange_checkLeave enabled (default) -
Build: Click Next, name it (e.g.
apolloTest.exe), click Create Payload.
Wait 30-60 seconds. When done, a Payload successfully built! popup appears with a Download here link. Click it directly to download. You can also find it later under Payloads in the left sidebar.
✅ Checkpoint: Payload downloaded to C:\Users\Administrator\Downloads\.
Mythic UI runs in the Windows workstation browser, so the agent is already on the right host. Open a PowerShell prompt and run:
Start-Process -FilePath "C:\Users\Administrator\Downloads\apolloTest.exe" -WindowStyle HiddenUsing -WindowStyle Hidden prevents the console window from appearing. In a real engagement you would never manually execute a beacon; the delivery mechanism (phishing attachment, macro, exploit, dropper) handles execution entirely. For this lab, the PowerShell method above is the cleanest way to fire it off.
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.

[Figure 10.3.3: Mythic Active Callbacks table showing the windows callback row, with the tasking pane confirming shell whoami returns windows\administrator]
✅ Checkpoint: First Mythic callback received.
Click the callback's ID button to open the tasking pane. Run:
ps
This executes Apollo's built-in process enumeration. No shell required. You'll get a full process table with PID, name, architecture, and user. Scroll through and look for familiar Windows processes (lsass.exe, svchost.exe, explorer.exe) to confirm the agent has a real view of the host.

[Figure 10.3.4: Mythic tasking pane with ps output showing the full process table including PID, name, architecture, and user]
✅ Checkpoint: Lab is fully operational for Mythic. Move to Sliver or Havoc for the other C2 walkthroughs, or Kali for AD enum / attack tooling.
Most common cause: missing SSL cert for mythic_nginx.
cd /opt/Mythic
sudo ./mythic-cli logs mythic_nginxIf 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 restartMythic'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_nginxLook for repeated errors. Common: Postgres still initializing on first boot (give it another five minutes), Docker images still pulling (docker images to verify), or port conflict (sudo netstat -tlnp | grep 7443).
Two possible causes:
-
Mythic generated its own admin password and you didn't read it: The lab password works because cloud-init writes it to
MYTHIC_ADMIN_PASSWORDin.envbefore Mythic boots. If that injection failed, Mythic falls back to a random password.sudo cat /opt/Mythic/.env | grep MYTHIC_ADMIN_PASSWORD -
You're using the wrong username: It's
mythic_admin, notadmin(which is the SSH user) ormythic(which is the hostname).
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 apolloLook 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.
In order:
-
Listener is running: Mythic UI > Installed Services > C2 Profiles >
httpshows "Accepting Connections." -
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/testisn't a real callback path). 200-with-decoy means the header check failed. -
Agent build parameters match: In the Apollo agent build, the
headersfield MUST includeX-Request-ID: <token>, andpost_urimust start with the configured URI prefix (cdn/media/stream/...). Mismatch = decoy page. - Defender / AV on Windows: Open Event Viewer, check for Defender quarantine events. The agent never executes.
-
Agent is wedged at startup: Run
apollo.exefrom a cmd prompt and watch for errors / silent exit. If silent, build withDebugoutput format to get verbose logs.
See Troubleshooting > Agent Won't Callback for the full checklist applying to all C2s.
enable_mythic_autostart should be true in tfvars (default). Check the systemd unit:
sudo systemctl status mythic.serviceIf disabled or failed:
sudo systemctl enable mythic.service
sudo systemctl start mythic.serviceMythic 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-applyMythic 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 startWarning: removing the volume wipes ALL Mythic state (callbacks, payloads, operators). Only do this if state is recoverable elsewhere or you're starting fresh.
← Previous: Redirector | Next: Sliver →
“The price of reliability is the pursuit of the utmost simplicity.”
C. A. R. Hoare, Turing lecture (1980)