Overview
This profile uses HTTP Get and Post messages to communicate with the main Mythic server. Unlike the default HTTP though, this profile allows a lot of customization from both the client and server. There are two pieces to this as with most C2 profiles - Server side code and Agent side code. In general, the flow looks like:
Agent Configuration
From the UI perspective, there are only two parameters - a JSON configuration and the auto-populated operation specific AES key. For the JSON configuration, there is a generic structure:/<test:string>
. The meaning behind that format is explained in the HTTP for the server side configuration, but the point here to look at is the next piece - urlFunctions
urlFunctions - This describes transforms for modifying the URI of the request. In the above example, we replace the <test:string>
with a random selection from [“jquery-3.3.1.min.js”, “jquery-3.3.1.map”].
AgentHeaders - This defines the different headers that the agent will set when making requests
Note: if you’re doing domain fronting, this is where you’d set that value
QueryParameters - This defines the query parameters (if any) that will be sent with the request. When doing transforms and dynamic modifications, there is a standard format that’s described in the next section.
When doing query parameters, if you’re going to do anything base64 encoded, make sure it’s URL safe encoding. Specifically, /, +, =, and characters need to be URL encoded (i.e. with their %hexhex equivalents)
Transforms
The defining feature of the HTTP profile is being able to do transforms on the various elements of HTTP requests. What does this look like though?Server Configuration
Like with all C2 profiles, the HTTP profile has its own docker container that handles connections. The purpose of this container is to accept connections from HTTP agents, undo all of the special configurations you specified for your agent to get the real message back out, then forward that message to the actual Mythic server. Upon getting a response from Mythic, the container performs more transforms on the message and sends it back to the Agent. The docker container just abstracts all of the C2 features out from the actual Mythic server so that you’re free to customize and configure the C2 as much as you want without having to actually adjust anything in the main server. There is only ONE HTTP docker container per Mythic instance though, not one per operation. Because of this, the HTTP profile’s server-side configuration will have to do that multiplexing for you. Below is an example of the setup:
HTTP Comms from Agent to Server
URI formatting
When it comes to the URIs you choose to use for this, there’s an additional feature you can leverage. You can choose to keep them static (like /download.php) and specify/configure the query parameters/cookies/body, but you can also choose to register more dynamic URIs. There’s an example of this above:Specifically for urlFunctions, the “name” must match the thing that’ll be replaced. Unlike query parameters and cookie values where the name specifies the name for the value, the name here specifies which field is to be replaced with the result of the transforms
One last thing to note about this. You cannot have two URIs in a single instance within the GET or the POST that collide. For example, you can’t have two URIs that are /download.php but vary in query parameters. As far as the docker container’s service is concerned, the differentiation is between the URIs, not the query parameters, cookies, or body configuration. Now, in two different instances you can have overlapping URIs, but that’s because they are different web servers bound to different ports.
Special kinds of configuration
What if you want all of your messages to be “POST” requests or “GET” requests? Well, Apfell by default tries to do GET requests when getting tasking and POST requests for everything else; however, if there are no GET agent_message instances in that array (i.e.{"GET":{"AgentMessage":[]}}
) then the agent should use POST messages instead and vise versa. This allows you to have yet another layer of customization in your profiles.