Skip to content
katana edited this page May 15, 2026 · 3 revisions

Agent

The agent is a lightweight binary that runs on the remote host. It connects back to the server, registers its subnets, and forwards traffic on demand. No root or administrator privileges are required.


Modes

Standard Mode (default)

The agent connects outbound to the server over QUIC/UDP. The default server agent port is 2048.

./agent-linux-amd64 -s <server-ip>:2048 -k <key>

Bind Mode

The agent listens on a local TCP port and waits for the server to dial in. Useful when the agent host cannot reach the server directly but the server can reach the agent.

# On the agent host
./agent-linux-amd64 -m agent-bind -l 0.0.0.0:9001 -k <key>

# From the server REPL
connect <agent-ip>:9001

Background Mode

Daemonize the agent so it detaches from the terminal.

./agent-linux-amd64 -s <server-ip>:2048 -k <key> -b

On Unix this re-executes the binary with setsid and stdio redirected to /dev/null. On Windows it spawns a detached process.


CLI Flags

Flag Description
-s, --server Server agent transport address, e.g. <ip>:2048
-k, --key Base64url-encoded 32-byte AES-256 key
-m, --mode agent (default) or agent-bind
-l, --listen Listen address for bind mode, default 0.0.0.0:9001
-b, --background Run as background daemon
-c, --config Path to JSON config file

Config File

{
  "key": "<base64url-key>",
  "server_addr": "<server-ip>:2048",
  "mode": "agent"
}
./agent-linux-amd64 -c agent.json

PowerShell Agent (Invoke-Rosemary)

Invoke-Rosemary.ps1 supports outbound agent mode and bind mode. Bind mode works on legacy Windows PowerShell hosts. Outbound mode uses QUIC and requires PowerShell 7 on a .NET runtime where System.Net.Quic and libmsquic are available.

# Import
. .\Invoke-Rosemary.ps1

# Help
Invoke-Rosemary -Help

Invoke-Rosemary -Mode agent -Server 192.168.1.10:2048 -Key YOUR_KEY

Invoke-Rosemary -Mode agent-bind -Listen 0.0.0.0:9001 -Key YOUR_KEY

Invoke-Rosemary -Mode agent -Server 192.168.1.10:2048 -Key YOUR_KEY -Background

Invoke-Rosemary -Mode agent -Server 192.168.1.10:2048 -Key YOUR_KEY -Verbose

Check QUIC support before using PowerShell outbound mode:

[type]::GetType('System.Net.Quic.QuicConnection, System.Net.Quic') -ne $null
[System.Net.Quic.QuicConnection]::IsSupported
Parameter Description
-Help Show usage information
-Key Base64 encryption key - must match the server
-Mode agent (outbound) or agent-bind (inbound)
-Server Server address host:port - required in agent mode
-Listen Bind address for agent-bind mode (default 0.0.0.0:9001)
-Background Relaunch as a hidden background process and return immediately
-Verbose Show connection and session diagnostic output

If either QUIC check fails, use the Go Windows agent for outbound mode or run the PowerShell agent in agent-bind mode.


Subnet Discovery

On startup the agent discovers all local subnets automatically:

  1. Enumerates network interfaces via net.Interfaces()
  2. On Linux: parses output of ip route show
  3. On Windows: parses output of route print -4
  4. Filters out loopback and link-local ranges
  5. Sends the full subnet list to the server in the register message

The server installs interception rules for each discovered subnet so traffic to those ranges is transparently tunneled through the agent.


Internet Detection

Before registering, the agent probes internet access by attempting a TCP dial to an external address. The result is included in the register message and shown in the dashboard. This allows the server to know which agents can be used as a default egress.


Heartbeat and Reconnect

  • The agent sends a heartbeat message to the server every 10 seconds
  • If the transport session drops, the agent reconnects automatically with exponential backoff
  • The server can also send a reconnect message to force the agent to reconnect
  • The server can send a disconnect message to tell the agent to exit

Port Forwarding

The server can instruct the agent to open local port forwards:

  • TCP forward: agent listens on a local port and bridges connections to a target host
  • UDP forward: agent listens on a local UDP port with per-client session tracking and idle timeout
  • Forwards are started and stopped via start-agent-listener and stop-agent-listener messages

Ping Sweep

The server can request the agent to discover live hosts in a subnet:

  • Uses concurrent TCP port probing (tcpPing) across the subnet
  • Results are returned as a ping-sweep-response message
  • Triggered from the dashboard or via discover <agent-id> <subnet> in the REPL

Port Scan

The server can request a TCP or UDP port scan via the agent:

  • Concurrent dial workers probe each port
  • Results are returned as a port-scan-response message
  • Triggered from the dashboard or via portscan <agent-id> tcp|udp <target> [ports]

DNS Resolution

The agent resolves DNS queries on behalf of the server:

  • Uses the system resolver first
  • Falls back to public resolvers: 8.8.8.8, 1.1.1.1, 8.8.4.4
  • Handles both A and AAAA records

ICMP

The agent handles two types of ICMP messages:

  • icmp-request: ping a specific target and return the result
  • icmp_proxy: transparently proxy ICMP echo requests for the server's interception layer

Uses golang.org/x/net/icmp for raw IPv4 and IPv6 ICMP, with a fallback to the system ping binary if raw sockets are unavailable.


Supported Platforms

Platform Architectures
Linux amd64, arm64, arm, 386
Windows amd64, arm64, 386
macOS amd64, arm64
FreeBSD amd64, arm64, arm, 386
OpenBSD amd64, arm64, arm, 386

Clone this wiki locally