-
Notifications
You must be signed in to change notification settings - Fork 1
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.
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>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>:9001Daemonize the agent so it detaches from the terminal.
./agent-linux-amd64 -s <server-ip>:2048 -k <key> -bOn Unix this re-executes the binary with setsid and stdio redirected to /dev/null. On Windows it spawns a detached process.
| 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 |
{
"key": "<base64url-key>",
"server_addr": "<server-ip>:2048",
"mode": "agent"
}./agent-linux-amd64 -c agent.jsonInvoke-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 -VerboseCheck 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.
On startup the agent discovers all local subnets automatically:
- Enumerates network interfaces via
net.Interfaces() - On Linux: parses output of
ip route show - On Windows: parses output of
route print -4 - Filters out loopback and link-local ranges
- Sends the full subnet list to the server in the
registermessage
The server installs interception rules for each discovered subnet so traffic to those ranges is transparently tunneled through the agent.
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.
- The agent sends a
heartbeatmessage to the server every 10 seconds - If the transport session drops, the agent reconnects automatically with exponential backoff
- The server can also send a
reconnectmessage to force the agent to reconnect - The server can send a
disconnectmessage to tell the agent to exit
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-listenerandstop-agent-listenermessages
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-responsemessage - Triggered from the dashboard or via
discover <agent-id> <subnet>in the REPL
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-responsemessage - Triggered from the dashboard or via
portscan <agent-id> tcp|udp <target> [ports]
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
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.
| Platform | Architectures |
|---|---|
| Linux | amd64, arm64, arm, 386 |
| Windows | amd64, arm64, 386 |
| macOS | amd64, arm64 |
| FreeBSD | amd64, arm64, arm, 386 |
| OpenBSD | amd64, arm64, arm, 386 |
Use only on systems you own or have explicit written permission to test. Unauthorized use is prohibited.