AESPSK
, and use that as the key to decrypt the message
checkin
process is to go from a payload (and thus payloadUUID) to a full callback (and thus callbackUUID), so at the end of staging and everything you’ll end up with a new UUID that you’ll use as the outer UUID.
crypto_type=True
. This will then signal to Mythic to either generate a new per-payload AES256_HMAC key or (if your agent is using a translation container) tell your agent’s translation container to generate a new key. In the http
profile for example, this is a ChooseOne
option between aes256_hmac
or none
. If you’re doing plaintext comms, then you need to set this value to none
when creating your payload. Mythic looks at that outer PayloadUUID
and checks if there’s an associated encryption key with it in the database. If there is, Mythic will automatically try to decrypt the rest of the message, which will fail. This checkin has the following format:
integrity_level
is an integer from 1-4 that indicates the integrity level of the callback. On Windows, these levels correspond to low integrity (1) , medium integrity (2), high integrity (3), or SYSTEM integrity (4). On Linux, these don’t have a great mapping, but you can think of (2) as a standard user, (3) as a user that’s in the sudoers file or is able to run sudo, and (4) as the root user.crypto_type=True
. This will then signal to Mythic to either generate a new per-payload AES256_HMAC key or (if your agent is using a translation container) tell your agent’s translation container to generate a new key. In the http
profile for example, this is a ChooseOne
option between aes256_hmac
or none
. The key passed down to your agent during build time will be the base64 encoded version of the 32Byte key.
The message sent will be of the form:
hfN9Nk29S8LsjrE9ffbT9KONue4uozk+/TVMyrxDvvM=
and message:
crypto_type=True
. This will then signal to Mythic to either generate a new per-payload AES256_HMAC key or (if your agent is using a translation container) tell your agent’s translation container to generate a new key. In the http
profile for example, this is a ChooseOne
option between aes256_hmac
or none
.
When it says “base64 of public RSA key” you can do one of two things:
hfN9Nk29S8LsjrE9ffbT9KONue4uozk+/TVMyrxDvvM=
:
session_key
value is encrypted with the public RSA key that was in the initial message and base64 encoded. The response also includes a new staging UUID for the agent to use. This is not the final UUID for the new callback, this is a temporary UUID to indicate that the next message will be encrypted with the new AES key.
The next message from the agent to Mythic is as follows:
translate_from_c2_format
function. That function gets a dictionary of information like the following:
enc_key
, dec_key
, and type
, Mythic uses the payloadUUID to then look up information about the payload. It uses the profile
associated with the message to look up the C2 Profile parameters and look for any parameter with a crypto_type
set to true
. Mythic pulls this information and forwards it all to your translate_from_c2_format
function.
Ok, so that message gets your payloadUUID/crypto information and forwards it to your translation container, but then what?
Normally, when the translate_to_c2_format
function is called, you just translate from your own custom format to the standard JSON dictionary format that Mythic uses. No big deal. However, we’re doing EKE here, so we need to do something a little different. Instead of sending back an action of checkin
, get_tasking
, post_response
, etc, we’re going to generate an action of staging_translation
.
Mythic is able to do staging and EKE because it can save temporary pieces of information between agent messages. Mythic allows you to do this too if you generate a response like the following:
action
- this must be “staging_translation”. This is what indicates to Mythic once the message comes back from the translate_from_c2_format
function that this message is part of staging.
session_id
- this is some random character string you generate so that we can differentiate between multiple instances of the same payload trying to go through the EKE process at the same time.
enc_key
/ dec_key
- this is the raw bytes of the encryption/decryption keys you want for the next message. The next time you get the translate_from_c2_format
message for this instance of the payload going through staging, THESE are the keys you’ll be provided.
crypto_type
- this is more for you than anything, but gives you insight into what the enc_key
and dec_key
are. For example, with the http
profile and the staging_rsa
, the crypto type is set to aes256_hmac
so that I know exactly what it is. If you’re handling multiple kinds of encryption or staging, this is a helpful way to make sure you’re able to keep track of everything.
next_uuid
- this is the next UUID that appears in front of your message (instead of the payloadUUID). This is how Mythic will be able to look up this staging information and provide it to you as part of the next translate_from_c2_format
function call.
message
- this is the actual raw bytes of the message you want to send back to your agent.
translate_from_c2_format
an actual checkin
message.
What if there’s other information you need/want to store though? There are three RPC endpoints you can hit that allow you to store arbitrary data as part of your build process, translation process, or custom c2 process:
create_agentstorage
- this take a unique_id string value and the raw bytes data value. The unique_id
is something that you need to generate, but since you’re in control of it, you can make sure it’s what you need. This returns a dictionary:
get_agentstorage
- this takes the unique_id string value and returns a dictionary of the stored item:
delete_agentstorage
- this takes the unique_id string value and removes the entry from the database