espilon-source/tools/C3PO/README.md
Eun0us 31c312f085 docs: update all documentation for v0.3.0
Reflect new module architecture, deploy system, Docker support,
honeypot dashboard, and tunnel proxy in documentation.
Updated French README.
2026-02-28 20:16:16 +01:00

8.9 KiB

C3PO (C2) - Full Documentation

C3PO is the Command & Control (C2) server for ESPILON agents. It manages device connections, command dispatch, device state tracking, and provides a CLI, a multi-device TUI (Textual), a web dashboard, and a UDP camera receiver with recording.


Summary

Main features:

  • TCP server for ESP agents (Base64 + ChaCha20-Poly1305 AEAD + Protobuf)
  • Device registry and group management
  • Interactive CLI + multi-device TUI
  • Web dashboard (Flask) with Dashboard, Cameras, and MLAT pages
  • UDP camera receiver with recording
  • MLAT (multilateration) engine for RSSI-based positioning

Prerequisites

  • Python 3.10+ (tested with 3.11)
  • pip (package manager)
  • Virtual environment (recommended)

Installation

1. Créer un environnement virtuel

cd tools/c2
python3 -m venv .venv

Ceci crée un dossier .venv/ isolé pour les dépendances Python.

2. Activer l'environnement

Linux / macOS :

source .venv/bin/activate

Windows (PowerShell) :

.\.venv\Scripts\Activate.ps1

Windows (CMD) :

.\.venv\Scripts\activate.bat

Le prompt devrait afficher (.venv) pour confirmer l'activation.

3. Installer les dépendances

pip install -r requirements.txt

Ceci installe toutes les dépendances nécessaires :

Package Version Usage
pycryptodome >=3.15.0 ChaCha20-Poly1305 AEAD + HKDF key derivation
protobuf >=4.21.0 Sérialisation Protocol Buffers
flask >=2.0.0 Serveur web (dashboard, API)
python-dotenv >=1.0.0 Chargement config .env
textual >=0.40.0 Interface TUI multi-pane
opencv-python >=4.8.0 Traitement vidéo/images caméra
numpy >=1.24.0 Calculs matriciels (opencv, scipy)
scipy >=1.10.0 Algorithme MLAT (optimisation)

4. Vérifier l'installation

python -c "from web.server import UnifiedWebServer; print('OK')"

Désactiver l'environnement

deactivate

Configuration

C2 (TCP)

The core C2 server uses constants defined in utils/constant.py:

  • HOST (default 0.0.0.0)
  • PORT (default 2626)

Web + Camera + MLAT

Copy .env.example to .env and adjust as needed:

cp .env.example .env

Key variables:

  • WEB_HOST, WEB_PORT (dashboard web server, default 0.0.0.0:8000)
  • UDP_HOST, UDP_PORT (camera UDP, default 0.0.0.0:5000)
  • CAMERA_SECRET_TOKEN (must match firmware)
  • WEB_USERNAME, WEB_PASSWORD (dashboard login)
  • FLASK_SECRET_KEY (sessions)
  • MULTILAT_AUTH_TOKEN (Bearer token for MLAT API)
  • IMAGE_DIR (JPEG frames)
  • VIDEO_ENABLED, VIDEO_PATH, VIDEO_FPS, VIDEO_CODEC

Launch

Classic CLI mode:

python3 c3po.py

TUI (Textual) mode:

python3 c3po.py --tui

C2 Commands (CLI/TUI)

Main commands:

Command Description
help [command] General help or per-command help
list List connected devices
modules List ESP commands by module
send <target> <cmd> [args...] Send a command
group <action> Manage groups
active_commands List running commands
web start|stop|status Web dashboard
camera start|stop|status Camera UDP receiver
clear Clear screen
exit Quit

Examples:

list
send ce4f626b system_reboot
send all fakeap_status
send group scanners mlat start AA:BB:CC:DD:EE:FF
web start
camera start
active_commands

Groups

group add bots ce4f626b a91dd021
group list
group show bots
group remove bots ce4f626b

ESP Commands (Modules)

ESP commands are organized by module (use modules). Summary:

Module Command Description
system system_reboot Reboot ESP32
system system_mem Memory info
system system_uptime Device uptime
system system_info Auto-query on connect
network ping <host> Ping
network arp_scan ARP scan
network proxy_start <ip> <port> TCP proxy
network proxy_stop Stop proxy
network dos_tcp <ip> <port> <count> TCP flood
fakeap fakeap_start <ssid> [open|wpa2] [pass] Start Fake AP
fakeap fakeap_stop Stop Fake AP
fakeap fakeap_status Fake AP status
fakeap fakeap_clients List clients
fakeap fakeap_portal_start Captive portal
fakeap fakeap_portal_stop Stop portal
fakeap fakeap_sniffer_on Sniffer on
fakeap fakeap_sniffer_off Sniffer off
recon cam_start <ip> <port> Start camera stream
recon cam_stop Stop camera stream
recon mlat config [gps|local] <c1> <c2> Set scanner position
recon mlat mode <ble|wifi> Scan mode
recon mlat start <mac> Start MLAT
recon mlat stop Stop MLAT
recon mlat status MLAT status

