Part 1: Creating Mythic C2 Agent
Mythic landscape, motivations, and overview
Intro
This is a development blog series that goes along with my experience in creating a Mythic C2 agent written in C. This is not supposed to be a step-by-step tutorial, but rather a written log of what I’ve learned. I will include code snippets for the sake of reinforcing what I’ve learned along the way.
I hope this can be of help to anyone looking into creating their own agent.
Why
I decided to start my own C2 agent for a variety of reasons, here are a few:
- The main reason: To improve my development skills in C and low-level memory management concepts.
- More thoroughly understand the architecture of C2 agents in general.
- And because I was surprised I couldn’t find any open-source Mythic agents written in C (before @silentwarble released Hannibal).
Objectives
Many people that write custom C2 agents never open-source them to try and stay ahead of the cat-and-mouse game that is evasion. This being my first custom agent, I have no issue open-sourcing it since its not even close to opsec-safe already.
This project had a few objectives which included learning and implementing the following:
- Keep the agent memory-safe and avoid crashing like the plague
- Optional command inclusion to reduce binary size
- Traffic flexibility with malleable C2 profiles similar to Cobalt Strike
- Open-source the project to take input from the community
Mythic
Now that we got that out of the way we can talk about Mythic. I will try to give a high-level overview of what the Mythic framework is and how it works, or at least what you need to know to start developing a custom agent.
If you are not familiar, Mythic is a Command and Control framework, but it is not like many other C2 frameworks. Almost everything in Mythic is modular and modifiable. All of the components are separated into Docker containers including: server, logging, transport profiles, and yes… the agents.
This makes it a good choice if you want to hop in and start developing a C2 agent but don’t want to worry about creating or maintaining a backend/frontend server.
However, this does mean that you have to learn how the payload containers speak to the rest of the framework.
The development process was a bit confusing at first, but I started to understand everything (or at least what I needed to) after a few days of playing around. Luckily, the developer @its_a_feature_ maintains very good documentation which helped me figure out most of it.

I began by reading through the source code of different agents on the official Mythic Agents GitHub page. This gave me a pretty good starting place and got me familiar with the Payload Container format. Also I read through the ExampleContainers repository which outlined the file format.
Starting Out
There is one really important thing I had to decide before I could do anything… pick a cool edgy name for the project.
“Xenon?”
“Yeah, nice.”
Ok, moving on now…
Development Environment
The development environment I setup consisted of a Linux host running the Mythic server from /home/mythic/Mythic
and then my project folder at /home/mythic/Xenon
. Each time changes are made to any Python or container files, I would reinstall the project from the directory.
mythic@teamserver-mythic:~/Mythic$ sudo ./mythic-cli install folder ../Xenon/
This was kind of annoying, but if you are just modifying the agent code you probably don’t have to reinstall from the folder each time.
If you have a better way to setup your dev environment, please let me know.
Structure
I created a C project structure under Xenon/Payload_Type/xenon/xenon/agent_code
. I chose mingw-w64 as the compiler since I was most familiar with it and I would be cross-compiling targeting Windows (assuming Mythic server is running on Linux).
agent_code
├── Include
│ └── Xenon.h
├── Makefile
└── Src
└── Xenon.c
This is where the actual agent code is compiled from inside of the Payload Container.
Builder Dot Pie🥧
The builder.py
is a very important file that is located at Xenon/Payload_Type/xenon/xenon/mythic/agent_functions/builder.py
.
It is called every time an operator goes through the Generate New Payload dialog.
It handles the parsing of the selected build settings, compilation of the agent, frontend updates, and build logging. It defines a class XenonAgent
which describes some metadata for the Xenon agent and contains an asynchronous build
function.
If no errors are encountered, then the compiled executable will become available for download in the Mythic UI.

With that working I moved onto the real development.