Introduction to Mythic C2
By Red Siege | June 28, 2023
Continuing along with my occasional series looking at how to set up and use various C2 frameworks, this is a guide to Mythic C2. Developed by Cody Thomas at SpecterOps and originally named Apfell, Mythic started out as a C2 targeted at running operations against organizations running MacOS, but rebranded as Mythic in 2020 once it became clear to the developers that it had grown into a multi-platform project.
The core elements of Mythic are written in Python 3, and the framework relies heavily on docker for managing key elements of its functionality, including the server, agents and C2 profiles (communications channels). Mythic is a multi-user C2 platform with a Web UI. It’s designed to be extensible, with the ability for other people to write agents and communications channels for it. As of late January 2023, it supported communications over tcp, http, websockets, smb and dns. It also has about a dozen different agents written in languages including Go, Python and C#, among others, and targeting Windows, MacOS and Linux.
The docker containers Mythic relies on for agents, C2 communication channels and the like can be large, as they can contain whole build environments, sometimes for multiple OSes. For point of reference, one of the Mythic installs I was recently experimenting with, including the server, the HTTP communication channel, and the Poseidon and Apollo agents, used approximately 13 GB of disk space. I also used a VPS with 2GB of RAM, as the host was giving me issues when running with only 1GB.
To get started with Mythic, you can run
git clone https://github.com/its-a-feature/Mythic for the most current version in the repo, or visit the releases page at
https://github.com/its-a-feature/Mythic/releases and download the most recent release.
Before running Mythic for the first time, make sure that both
docker-compose are installed, as both are necessary for Mythic to install and run. On Kali,
apt update && apt upgrade -y && apt install docker docker-compose should suffice. For Debian and Ubuntu, which may require additional repos, Mythic includes a pair of scripts (
install_docker_ubuntu.sh) to make things easier. (There is an
install_docker_kali.sh, but it’s just the commands I listed previously.)
Mythic configurations are stored in
Mythic/.env. Mythic will automatically generate this file the first time
mythic-cli runs, using the defaults shown in the Mythic documentation here. I will note that these configurations only affect the Mythic server, not the agents, and there are a few settings you may want to set for opsec reasons. The
ALLOWED_IP_BLOCKS variable lets one specify blocks of IP addresses which are allowed to connect to the Mythic server. These should be set as a comma-separated list of netblocks with no host IP addresses set (e.g. 127.0.0.0/24,192.168.0.0/16,etc.).
NGINX_PORT sets the TCP port the Mythic server GUI listens on (default is 7443). While this port that can be exposed to the internet, a preferable way of connecting would be to block connections to the NGINX port from the internet, and instead use an ssh rule to forward connections from 127.0.0.1:<NGINX_PORT> on one’s workstation to 127.0.0.1:<NGINX_PORT> on the Mythic server. Setting the following configuration in the workstation’s
.ssh/config file before can enable this automatically:
hostname <server IP>
LocalForward 127.0.0.1:7443 127.0.0.1:7443
The two options that can affect operations with Mythic are
EXCULDED_PAYLOAD_TYPES, which can be used to disallow specific C2 channels and agents (e.g.
For purposes of this blog, I used Mythic’s default settings. I started Mythic by running
sudo ./mythic-cli start in the
Mythic/ directory. As this was the first time I’d run the start command for this instance of Mythic, it took several minutes to run as it pulled down and built the necessary Docker images.
By default, Mythic has no C2 profiles or agents installed. Anything you want to use needs to be installed using the Mythic CLI tool. To install the Poseidon agent, I typed the command below:
sudo ./mythic-cli install github https://github.com/MythicAgents/Poseidon
I followed that up with installing the Medusa and Apollo agents, using essentially the same command as shown below
sudo ./mythic-cli install github https://github.com/MythicAgents/<agent name>
Poseidon installs its own TCP C2 channel, but this is a peer-to-peer channel for agents communicating inside a compromised environment, so to enable outbound communications to my server, I also installed the http C2 channel with the following command:
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/http
I opened my
Mythic/.env file to find the password for the
Password in hand, I authenticated to the server at https://127.0.0.1:7443. Mythic generates a self-signed cert, so I needed to click through the browser warnings.
Mythic is a multi-operator framework, and using an admin account you can add users by clicking the user icon in the upper right-hand corner of the page and selecting User Management.
Mythic groups activities performed against a target or related set of targets into “operations”. Mythic users must be granted permissions on a per-operation basis. The default operation, which can be set in the
.env file is
Operation Chimera. You can access the operations screen by clicking
Operation Chimera in the button bar at the top of the page.
On the operations screen, you can create and edit operations, create new users, and also create command blocklists. I clicked
New Operation to create a new operation, and named it
Operation RedSiege. Once it was created, I clicked the
Edit button for
operators on that operation, and I had the option to assign users to the operation, set their role, and assign blocklists.
The available roles are
Lead is also the operation admin, with the ability to add/remove operators and change roles,
operator is the standard operator, and
spectators can observe the operation, but not take any actions.
I assigned my
justin account as the lead for the operation, then logged out of the
mythic_admin account and logged back in with
justin. As an aside I’ll note that, even as the operation lead, I could not modify the operation until I clicked the blue
Make Current button on the operation management screen.
Edit button for the operation itself brings up the options to rename the operation, mark it completed, or configure Slack webhooks for the operation, if you’re integrating with Slack.
The last thing on the operations configuration page is the blocklists section. Blocklists define a list of commands that Mythic will not permit a given agent (e.g. Apollo, Poseidon, Merlin) to run.
Blocklists can be assigned per-user, per-operation. So, If you wanted a particular user to not be able to do anything to modify the disk on a compromised machine, you could create a blocklist that disables commands such as
mkdir, etc., and then assign it under the operation’s
operators edit page.
I clicked the headphones icon at the top of the page to bring up the Payload Types and C2 Profiles page.
This page shows information about all the installed agents and C2 channels. On my server this showed that I had the Apollo and Poseidon agents installed, and the http and Poseidon TCP C2 channels installed.
Mythic’s http C2 channel configuration options are limited to changing server headers, the port, URL, and whether TLS is enabled. To access the profile configuration, I hit the down arrow on the
start profile button to access the dropdown menu and selected
The config is a JSON file which allows an operator to set server headers, the listening port, and whether TLS/SSL is enabled. To enable TLS/SSL, set
use ssl to
true. If the
key path and
cert path are valid files, Mythic will use those for the http2 C2 profile. If not, it will generate self-signed certificates.
I chose to use the default profile. The http C2 profile will be relatively easy to fingerprint, as every request will be essentially identical. There is a dynamichttp C2 profile , which allows for much more tailoring and building randomness into the traffic, but as near as I can tell, no agents are equipped to use that profile at this time.
I saved my configuration and hit the
Start Profile button. After a moment, an output log popped up, confirming the action, and the Profile panel reflected the new status.
Mythic supports a variety of agents, each of which has its own set of capabilities and support for OSes and communications channels. As a result, it’s important to read the documentation for a given agent carefully to ensure that the agent will be able to support the specific operations it’s going to be used for.
Clicking the biohazard icon in the button bar at the top of the page brings up the payloads page.
I clicked the
Actions dropdown and picked
Generate New Payload from the menu.
I selected Linux for my target operating system. Selecting the target OS will limit which agent types are selectable on the next screen.
Having selected a Linux agent, my options for agents were Medusa and Poseidon. I chose Medusa, and got the build parameters. Medusa supports producing agents as regular scripts or base64-encoded blobs. It also gives options for producing agents compatible with either Python 2.7 or 3.8, choosing the cryptography implementation (manual or the
cryptography library), and whether to encode and encrypt the agent code. I chose to go with the defaults.
Some agent types allow the operator to configure what commands are built into an agent. This can be used to manage the size of the payload, and to ensure certain commands aren’t available to run. Medusa requires the operator to affirmatively specify what commands to build in. I elected to build all commands into my agent.
On the next page, I selected the http C2 profile (the only one available), and set the callback host to
http://cdn.ravenrockgifts.com, after creating an A record for that host with my DNS provider. Other options here include setting a kill date for the agent, the URIs and parameters for POST and GET requests, and the callback port.
On the final agent creation page, I can set the filename and a description for the agent and approve its creation.
Pretty quickly, a popup appeared telling me the agent was ready for download, and it appeared on the payloads page.
Clicking on the information icon on the right calls up the configuration of the payload, including the list of embedded commands.
When working with an active agent, the same information can be accessed through the agent’s dropdown menu, under the
View Metadata option.
For testing purposes, I downloaded the agent to the machine I was operating from and ran
python3 medusa.py, and almost immediately got a callback. Clicking the keyboard icon allowed me to interact with the beacon.
I also created an Apollo agent which I ran on a workstation in my test lab.
Apollo, Medusa and Poseidon illustrate the divergence of capabilities across Mythic agents. Apollo is a C#-based agent which only runs on Windows, with built-in process migration commands, mimikatz, and assembly execution, among other features. Python-based Medusa runs on Windows, Linux and MacOS, but is missing Windows-specific features, although it includes the ability to execute arbitrary Python code. Poseidon is written in Go, targets Linux and MacOS, and has some MacOS specific features, such as
In terms of C2 channels, all of them support the http(s) C2 profile, while only Apollo supports SMB C2 for communications inside an environment. Poseidon has its own TCP-based in-environment C2 communications profile, as well as supporting websockets.
Mythic has C2 channels that support linking beacons together, building a chain of beacons deep into a network that all connect out through one beacon that has HTTP access back to the C2 server. A beacon needs to be built with a peer-to-peer C2 channel and then linked to a beacon that has either direct, or chained C2 server access using the
link command. The SMB channel is the most common, although the Poseidon and Freyja beacons have their own custom TCP P2P channels.
link command will bring up a dialog window allowing the operator to either select a known host that has been previously linked to, or define a new host.
Linked agents will show up with a chain-link icon under the C2 type. They may also have unusually high last checkin times, as they appear to not register a checkin unless they’ve been sent a command or have data to return.
Some Mythic agents support creating SOCKS5 proxies to allow an operator to proxy traffic from their testing host into the target network. Both the Apollo and Medusa agents support SOCKS5 proxies, and the new .NET 6-based Athena agent is listed as having beta support for proxies.
An operator can start a proxy using the command
socks [port]. The given port must be in the range specified in the Mythic configuration file’s
MYTHIC_SERVER_DYNAMIC_PORTS variable, which defaults to 7000-7010. At this time, Mythic only supports using TCP over its SOCKS5 proxies; UDP communications are not supported.
Once an operator has created a proxy, clicking on the socks icon at the top of the screen will bring up the SOCKS tab, showing all active proxies, the ports they’re running on and the agents they’re running through.
With my Mythic server running on a different host than the one I’m sitting at, I need to add a port forward to my ssh connection to make the proxy accessible to my tools. I can do this either when I start the connection by adding
-L 127.0.0.1:7000:127.0.0.1:7000 to the end of my ssh command line, or by using an ssh control sequence to add it to an existing session by doing the following:
ssh> -L 127.0.0.1:7000:127.0.0.1:7000
~C doesn’t appear in my terminal, but the prompt changes to
ssh> letting me know I’m now giving commands directly to SSH, and I can add my port forward just as if I were doing it when I started the client.
Now, with a proxy and a local port forward in place, I can proxy tools like Certipy through the agent.
I’ll note that launching a SOCKS5 proxy will not change the check-in interval on the agent, so if commands being executed through an agent seem to be taking an exceptionally long time to run, setting that agent to an interactive mode (
sleep 0) will speed things up.
That’s the basics of installing and using Mythic. It’s one of the more customizable C2s out there, both in terms of the different agents and the ways individual agents can be tailored for a given task. Stand up a server, give it a spin, then head over to our Discord to share your thoughts.
Justin Palk has more than 16 years of experience in IT and information security, and has worked in the academic, federal civilian government and health research sectors. He has held a variety of roles including system administrator, developer, auditor, assessment team lead and web application penetration tester. He regularly competes in CTFs in the U.S. and Europe.
GCIH, GWAPT, GPEN, GMOB, GDSA
Related StoriesView More
By Red Siege | March 4, 2024
By Alex Reid, Current Red Siege Intern A long-time tactic of threat actors and offensive security professionals alike, tampering with LSASS.exe in order to recover credentials remains a highly […]Learn More
By Red Siege | February 15, 2024
By: Justin Palk, Senior Security Consultant SSH is an incredibly valuable tool for penetration testing. It provides us with a secure channel for administering machines, remotely executing tools, transferring […]Learn More
By Red Siege | January 22, 2024
By: Alex Reid, Current Red Siege Intern Introduction This blog post accompanies the release of an open source tool called GraphStrike which can be found here. Those familiar with my […]Learn More