Skip to content

Replace tunnel/proxy with relay #2216

@mssalvatore

Description

@mssalvatore

Refactor

Component(s) to be refactored

  • Tunnel replaced by Relay

Explanation

Problem

The current tunneling mechanism has a few major bugs and drawbacks:

  • The number of hops is limited (see Investigate the tunneling mechanisms #1583)
  • There is a bug that makes tunneling unreliable (see Fix tunneling tests #2174)
  • Agents have knowledge of a server and proxy, which leads to logic wherein the agent must distinguish between the server and proxy
  • Agents attempt to find tunnels/proxies using a multicast address, which can be noisy and relies on the network supporting multicast
  • Ideal functioning of the proxy relies on 2 ports (5000 and 5007) being accessible from victims.
  • The command & control server has very limited ability to dictate how agents connect back to it. A variety of different strategies are possible, but adding them would be complex

Solution

To solve the above issues, the tunnel/proxy will be replaced with a TCP relay. TCP relays simply pass all traffic they receive on to the Island (or the next relay in the chain). TCP relays are passed to the agent via a command-line argument in priority order when the agent starts. The agent has no knowledge of which one is a direct connection to the island and which ones are actually relays.

When an agent starts, it starts a TCP relay and appends the ip:port of its relay to the list it was given. It then passes this complete list to all child agents that it spawns. This gives the child agents a variety of relays to try without the need to multicast them through the network. It also allows the parent (or command & control) to dictate how the child agent should connect by changing the order of the servers.

Benefits

  • Code reduction and simplification
    • Only one mechanism (TCP), whereas now there are two (TCP and HTTP)
    • Agent's don't need to connect with and without a proxy or search for proxies. They simply try every server given to them in order
  • This design allows for an unlimited number of hops, whereas the previous implementation would only allow connections to be proxied 1-2 hops from the island.
  • Improved firewall evasion
    • If the Island has more than one IP address, agents can connect to any of them.
    • Using one port instead of two reduces noise.
    • Using a well-known port (if possible) increases the likelihood that traffic will be allowed to/from the relay.
  • Changing relay networking strategies is as simple as changing the order in which servers are specified. For example, for "shortest path" strategy, each agent appends its relay to the list of known relays. For a strategy where agents should try their parent's relay first, the parent's relay is prepended.
  • Relays are protocol agnostic. That is, any protocol that can operate over TCP can be sent over the relay, whereas the HTTP tunnel only allows HTTP.
  • Since the agent makes no distinction between the C&C server or the relays, these changes enable us to have multiple or replicated C&C servers.
  • This refactoring effort will allow us to put better unit tests around tunneling

Tasks

  • Create a TCPRelay (0d) - @cakekoa
  • Track a list of "relay users" in TCPRelay (populate on connect) (0d) - @cakekoa
  • Modify ExploitInterceptingTelemetryMessenger to notify TCPRelay of exploits (0d) - @cakekoa
    • Add method to TCPRelay that accepts an ExploitTelem and keeps track of exploited machines
    • Pass the ExploitTelem to TCPRelay's method
  • Establish a relay control language/protocol that allows agents to tell relays when it's finished with them (just need -) (0d) - @cakekoa
  • Add a timeout to wait for exploited machines to connect (0d) - @cakekoa
  • Add a timeout to wait for "relay users" to either use the relay or signal that they're done (0d) - @cakekoa
  • Start the TCPRelay during agent setup (0d) - @cakekoa
    • Add a function that attempts to use well-known ports for the relay to listen on. If no well-known port is available, pick a random available port.
  • Make a list of all known servers/relays available to exploiters (0d) @ilija-lazoroski
  • Modify the code that builds agent execution commands to provide a list of servers (no proxy flag) (0d) @ilija-lazoroski
  • Modify the agent's command-line arguments (0d) @ilija-lazoroski
    • Remove proxy argument
    • Modify server argument to accept a comma-separated list of servers
  • Modify the agent "find server" logic to use the list of severs (0d) @ilija-lazoroski, @shreyamalviya
    • Send - to all servers that the agent isn't using
  • Modify the agent to signal its relay/server that it's shutting down (0d) - @cakekoa
  • Remove any disused tunnel/proxy code (0d) - @cakekoa
    • Remove stale vulture allow list entries
  • Add new ETE tests to test different aspects/features of the new relay strategy (0d) - @VakarisZ
    • Multi-hop (add one more hop than we have now)
    • Connect through ancestor relay
  • Address
    # TODO: This functionality is duplicated in the agent. Unify them after 2216-tcp-relay is merged
    (0d) - @VakarisZ

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions