Thanatos: Installation and Usage

This is part two of a series of blog posts on Thanatos, a Mythic C2 agent written in Rust. This post will go over setting up Mythic and Thanatos in an Ubuntu VM and the agent’s usage.

Part one of the series discusses how this project came about and the development of it.

Project repository: https://github.com/MythicAgents/thanatos

Overview

Thanatos Features and Functionality

If you’re new to Mythic, I highly recommend checking out the Mythic Documentation. Mythic is very unique compared to other C2 frameworks due to its modular design. Other frameworks such as Cobalt Strike or Empire include a full suite of modules including: C2 profiles/transports, stagers, payloads a UI, etc. Mythic decides to take these common features of a C2 framework and split them up into three distinct server, C2 profiles and payload types modules. Due to this design, payloads can vary from compiled .NET Windows executables to chrome web browser extensions. C2 profiles give the operator and developers flexibility on how their payloads communicate with Mythic. This allows a very high level of flexibility to tune the operation based on what the target is. The currently public C2 profiles are HTTP, DNS and websocket but profiles can be developed which utilize AWS S3 buckets, Microsoft Teams, Dropbox or various other mediums for communication.

It’s important to note this modular aspect when using Mythic since it provides a somewhat unique experience when performing red team operations.

Installing Mythic with Thanatos

Setting up a machine with Mythic and installing Thanatos is very straight forward thanks to Mythic’s use of Docker containers. Along the that, there is a convenient mythic-cli program which can be used instead of manually setting up and running all of the images.

The first thing to do is setup Linux machine and install docker. For this example I will be using Ubuntu 20.04 in a virtual machine.

Be sure you allocate enough resources to your machine. I will be using a virtual machine with 20GB of hard drive space, 8GB of ram and 2 vCPUs.

After Linux is setup, docker and docker-compose need to be installed.

1sudo apt update
2sudo apt install docker.io docker-compose

Ensure the docker daemon has been started and set to start on boot

1sudo systemctl enable --now docker

Next, clone the Mythic repository from Github. This can be cloned to anywhere on the machine.

1git clone https://github.com/its-a-feature/Mythic.git --depth 1

The --depth 1 is optional but it makes the download significantly faster.

 1ubuntu@mythic-server:~$ git clone https://github.com/its-a-feature/Mythic.git --depth 1
 2Cloning into 'Mythic'...
 3remote: Enumerating objects: 2245, done.
 4remote: Counting objects: 100% (2245/2245), done.
 5remote: Compressing objects: 100% (1983/1983), done.
 6remote: Total 2245 (delta 276), reused 2112 (delta 231), pack-reused 0
 7Receiving objects: 100% (2245/2245), 24.81 MiB | 17.27 MiB/s, done.
 8Resolving deltas: 100% (276/276), done.
 9ubuntu@mythic-server:~$ cd Mythic/
10ubuntu@mythic-server:~/Mythic$ ls
11C2_Profiles           Example_Payload_Type      install_docker_kali.sh    mythic-docker        postgres-docker  SECURITY.md
12docker-compose.yml    Example_Translator        install_docker_ubuntu.sh  mythic-react-docker  rabbitmq-docker  VERSION
13documentation-docker  hasura-docker             LICENSE                   nginx-docker         README.md
14Example_C2_Profile    install_docker_debian.sh  mythic-cli                Payload_Types        redis-docker
15ubuntu@mythic-server:~/Mythic$

The newly cloned Mythic repo contains a mythic-cli program. This program is used for managing the framework.

Configuring the server is done through a .env file located in the Mythic directory. To generate this configuration file run ./mythic-cli config

 1ubuntu@mythic-server:~/Mythic$ ./mythic-cli config
 2ALLOWED_IP_BLOCKS = 0.0.0.0/0
 3COMPOSE_PROJECT_NAME = mythic
 4DEFAULT_OPERATION_NAME = Operation Chimera
 5DOCUMENTATION_BIND_LOCALHOST_ONLY = true
 6DOCUMENTATION_HOST = mythic_documentation
 7DOCUMENTATION_PORT = 8090
 8EXCLUDED_C2_PROFILES =
 9EXCLUDED_PAYLOAD_TYPES =
