4. Extending Agent Commands

What is this?

Sometimes you want to use public agents, but you also have some internal-specific commands you'd like to use with the agent as well. You might also have a set of commands you want to use across a variety of agents, but don't want to have to create/maintain it for each agent. This is where the new "command_augment" container comes into play.

What does this mean?

When creating a Payload type there's an option to specify an "AgentType". Normally this defaults to "agent" and you have a normal Payload Type. You could also change this to "wrapper" and have a wrapper payload type. There's also a "service" type you can set so that Mythic's UI doesn't expect you to have any C2 associated with the profile, but instead you to interact with 3rd party services. This is one more kind of "AgentType" called "command_augment".

This works exactly the same as normal "agent" Payload Types except you don't actually build anything. Instead, the commands you register are "injected" into callbacks of other Payload Types. Naturally, these commands either need to be self contained (i.e. they set their completed status to true and never get sent down to the agent) or they need to eventually result in some other command getting executed (i.e. spawning subtasks or changing their CommandName in their create tasking function so that the agent executes a different function).

class Apfell(PayloadType):
    name = "Apfell"
    file_extension = "js"
    author = "@its_a_feature_"
    supported_os = [SupportedOS.MacOS]
    agent_type = AgentType.CommandAugment
    wrapper = False
    wrapped_payloads = []
    note = """This payload uses JavaScript for Automation (JXA) for execution on macOS boxes."""
    supports_dynamic_loading = True
    c2_profiles = ["http", "dynamichttp"]

You can choose to have your commands injected by one or both of the following options:

  • SupportedOs - the supported OS can be used as part of your command augment payload type definition to limit yourself to only certain operating systems

  • CommandAugmentSupportedAgents - you can provide a list of agent names here and only have your commands injected into callbacks based on these agents

If you provide both, then both must be true (i.e. OS must match and payload type name must match).

For every Command associated with this CommandAugment container, only the ones that have CommandParameters with builtin or suggested_command set to True are loaded automatically into the callback (assuming the above criteria are met). If you want to allow others to be loaded or not, you need to include your own load/unload commands within the CommandAugment container. If you're not actually adding new commands that need to be sent down to the agent for loading, but instead just need to make Mythic aware of new commands that can be issued, then you can use the MythicRPCCallbackAddCommand functionality to just let Mythic know.

What does this look like?

In the Callback metadata table, you can see these commands automatically injected:

You can also see them in the add/remove commands for callbacks:

You can see which specific backing container the command is associated with. There is currently no de-duplication of command names between what's part of the Payload Type itself and what you inject with CommandAugment containers. You can see above that there's two ls commands. When tab completing on the command line, you'll cycle through both of them, but there's currently no easy way to tell which is which. So, it's recommended that if you want to inject your own commands into a callback, that you do it in a way that makes it clear what your injected commands are for the operator.

Last updated