Files
litterbox/Whiskers/README.md
T

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

  1. Get the binary
    • Download Whiskers.exe from the LitterBox release page, OR
    • Build from source — see BUILD.md
  2. Drop it anywhere on the VM (e.g. C:\Tools\Whiskers.exe)
  3. Allow inbound TCP 8080 in Windows Firewall:
    New-NetFirewallRule -DisplayName "Whiskers" `
                        -Direction Inbound -Protocol TCP -LocalPort 8080 `
                        -Action Allow
    
  4. Run it:
    .\Whiskers.exe --port 8080
    
    You should see something like:
    2026-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 create runs 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 specifies drop_path. That folder is auto-cleaned after each run, but Whiskers never reaches outside the supplied drop_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/exec keeps 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.