10HASURA_BIND_LOCALHOST_ONLY = true
11HASURA_HOST = mythic_graphql
12HASURA_PORT = 8080
13HASURA_SECRET = bWeMjZIlXjbl54NWlW0GoHv2FJOnhH
14JWT_SECRET = ZxkLIpPB5HbH8LNU3kvTpkxS6epnPU
15MYTHIC_ADMIN_PASSWORD = 2Kszg9c5fRUDapU1TF9UxNzpfn16HA
16MYTHIC_ADMIN_USER = mythic_admin
17MYTHIC_DEBUG = false
18MYTHIC_ENVIRONMENT = production
19MYTHIC_REACT_BIND_LOCALHOST_ONLY = true
20MYTHIC_REACT_HOST = mythic_react
21MYTHIC_REACT_PORT = 3000
22MYTHIC_SERVER_BIND_LOCALHOST_ONLY = true
23MYTHIC_SERVER_DYNAMIC_PORTS = 7000-7010
24MYTHIC_SERVER_HOST = mythic_server
25MYTHIC_SERVER_PORT = 17443
26NGINX_BIND_LOCALHOST_ONLY = false
27NGINX_HOST = mythic_nginx
28NGINX_PORT = 7443
29NGINX_USE_SSL = true
30POSTGRES_BIND_LOCALHOST_ONLY = true
31POSTGRES_DB = mythic_db
32POSTGRES_HOST = mythic_postgres
33POSTGRES_PASSWORD = zhqoomxZd3BsI1x5tcAnLTosiJjBRG
34POSTGRES_PORT = 5432
35POSTGRES_USER = mythic_user
36RABBITMQ_BIND_LOCALHOST_ONLY = true
37RABBITMQ_HOST = mythic_rabbitmq
38RABBITMQ_PASSWORD = bIoU2A9M5vZTZ8LopdYpik2pktMDiJ
39RABBITMQ_PORT = 5672
40RABBITMQ_USER = mythic_user
41RABBITMQ_VHOST = mythic_vhost
42REBUILD_ON_START = true
43REDIS_BIND_LOCALHOST_ONLY = true
44REDIS_HOST = mythic_redis
45REDIS_PORT = 6379
46SERVER_HEADER = nginx 1.2
47SIEM_LOG_NAME =
48WEB_KEEP_LOGS = false
49WEB_LOG_SIZE = 1024000
50ubuntu@mythic-server:~/Mythic$

The defaults can be kept the same; however, I am going to set a different admin password.

1MYTHIC_ADMIN_PASSWORD="TestingPassword123!@#"

Since this is a test VM for a demo only reachable from my host machine, I am okay with using the default Mythic admin user and an insecure password.

After that’s done, it’s time to install the Thanatos payload and HTTP C2 profile.

1sudo ./mythic-cli install github https://github.com/MythicAgents/thanatos
2sudo ./mythic-cli install github https://github.com/MythicC2Profiles/http

Mythic can now be started

1sudo ./mythic-cli mythic start

This can take a fair bit of time depending on your network connection. Mythic has to download all of the docker images for the server along with the docker images for the HTTP profile and Thanatos.

1real    3m4.578s
2user    0m2.149s
3sys     0m0.422s

If everything went well, Mythic should be reachable at https://<IP address>:7443/ using a web browser.

To make sure everything was set up correctly, log in using the password you set. The username is mythic_admin unless you changed it during the configuration. Navigate to the C2 Profiles and Paylod Types page by clicking on the headphones icon in the top left corner.

Thanatos should be listed under the Payload Types and http under the C2 Profiles with a green status icon.

c2_and_payload_types.png

Note: “tetanus” was the old name for the Mythic agent. This is why the payload types entry has an agent named tetanus instead of thanatos.

Building the Agent

The build page can be reached by clicking on the Payloads icon on the top left of the web page next to the C2 Profiles and Payload Types icon. In the drop down Actions menu in the top left, click the Generate New Payload button.

This menu will prompt you to select the target OS. Thanatos only supports targeting Windows or Linux. After the target OS is selected, the build parameters configuration will be available.

