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 is Reverse Port Forward?
  • What do RPFWD messages look like?
  • How does this fit into Agent Messages?
  • How does an agent handle RPFWD?

Was this helpful?

Export as PDF
  1. Customizing
  2. C2 Related Development
  3. C2 Profile Code
  4. Agent Side Coding

RPFWD

How does Reverse Port Forward work within Mythic

What is Reverse Port Forward?

Reverse port forwards provide a way to tunnel incoming connections on one port out to another IP:Port somewhere else. It normally provides a way to expose an internal service to a network that would otherwise not be able to directly access it.

What do RPFWD messages look like?

Agents transmit dictionary messages that look like the following:

{
  "exit": True,
  "server_id": 1234567,
  "data": ""
}

These messages contain three components:

  • exit - boolean True or False. This indicates to either Mythic or your Agent that the connection has been terminated from one end and should be closed on the other end (after sending data). Because Mythic and 2 HTTP connections sit between the actual tool you're trying to proxy and the agent that makes those requests on your tool's behalf, we need this sort of flag to indicate that a TCP connection has closed on one side.

  • server_id - unsigned int32. This number is how Mythic and the agent can track individual connections. Every new connection will generate a new server_id . Unlike SOCKS where Mythic is getting the initial connection, the agent is getting the initial connection in a reverse port forward. In this case, the agent needs to generate this random uint32 value to track connections.

  • data - base64 string. This is the actual bytes that the proxied tool is trying to send.

In Python translation containers, if exit is True, then data can be None

How does this fit into Agent Messages?

These RPFWD messages are passed around as an array of dictionaries in get_tasking and post_response messages via a (added if needed) rpfwd key:

{
    "action": "get_tasking",
    "tasking_size": 1,
    "rpfwd": [
        {
            "exit": False,
            "server_id": 2,
            "data": "base64 string"
        },{
            "exit": True,
            "server_id": 1,
            "data": ""
        }
    ],
    "delegates": []
}

or in the post_response messages:

{
    "action": "post_response",
    "responses": [
        {
            "user_output": "blah",
            "task_id": "uuid here",
            "completed": true
        }
    ],
    "rpfwd": [
        {
            "exit": False,
            "server_id": 2,
            "data": "base64 string"
        },{
            "exit": True,
            "server_id": 1,
            "data": ""
        }
    ],
    "delegates": []

Notice that they're at the same level of "action" in these dictionaries - that's because they're not tied to any specific task, the same goes for delegate messages.

How does an agent handle RPFWD?

For the most part, the message processing is pretty straight forward:

  1. Agent opens port X on the target host where it's running

  2. ServerA makes a connection to PortX

  3. Agent accepts the connection, generates a new uint32 server_id, and sends any data received to Mythic via rpfwd key.

  4. Mythic looks up the server_id, if Mythic has seen this server_id, then it can pass it off to the appropriate thread or channel to continue processing. If we've never seen the server_id before, then it's likely a new connection that opened up, so we need to handle that appropriately. Mythic makes a new connection out to the RemoteIP:RemotePort specified when starting the rpfwd session. Mythic forwards the data along and waits for data back. Any data received is sent back via the rpfwd key the next time the agent checks in.

  5. For existing connections, the agent looks at if exit is True or not. If exit is True, then the agent should close its corresponding TCP connection and clean up those resources. If it's not exit, then the agent should base64 decode the data field and forward those bytes through the existing TCP connection.

  6. The agent should also be streaming data back from its open TCP connections to Mythic in its get_tasking and post_response messages.

That's it really. The hard part is making sure that you don't exhaust all of the system resources by creating too many threads, running into deadlocks, or any number of other potential issues.

PreviousSOCKSNextServer Side Coding

Last updated 1 year ago

Was this helpful?

While not perfect, the poseidon agent have a generally working implementation for Mythic:

https://github.com/MythicAgents/poseidon/blob/master/Payload_Type/poseidon/poseidon/agent_code/rpfwd/rpfwd.go