5.8 KiB
Whiskers
LitterBox's sensor agent — a single-binary HTTP execution runner. Runs on the Windows VM where you've installed an EDR (Elastic Defend, Defender, etc.) and accepts payloads from LitterBox over HTTP. Executes them, reports stdout/stderr/PID/exit code back. Does not read EDR alerts — telemetry comes from your EDR agent independently. LitterBox queries your local Elastic stack (or whichever backend your EDR ships to) for alerts on its own.
LitterBox ── HTTP ──► Whiskers.exe ── Process.Spawn ──► payload
│
└─ same VM has your EDR agent watching everything
(Elastic Defend / Defender / etc.)
The naming: in the LitterBox family, Whiskers is the agent — sensors out
in the field, deployed on the EDR VM, picking up what happens to a payload
during execution. The orchestrator is LitterBox itself; the client
library is GrumpyCats.
Install
- Get the binary
- Download
Whiskers.exefrom the LitterBox release page, OR - Build from source — see
BUILD.md
- Download
- Drop it anywhere on the VM (e.g.
C:\Tools\Whiskers.exe) - Allow inbound TCP 8080 in Windows Firewall:
New-NetFirewallRule -DisplayName "Whiskers" ` -Direction Inbound -Protocol TCP -LocalPort 8080 ` -Action Allow - Run it:
You should see something like:
.\Whiskers.exe --port 80802026-04-29T13:30:12Z INFO whiskers ready version=0.1.0 listen=0.0.0.0:8080
Verify
From any machine that can reach the VM:
curl http://<edr-vm-ip>:8080/api/info
# {"hostname":"DESKTOP-...","os_version":"Windows ...","agent_version":"0.1.0"}
CLI flags
| Flag | Default | Notes |
|---|---|---|
--port <PORT> |
8080 |
TCP port to listen on |
--bind <ADDR> |
0.0.0.0 |
Bind address. Set 127.0.0.1 for loopback-only testing |
The binary also accepts --help and --version.
Run as a Windows service (optional)
For a VM where you want Whiskers up automatically after every reboot.
Easiest path is sc.exe:
# Run elevated PowerShell:
sc.exe create Whiskers binPath= "\"C:\Tools\Whiskers.exe\" --port 8080" `
start= auto DisplayName= "Whiskers (LitterBox sensor agent)"
sc.exe description Whiskers "LitterBox sensor agent — payload execution runner"
sc.exe start Whiskers
Stop / remove later with:
sc.exe stop Whiskers
sc.exe delete Whiskers
Whiskers isn't a "real" Windows service (no SCM lifecycle handling) so
sc createruns it as a console app under the service host. For most sandbox use that's fine; for a hardened production deploy wrap it in NSSM which handles SCM properly.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/api/info |
Self-reported {hostname, os_version, agent_version} |
POST |
/api/lock/acquire |
Single-occupancy gate. 200 if free, 409 if held |
POST |
/api/lock/release |
200, idempotent |
GET |
/api/lock/status |
{in_use: bool} |
POST |
/api/execute/exec |
Multipart: file + drop_path + executable_args + xor_key. Returns {status, pid} immediately; the spawn runs detached |
POST |
/api/execute/kill |
Terminate the most recent run if alive |
GET |
/api/logs/execution |
{pid, status, stdout, stderr, exit_code, started_at, finished_at, is_running} for the most recent run |
GET |
/api/logs/agent |
Plain-text agent-debug log (last 1000 lines) |
DELETE |
/api/logs/agent |
Clear the agent log buffer |
Single-occupancy by design — a new /api/execute/exec while a previous
run is still live will kill the previous one before starting the new
one. The lock is what the orchestrator (LitterBox) holds across the
whole exec → poll → release window to make sure two operators don't
double-fire.
The lock auto-expires after 30 minutes of being held — protects against a crashed orchestrator stranding Whiskers.
Security model
- Whiskers has no authentication. It's designed to run on a VM that only LitterBox should be able to reach (private network, VPN, or loopback). Don't expose port 8080 to the internet.
- Payloads land in
C:\Users\Public\Downloads\by default unless the caller specifiesdrop_path. That folder is auto-cleaned after each run, but Whiskers never reaches outside the supplieddrop_path. - Execution runs as the same user the Whiskers process is running as. If
you installed the service as
LocalSystem(sc.exe default), payloads run with SYSTEM privileges — fine for sandbox use, intentional for evaluating SYSTEM-context detections, but be aware. - The XOR option on
/api/execute/execkeeps the payload encrypted in transit and during the in-memory copy on the agent — useful when your EDR's behavioral monitor would match a plaintext known-bad sample before the spawn happens.
Troubleshooting
Bind error: address already in use — another process holds port
8080. Pick a different --port or stop the conflicting service.
Curl times out from another machine — Windows Firewall is blocking.
Verify the rule: Get-NetFirewallRule -DisplayName "Whiskers".
Lock stuck "in_use" — wait 30 minutes for auto-expiry, or POST /api/lock/release from any client (release is unauthenticated by
design — single-VM trust model).
/api/execute/exec returns 500 with Failed to spawn — the EDR on
the VM probably blocked the dropper or the spawn. Check your EDR's
quarantine log; this is exactly the signal we want to capture and
return to LitterBox via the Elastic alert query.
/api/logs/execution shows empty stdout — the spawned process may
not have flushed before exit, or it wrote to a separate console (GUI
app). For GUI / detached payloads, capture is best-effort.