Mythic Documentation
Version 3.3
Version 3.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
    • Understanding Commands
      • Basic Information
      • Parameters
      • MITRE ATT&CK in Commands
    • Payload Types
      • Containers
    • C2 Profiles
      • C2 Server Utilities
      • Egress vs P2P
      • HTTP
      • dynamicHTTP
      • Save Parameters
    • API Tokens
  • Message Flow
    • Building Payloads
    • Agent Sends Message
    • File Upload Mythic->Agent
    • File Download Agent->Mythic
    • P2P Messages
    • Operator Submits Tasking
  • Database Schema
  • Reporting
    • Artifacts
    • MITRE ATT&CK
    • Reports
  • Scripting
  • Presentations / Webinars
  • Common Errors
  • MythicTips
  • Customizing
    • Customizing Public Agent
    • Hooking Features
      • Actions
      • Linking Agents
        • P2P Connections
      • Process Browser
      • Artifacts
      • Credentials
      • File Downloads (Agent -> Mythic)
      • File Uploads (Mythic -> Agent)
      • Screenshots
      • Add / Remove Commands
      • Keylog
      • File Browser
      • Tokens
      • Alerts
      • SOCKS
      • RPFWD
      • Interactive Tasking
      • Task Status
      • OnContainerStart
    • 1. Payload Type Development
      • 2. Payload Type Definition
        • Container Syncing
        • Turning a VM into a Container
      • 3. Adding Commands
        • Commands
      • 4. Create Tasking & Comms Format
        • Agent Messages
          • 1. Agent Message Format
          • 2. Checkin
          • 3. Get Tasking
          • 4. Submitting Responses
          • 5. SOCKS
          • 6. Reverse Port Forward
          • 7. Peer-to-peer messages
          • 8. Interactive Tasking
      • 5. MythicRPC
      • 6. Browser Scripting
      • 7. Dynamic Parameter Values
      • 8. Sub-tasking / Task Callbacks
      • 9. OPSEC Checking
      • 10. Translation Containers
      • 11. Process Response
      • 12 TypedArray Parse Function
      • 13. SOCKS
      • 14. Reverse PortFwd
      • 15. Interactive Tasking
    • 2. C2 Development
      • Docker & Server Config
        • 1. Docker Containers
        • 2. Configuration Files
        • 3. OPSEC Checks
        • 4. Configuration Checks
        • 5. Sample Message
        • 6. File Hosting
        • 7. Redirect Rules
        • 8. Get IOC
        • 9. Push C2
    • 3. Consuming Containers
      • Webhooks
      • Logging
      • Eventing
        • Operator Context (run_as)
        • Workflow Triggers
        • Steps
      • Auth
    • 4. Extending Agent Commands
    • Mythic UI Development
  • Common Questions and Answers
    • FAQ / Troubleshooting Tips
    • Change Log
    • 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
    • Mythic 3.2->3.3 Updates
Powered by GitBook
On this page
  • What is OPSEC Checking
  • Where is OPSEC Checking?
  • opsec_pre / opsec_post
  • OPSEC Scripting

Was this helpful?

Export as PDF
  1. Customizing
  2. 1. Payload Type Development

9. OPSEC Checking

What is OPSEC Checking

It's often useful to perform some operational security checks before issuing a task based on everything you know so far, or after you've generated new artifacts for a task but before an agent picks it up. This allows us to be more granular and context aware instead of the blanket command blocking that's available from the Operation Management page in Mythic.

Where is OPSEC Checking?

OPSEC checks and information for a command is located in the same file where everything else for the command is located. Let's take an example all the way through:

class ShellCommand(CommandBase):
    cmd = "shell"
    needs_admin = False
    help_cmd = "shell {command}"
    description = """This runs {command} in a terminal by leveraging JXA's Application.doShellScript({command}).
WARNING! THIS IS SINGLE THREADED, IF YOUR COMMAND HANGS, THE AGENT HANGS!"""
    version = 1
    author = "@its_a_feature_"
    attackmapping = ["T1059", "T1059.004"]
    argument_class = ShellArguments
    attributes = CommandAttributes(
        suggested_command=True
    )

    async def opsec_pre(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPreTaskMessageResponse:
        response = PTTTaskOPSECPreTaskMessageResponse(
            TaskID=taskData.Task.ID, Success=True, OpsecPreBlocked=True,
            OpsecPreBypassRole="other_operator",
            OpsecPreMessage="Implemented, but not blocking, you're welcome!",
        )
        return response

    async def opsec_post(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPostTaskMessageResponse:
        response = PTTTaskOPSECPostTaskMessageResponse(
            TaskID=taskData.Task.ID, Success=True, OpsecPostBlocked=True,
            OpsecPostBypassRole="other_operator",
            OpsecPostMessage="Implemented, but not blocking, you're welcome! Part 2",
        )
        return response

    async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse:
        response = MythicCommandBase.PTTaskCreateTaskingMessageResponse(
            TaskID=taskData.Task.ID,
            Success=True,
        )
        await SendMythicRPCArtifactCreate(MythicRPCArtifactCreateMessage(
            TaskID=taskData.Task.ID, ArtifactMessage="{}".format(taskData.args.get_arg("command")),
            BaseArtifactType="Process Create"
        ))

        response.DisplayParams = taskData.args.get_arg("command")
        return response

opsec_pre / opsec_post

In the case of doing operational checks before a task's create_tasking is called, we have the opsec_pre function. Similarly, the opsec_post function happens after your create_tasking, but before your task is finally ready for an agent to pick it up.

  • opsec_pre/post_blocked - this indicates True/False for if the function decides the task should be blocked or not

  • opsec_pre/post_message - this is the message to the operator about the result of doing this OPSEC check

  • opsec_pre/post_bypass_role - this determines who should be able to bypass this check. The default is operator to allow any operator to bypass it, but you can change it to lead to indicate that only the lead of the operation should be able to bypass it. You can also set this to other_operator to indicate that somebody other than the operator that issued the task must approve it. This is helpful in cases where it's not necessarily a "block", but something you want to make sure operators acknowledge as a potential security risk

As the name of the functions imply, the opsec_pre check happens before create_tasking function runs and the opsec_post check happens after the create_tasking function runs. If you set opsec_pre_blocked to True, then the create_tasking function isn't executed until an approved operator bypasses the check. Then, execution goes back to create_tasking and the opsec_post. If that one also sets blocked to True, then it's again blocked at the user to bypass it. At this point, if it's bypassed, the task status simply switched to Submitted so that an agent can pick up the task on next checkin.

OPSEC Scripting

Previous8. Sub-tasking / Task CallbacksNext10. Translation Containers

Was this helpful?

From the opsec_pre and opsec_post functions, you have access to the entire task/callback information like you do in . Additionally, you have access to the entire RPC suite just like in .

Create_Tasking
Create_Tasking