payload_build_parameters.png

  1. The first build parameter is an option to configure how the agent should run. If this options is set and the payload is built for Windows, the agent will hide the console window when it is executed. For Linux, this option controls whether the agent should run in the foreground or fork and run in the background.

  2. The second build parameter controls how many attempts the agent should make for the initial check in. If the agent fails to establish a connection when it is executed, it will sleep for the configured interval and try to establish another connection. The retries determine how many attempts the agent should make before it will stop. More information about it can be found in the Mythic documentation.

  3. The third parameter configures the output format for the payload file. Thanatos can be built as a standalone executable, a shared library, or raw shellcode for Windows. The shared library option will build a Windows DLL when targeting Windows and an ELF shared object when targeting Linux. The raw shellcode for Windows can be used for injecting the payload through various injection techniques or for developing obfuscation wrappers. Picking the shellcode option when targeting Linux will result in the build failing!

  4. The fourth parameter controls static linking for Linux payloads. Statically linking the payload will make the executable size larger; however, it will help ensure it can run on all Linux platforms. This is recommended if trying to spawn the agent on a host using a non glibc libc or on older Linux systems. This option has no effect when building payloads for Windows.

  5. The fifth parameter is the payload architecture. The payload can be built to target both 32 and 64 bit x86 systems.

  6. The sixth parameter is the working hours. The working hours mean that the agent will only make connections to Mythic during the configured time frame. This also includes the initial check in. If the agent was executed when not in the configured working hours period, it will not check in until the start of the working hours the next day. This option can be changed during operation of the agent using the workinghours command. The format for the working hours is HH:MM-HH:MM using 24 hour format. When operating, the agent will use the targeted system’s locally set time zone. Time zone calculations may be needed in order to compensate for time differences.

After the build parameters are set, the next menu will allow you to configure what commands to build into the agent. The agent does not support dynamic compilation of features so all commands are included.

The C2 profiles page only gives an option for HTTP. There are plans to include different C2 profiles in the future.

c2_profile_parameters.png

c2_profile_parameters2.png

  • Callback Host

    • Hostname or IP to connect to when beaconing back to Mythic.
  • Callback Interval in seconds

    • Sleep interval for the agent in seconds. This can be changed while interacting with the agent using the sleep command.
  • Callback Jitter in percent

    • Jitter to apply for the agent’s sleep interval. The agent will pick a random percentage value between 0 and the configured jitter during each sleep time. The jitter is randomly added or subtracted from the configured sleep interval during the sleep time. If the sleep interval is set for 30 seconds and the jitter value is 50%, the agent will choose a random sleep time between 15 to 45 seconds. This value can be changed during operation using the sleep command.
  • Callback Port

    • Listening port of the server for http requests.
  • Crypto type

    • Choose whether the C2 traffic should be AES256 encrypted or if there should be no encryption.
  • GET request URI

    • The URI for performing GET requests.
  • HTTP Headers

    • Addition HTTP headers for the agent.
  • Kill Date

    • Kill date of the agent
  • Query Path Name

    • Name of the query parameter for GET requests
  • Perform Key Exchange

    • Configure whether or not the agent should perform a key exchange during the initial check in.
  • Proxy Information

    • Connecting to socks proxies from the agent to Mythic is currently unimplemented so these proxy parameters can be left blank

Once the C2 profile information is set, the next page will allow you to name the payload along with setting a description for it. The description for the payload will be the initial description in the C2 callbacks page.

Once the payload creation has kicked off, it can take around 15 seconds to a few minutes for the agent to build depending on VM resources. Thanatos will do dependency caching after the initial build depending on target OS, architecture and static linking. For example, an initial x64 Windows agent build will take the pre-built dependencies and cache them. Future builds targeting Windows x64 will take significantly less time as compared to the initial build because the dependencies from the initial build are used.

The payload builder works this way to keep the initial size of the docker image smaller while also shortening consecutive build times. Not every operation is going to need the pre-build dependencies targeting 32 bit Linux; therefore, those pre-built dependencies are not going to take up unnecessary disk space.

Using the Agent

The basic agent operations are very similar to any other Mythic payload. Thanatos has a few features which are slightly different than other Mythic payloads.

During initial check in for Linux hosts, Thanatos will query information about the Linux kernel version and whether or not the agent is on an SELinux system. That information can be found by clicking on the Linux icon under the OS section in the callback page.

linux_icon.png linux_checkin_output.png

Here is an example of what it will show. The kernel version of the system this payload is running on is 5.16.12-200.fc35.x86_64 and it does have SELinux capabilities.

The interact row can be used to interact with the agent. The dropdown menu provides various quick interactions. Clicking on the keyboard icon will pull up the command window at the bottom of the screen.

agent_interaction.png

task_an_agent.png

Issuing help in the command window will show a list of all the available commands and a brief description about them. More information about the available commands can be found in the Mythic documentation.

The Mythic documentation can be reached by clicking on the question mark in the top right corner and clicking on Agent Documentation. This page is where Mythic will store the documentation about payload types and C2 profiles. The left side of the web page will have a list of all the installed agents. Clicking on Thanatos will pull up the documentation for the Thanatos payload. Clicking on the Commands menu on the left side of the web page will bring up a list of all the commands Thanatos supports. Clicking on the command will take you to that command’s documentation.