Notes:

  • DEV_MODE = True in tools/c2/cli/cli.py allows raw text: send <target> <any text>
  • system_info is automatically sent on new connections.

TUI (Textual)

The TUI shows:

  • Left panel: all connected devices
  • Right panel: global logs
  • Bottom input bar with autocomplete

Key bindings:

  • Alt+G: toggle global logs
  • Ctrl+L: clear global logs
  • Ctrl+Q: quit
  • Esc: focus input
  • Tab: completion

Screenshots

Replace the placeholders below with your own captures:

C3PO CLI Placeholder C3PO TUI Placeholder C3PO Web Dashboard Placeholder C3PO Cameras Placeholder C3PO MLAT Placeholder


Web Dashboard

Start from the CLI:

web start

Default local URL:

http://127.0.0.1:8000

Default credentials: admin / admin (defined in .env).

Pages:

  • /dashboard (devices)
  • /cameras (streams)
  • /mlat (MLAT view)

API (Bearer token)

Authenticate with:

Authorization: Bearer <MULTILAT_AUTH_TOKEN>

Endpoints:

  • GET /api/devices
  • GET /api/cameras
  • POST /api/recording/start/<camera_id>
  • POST /api/recording/stop/<camera_id>
  • GET /api/recording/status?camera_id=<id>
  • GET /api/recordings
  • POST /api/mlat/collect
  • GET /api/mlat/state
  • GET|POST /api/mlat/config
  • POST /api/mlat/clear
  • GET /api/stats

Example:

curl -H "Authorization: Bearer multilat_secret_token" http://127.0.0.1:8000/api/devices

Camera UDP

The UDP receiver assembles JPEG frames and stores them in IMAGE_DIR. Expected protocol:

  • Each packet starts with CAMERA_SECRET_TOKEN
  • START: begin frame
  • END: end frame
  • Other packets are JPEG chunks

C2 commands:

  • camera start
  • camera stop
  • camera status

Quick test:

python3 test_udp.py 5000

Recording:

  • Triggered via Web API (recording endpoints)
  • Files stored in static/recordings

MLAT (Multilateration)

Supported formats (from ESP):

  • MLAT:G;<lat>;<lon>;<rssi>
  • MLAT:L;<x>;<y>;<rssi>
  • Legacy: MLAT:<lat>;<lon>;<rssi>

Requirements:

  • At least 3 active scanners
  • Calibration via rssi_at_1m and path_loss_n (/api/mlat/config)

Architecture (Summary)

tools/C3PO/
├── c3po.py              # C2 entrypoint (CLI / TUI)
├── cli/                 # CLI + help
├── commands/            # Registry + internal commands
├── core/                # Registry, transport, crypto, keystore
│   ├── crypto.py        # ChaCha20-Poly1305 AEAD + HKDF
│   ├── keystore.py      # Per-device master key management (keys.json)
│   ├── transport.py     # TCP transport with per-device crypto
│   └── registry.py      # Device registry
├── log/                 # Log manager
├── streams/             # Camera UDP + config
├── tui/                 # Textual UI
├── web/                 # Flask server + MLAT
├── templates/           # HTML
├── static/              # CSS/JS/streams/recordings
├── utils/               # Display, constants
├── keys.json            # Per-device master key store
└── requirements.txt

Troubleshooting

  • Base64 decode failed or Decrypt failed: verify the device was provisioned with tools/deploy.py and that keys.json contains the correct master key for the device ID
  • TUI not available: install textual
  • No camera frames: check CAMERA_SECRET_TOKEN and UDP_PORT
  • Web not reachable: check WEB_HOST, WEB_PORT, firewall
  • MLAT not resolving: needs at least 3 scanners

Security Notes

  • Each device must be provisioned with a unique master key via tools/deploy.py
  • Master keys are stored in keys.json — keep this file secure and never commit it to version control
  • The C2 derives per-device encryption keys using HKDF-SHA256 (master_key + device_id salt)
  • All C2 communications use ChaCha20-Poly1305 AEAD with random 12-byte nonces
  • Change WEB_USERNAME / WEB_PASSWORD and FLASK_SECRET_KEY
  • Change MULTILAT_AUTH_TOKEN for the API