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
  • Message Structure
  • Message Location

Was this helpful?

Export as PDF
  1. Customizing
  2. 1. Payload Type Development
  3. 4. Create Tasking & Comms Format
  4. Agent Messages

8. Interactive Tasking

Message Structure

Messages for interactive tasking have three pieces:

{
    "task_id": "UUID of task",
    "data": "base64 of data",
    "message_type": int enum of types
}

If you have a command called pty and issue it, then when that task gets sent to your agent, you have your normal tasking structure. That tasking structure includes an id for the task that's a UUID. All follow-on interactive input for that task uses the same UUID (task_id in the above message).

The data is pretty straight forward - it's the base64 of the raw data you're trying to send to/from this interactive task. The message_type field is an enum of int. It might see complicated at first, but really it boils down to providing a way to support sending control codes through the web UI, scripting, and through an opened port.

const (
   Input = 0
   Output = 1
   Error = 2
   Exit = 3
   Escape = 4    //^[ 0x1B
   CtrlA = 5     //^A - 0x01 - start
   CtrlB = 6     //^B - 0x02 - back
   CtrlC = 7     //^C - 0x03 - interrupt process
   CtrlD = 8     //^D - 0x04 - delete (exit if nothing sitting on input)
   CtrlE = 9     //^E - 0x05 - end
   CtrlF = 10     //^F - 0x06 - forward
   CtrlG = 11     //^G - 0x07 - cancel search
   Backspace = 12 //^H - 0x08 - backspace
   Tab = 13       //^I - 0x09 - tab
   CtrlK = 14     //^K - 0x0B - kill line forwards
   CtrlL = 15     //^L - 0x0C - clear screen
   CtrlN = 16     //^N - 0x0E - next history
   CtrlP = 17     //^P - 0x10 - previous history
   CtrlQ = 18     //^Q - 0x11 - unpause output
   CtrlR = 19     //^R - 0x12 - search history
   CtrlS = 20     //^S - 0x13 - pause output
   CtrlU = 21     //^U - 0x15 - kill line backwards
   CtrlW = 22     //^W - 0x17 - kill word backwards
   CtrlY = 23     //^Y - 0x19 - yank
   CtrlZ = 24     //^Z - 0x1A - suspend process
   end
)

When something is coming from Mythic -> Agent, you'll typically see Input, Exit, or Escape -> CtrlZ. When sending data back from Agent -> Mythic, you'll set either Output or Error. This enum example also includes what the user typically sees in a terminal (ex: ^C when you type CtrlC) along with the hex value that's normally sent. Having data split out this way can be helpful depending on what you're trying to do. Consider the case of trying to do a tab-complete. You want to send down data and the tab character (in that order). For other things though, like escape, you might want to send down escape and then data (in that order for things like control sequences).

You'll probably notice that some letters are missing from the control codes above. There's no need to send along a special control code for \n or \r because we can send those down as part of our input. Similarly, clearing the screen isn't useful through the web UI because it doesn't quite match up as a full TTY.

Message Location

This data is located in a similar way to SOCKS and RPFWD:

{
    "action": "some action",
    "interactive": [ {"task_id": UUID, "data": "base64", "message_type": 0 } ]
}

the interactive keyword takes an array of these sorts of messages to/from the agent. This keyword is at the same level in the JSON structure as action, socks, responses, etc.

This means that if you send a get_tasking request OR a post_response request, you could get back interactive data. The same goes for rpfwd, socks, and delegates.

When sending responses back for interactive tasking, you send back an array in the interactive keyword just like you got the data in the first place.

Previous7. Peer-to-peer messagesNext5. MythicRPC

Was this helpful?