Issuing tasking can be done using the Mythic popup UI or through named parameter flags. The Mythic popup UI can be displayed by typing the command in the task Window and pressing Shift + Enter. Commands and their parameters can also be issued directly through the tasking prompt using named parameters or inline with the command.

shell_command_named.png

shell_command_inline.png

Not every command supports entering arguments directly in the task prompt. Every command does support the Mythic UI popup by pressing Shift + Enter after typing the command in the tasking prompt. For more information about command parameter formats, refer to the documentation for the command in the Mythic documentation.

Some commands support browser scripts. Browser scripts in Mythic allow more refined ways of formatting the task output along with potentially issuing other tasking through the browser script.

ls_command_browserscript.png

In the ls example, the browser script allows for new tasking to be issued by clicking on any of the tasking buttons. More browser script support is planned for the future since it makes issuing more tasks very convenient.

Unique Capabilities

Thanatos features a few capabilities which other agents do not have. Starting with building the agent, Thanatos allows the operator a lot of flexibility on choosing how to build the agent. This flexibility includes controlling the output format, target architecture, static linking and even whether or not the agent should daemonize. The operator can also choose configuration for the C2 communications such as how many times the agent should attempt to check in if the initial check in fails and what time throughout the day the agent should make check ins to the C2.

Going into the operation of the agent, Thanatos currently has two distinct features that are somewhat unique. The first being its SSH capabilities. The agent uses the ssh2 library in order to make SSH connections. The agent features a whole suite of commands which can all be executed over SSH. These include executing shell commands, downloading and uploading files between the SSH connected machine and Mythic, displaying the contents of files, grabbing directory listings and removing files. Typing ssh into the tasking prompt for a callback and pressing Shift + Enter will display the capabilities and parameters.

ssh_popup.png

The dropdown menu for the parameter group can be selected to choose what action you would like to perform over ssh.

ssh_dropdown.png

All of the actions are documented in the Mythic documentation but I would like to highlight the List action.

The first parameter for each ssh function is to select what credentials to use. The agent will pull these credentials from the Mythic credential database. When creating a new credential for ssh, the plaintext credential type means that the supplied credential is a plain text username and password combination. A credential type of key signifies that the supplied credential is an SSH private key. The only options in the Mythic credential which need to be populated are the Account Name for the username of the account to log in as for SSH and the Credential which is either the plain text password for the user or an SSH private key.

Once the credential is selected, the use ssh agent option can be set to false. This tells Thanatos whether it should use running ssh agents on the system for authentication instead of through the Mythic credential. More information about that can be found in the documentation for the ssh-agent command.

I have another Linux machine located at 192.168.122.56 where I know the username and password for a user on that machine.

ssh_filled.png

Once I submit the task, the agent will attempt to connect to that machine through SSH with the ubuntu user and grab a directory listing of the root directory.

ssh_browserscript.png

The SSH command features a browser script which will pull the time metadata and permissions for each entry similar to the regular ls browser script. Along with that, the browser script features the same context menus as the normal ls command. Through the browser script, the operator can issue new SSH tasking to list different subdirectories or perform other actions.

ssh_contextmenu.png

Tasking issued through the browser script will use the same credentials and host information for the new task so the new task will be queued automatically without having to manually fill out the task parameters.

This provides a very convenient way to interact with other machines through SSH without having to spawn a payload on the machine.


The second notable feature is the ability to stand up TCP redirectors through the redirect command. The agent will listen for connections on a machine and relay them to another machine. This is very useful when dealing with machines that do not have direct Internet access. A redirector can be created which will redirect traffic from the machine to a server on the Internet.

The redirect capability can also bring p2p-like functionality to other agents which do not support peer-to-peer connections. The Mythic documentation for the redirect command gives an example of using the redirector to tunnel C2 traffic through the agent. This idea can also be translated to other tools and C2 agents. Empire and meterpreter can be tunneled through Thanatos to give it p2p functionality.

Since setting up redirectors requires binding to a port on the machine, it is not very OPSEC safe and may not be practical in restricted environments. This functionality was designed for lab environments which require a lot of pivoting and lateral movement. I have found when going through various red team labs that there are machines which cannot directly connect to my machine. This can make pivoting a little cumbersome by having to use something like chisel or SSH port forwarding in order to gain access to that machine. Having a tool which contains port forwarding capabilities built in (and eventually socks proxying) makes it more convenient when trying to pivot to other machines since I do not have to upload chisel binaries or rely on the pivot machine having SSH available.

Future Improvements

Future development plans and agent features are mentioned in part one of the blog post series.