Mythic Documentation
Version 2.3
Version 2.3
  • Mythic
  • Operators
  • Installation
    • Connecting
    • A note about containers
    • Offline Installation
    • Updating Mythic
  • Internal Documentation
  • Quick Usage
  • Operational Pieces
    • MITRE ATT&CK
    • Operations
    • Browser Scripts
    • Active Callbacks
    • Files
    • Search
    • File Browser
    • Socks Proxy
    • Credentials
    • Comments
    • Tags
    • Expanded Callbacks
    • Screenshots
    • Event Feed
    • API Tokens
  • Message Flow
    • Building Payloads
    • Agent Sends Message
    • File Upload Mythic->Agent
    • File Download Agent->Mythic
    • P2P Messages
    • Operator Submits Tasking
  • Database Schema
  • Understanding Commands
    • Basic Information
    • Parameters
    • MITRE ATT&CK in Commands
  • Payload Types
    • Configuration
    • Containers
  • C2 Profiles
    • C2 Server Utilities
    • Egress vs P2P
    • HTTP
    • dynamicHTTP
    • Save Parameters
  • Reporting
    • Artifacts
    • MITRE ATT&CK
    • Reports
  • Scripting
  • Presentations / Webinars
  • Common Errors
  • Customizing
    • Hooking Features
      • Actions
      • Linking Agents
      • P2P Connections
      • Process_List
      • Artifacts
      • Credentials
      • File Downloads (Agent -> Mythic)
      • File Uploads (Mythic -> Agent)
      • Screenshots
      • Commands
      • Keylog
      • File Browser
      • Tokens
      • Task Status
    • Payload Type Development
      • Translation Containers
      • First Steps
      • Container Syncing
      • Payload Type Info
      • Commands
      • Browser Scripting
      • Dynamic Parameter Values
      • Create_Tasking
      • MythicRPC
      • OPSEC Checking
      • Sub-tasking / Task Callbacks
      • Process Response
      • SOCKS
      • Reverse PortFwd
      • Adding Commands
    • C2 Related Development
      • C2 Profile Code
        • Agent Side Coding
          • Delegates (p2p)
          • Agent Message Format
          • Action: Checkin
          • Action: get_tasking
          • Action: post_response
          • SOCKS
          • RPFWD
        • Server Side Coding
          • OPSEC Checks For C2 Profiles
          • Configuration Checks
          • Redirect Rules
          • C2 Docker Containers
          • C2 Configuration Files
    • Mythic UI Development
  • Common Questions and Answers
    • FAQ / Troubleshooting Tips
    • Change Log
    • Next Release
    • Tip of the Week
  • Updating
    • Mythic 2.1 -> 2.2 Updates
      • Agents 2.1.* -> 2.2.8
        • MythicRPC
    • Mythic 2.2 -> 2.3 Updates
      • Agents 2.2 -> 2.3
    • Mythic 2.3 -> 3.0 Updates
      • Agents 2.3 -> 3.0
Powered by GitBook
On this page
  • What are dynamic parameters?
  • Where are dynamic parameters?
  • Accessible Info from Dynamic Function

Was this helpful?

Export as PDF
  1. Customizing
  2. Payload Type Development

Dynamic Parameter Values

What are dynamic parameters?

Sometimes when creating a command, the options you present to the operator might not always be static. For example, you might want to present them with a list of files that have been download; you might want to show a list of processes to choose from for injection; you might want to reach out to a remote service and display output from there. In all of these scenarios, the parameter choices for a user might change. Mythic can now support this.

Where are dynamic parameters?

Since we're talking about a command's arguments, all of this lives in your Command's class that subclasses TaskArguments. Let's take an augmented shell example:

class ShellArguments(TaskArguments):
    def __init__(self, command_line):
        super().__init__(command_line)
        self.args = {
            "command": CommandParameter(
                name="command", type=ParameterType.String, description="Command to run"
            ),
            "files": CommandParameter(name="files", type=ParameterType.ChooseOne, default_value=[],
                                      dynamic_query_function=self.get_files)
        }

    async def get_files(self, inputMsg: PTRPCDynamicQueryFunctionMessage) -> PTRPCDynamicQueryFunctionMessageResponse:
        fileResponse = PTRPCDynamicQueryFunctionMessageResponse(Success=False)
        file_resp = await SendMythicRPCFileSearch(MythicRPCFileSearchMessage(
            CallbackID=inputMsg.Callback,
            LimitByCallback=False,
            Filename="",
        ))
        if file_resp.Success:
            file_names = []
            for f in file_resp.Files:
                if f.Filename not in file_names and f.Filename.endswith(".exe"):
                    file_names.append(f.Filename)
            fileResponse.Success = True
            fileResponse.Choices = file_names
            return fileResponse
        else:
            fileResponse.Error = file_resp.Error
            return fileResponse

    async def parse_arguments(self):
        if len(self.command_line) > 0:
            if self.command_line[0] == "{":
                self.load_args_from_json_string(self.command_line)
            else:
                self.add_arg("command", self.command_line)
        else:
            raise ValueError("Missing arguments")

Here we can see that the files CommandParameter has an extra component - dynamic_query_function. This parameter points to a function that also lives within the same class, get_files in this case. This function is a little different than the other functions in the Command file because it occurs before you even have a task - this is generating parameters for when a user does a popup in the user interface. As such, this function gets one parameter - a dictionary of information about the callback itself. It should return an array of strings that will be presented to the user.

Dynamic queries are only supported for the ChooseOne and ChooseMultiple CommandParameter types

You have access to a lot of the same RPC functionality here that you do in create_tasking, but except for one notable exception - you don't have a task yet, so you have to do things based on the callback_id. You won't be able to create/delete entries via RPC calls, but you can still do pretty much every query capability. In this example, we're doing a get_file query to pull all files that exist within the current callback and present their filenames to the user.

Accessible Info from Dynamic Function

What information do you have at your disposal during this dynamic function call? Not much, but enough to do some RPC calls depending on the information you need to complete this function. Specifically, the PTRPCDynamicQueryFunctionMessage parameter has the following fields:

  • command - name of the command

  • parameter_name - name of the parameter

  • payload_type - name of the payload type

  • callback - the ID of the callback used for RPC calls

PreviousBrowser ScriptingNextCreate_Tasking

Last updated 1 year ago

Was this helpful?