Mythic functions are using docker containers. The Payload_Type/mypayload/Dockerfile file is used to define the docker container the payload builder will use. There are docker base images already available which include dependencies for building different types of payloads but a custom one can be defined, which was needed in this case to install all the dependencies for Nim. This docker container is used for building the payload; other functions such as C2 communication are handled in profile containers.
The Payload_Type/mypayload/mythic/agent_functions/builder.py file includes metadata about the payload along with the implementation for building each payload. The Mythic documentation for this file includes a very in-depth guide on what to include in this file in order to define your agent in Mythic along with how to compile build parameters into the payload.
One can think of payload type development as containing “payload” code and “mythic” code. The payload code is the code for the agent itself and lives in the Payload_Type/mypayload/agent_code/ directory. The actual development of the agent and its features occur here. The other part of the agent is the mythic code which is in the Payload_Type/mypayload/mythic/agent_functions/ directory. Here is where various commands are defined for the agent. This will define the commands and their parameters along with any other pre-tasking before sending it down to the agent.
HTTP is a very common C2 communication transport and is one of the easiest to implement. Mythic already includes an HTTP C2 profile which can be used with an agent for C2 communications. This is a fairly straight forward profile which uses HTTP GET/POST requests and base64-encoded JSON data. The initial check-in for an agent consists of an HTTP request including several data fields which the mythic server uses to identify the agent respectively the system the agent runs on.
Each agent has a unique PayloadUUID that is generated at compile time. An HTTP POST request with this in the body of the request will register an initial check-in with Mythic in the callbacks page. Encryption can be included in the request payload by following the format specified in the documentation.
From here, an agent is periodically beaconing back to the Mythic server to get tasking and sending the results of completed tasking back.
That is all that’s needed for building a basic Mythic payload. Creating more advanced commands can be found through the Mythic documentation. The example does not go into depth about all of the other great capabilities included with Mythic. A good source of possibilities are the already existing agents. Mythic also supports a structure for peer-to-peer communications between agents. An agent can communicate with other agents directly in order to pass on tasking. The Apollo and Poseidon agents support p2p functionality through SMB and/or TCP.
Why Nim?
One of the greatest advantages Nim offers is that it’s a compiled, statically typed language with syntax that feels like a scripting language. Much of the syntax exactly matches or is very similar to Python’s. This was a huge advantage as many little tools that were developed for internal use are based on Python.
Additionally, since Nim is an ahead-of-time compiled language, it’s probably a more sensible choice for developing C2 implants or other post-exploitation tools than Python would be. While it is possible to compile Python code to an executable using tools like PyInstaller or Py2Exe, those tools seem to have problems with setting off antivirus programs and using them introduces one more step into the development process.
Here’s a quick overview of a few other features that make Nim promising:
- Cross-compilation support with mingw-64. Languages like Go, which was analyzed in another personal research project, highlight how helpful seamless cross-compilation is for offensive tool development. Being able to compile agents for Windows as well as for Linux clients brings more flexibility.
- The binaries Nim emits are fairly small, in comparison to binaries emitted by Go, which is crucial for initial deployment of the agent.
- Nim offers support for calling backend code like the Windows API using its Foreign Function Interface. This seems like a particularly promising feature for anyone interested in developing post-exploitation tools for Windows in Nim.
- The documentation is very detailed and there are a lot of tutorials to get starting.
Nimpostor Functions
To get a feeling which functions are essential, other agents from the MythicAgents github were analyzed. Especially the Apollo, Medusa and Poseidon agents are very advanced and have a great overview of functions. Furthermore, the code snippets from the OffensiveNim repository gave some more inspiration.
Currently the proof-of-concept payload is very basic and doesn’t have advanced capabilities implemented. It focuses on simple file system tasks like cd, ls, download, upload and the more advanced execute_assembly function that allows for execution of .NET files directly in memory.
Conclusion
The main goal of this research was to get to know the language Nim and see if it is suitable for internal tool development. This can be confirmed 100% and the topics mentioned in “Why Nim?” make it the new favorite for inhouse tooling for red teaming projects.
Although the agent is in what you could call a beta stage at the moment, it will definitely be developed further, so that it can be used in future Red Team projects.
The very next steps to be included are a bof_loader to be able to execute Beacon Object Files directly in memory, a socks proxy and the p2p functionality for inter-agent communication via SMB or TCP.
If you want to have a look at the code and test the agent yourself, you can do so at the SEC Consult Github Page.
This blogpost was written by Lukas Donaubauer and published on behalf of the SEC Consult Vulnerability Lab.