espilon-source/tools/C3PO/tui/help.py
Eun0us 79c2a4d4bf c3po: full server rewrite with modular routes and honeypot dashboard
Replace monolithic CLI and web server with route-based Flask API.
New routes: api_commands, api_build, api_can, api_monitor, api_ota,
api_tunnel. Add honeypot security dashboard with real-time SSE,
MITRE ATT&CK mapping, kill chain analysis.

New TUI with commander/help modules. Add session management,
tunnel proxy core, CAN bus data store. Docker support.
2026-02-28 20:12:27 +01:00

296 lines
12 KiB
Python

from utils.display import Display
# ESP32 Commands organized by module (matches Kconfig modules)
ESP_MODULES = {
"system": {
"description": "Core system commands",
"commands": {
"system_reboot": "Reboot the ESP32 device",
"system_mem": "Get memory info (heap, internal)",
"system_uptime": "Get device uptime",
}
},
"network": {
"description": "Network tools",
"commands": {
"ping": "Ping a host (ping <host>)",
"arp_scan": "ARP scan the local network",
"proxy_start": "Start TCP proxy (proxy_start <ip> <port>)",
"proxy_stop": "Stop TCP proxy",
"dos_tcp": "TCP flood (dos_tcp <ip> <port> <count>)",
}
},
"fakeap": {
"description": "Fake Access Point module",
"commands": {
"fakeap_start": "Start fake AP (fakeap_start <ssid> [open|wpa2] [pass])",
"fakeap_stop": "Stop fake AP",
"fakeap_status": "Show fake AP status",
"fakeap_clients": "List connected clients",
"fakeap_portal_start": "Start captive portal",
"fakeap_portal_stop": "Stop captive portal",
"fakeap_sniffer_on": "Enable packet sniffer",
"fakeap_sniffer_off": "Disable packet sniffer",
}
},
"recon": {
"description": "Reconnaissance module (Camera + MLAT)",
"commands": {
"cam_start": "Start camera streaming (cam_start <ip> <port>)",
"cam_stop": "Stop camera streaming",
"mlat config": "Set position (mlat config [gps|local] <c1> <c2>)",
"mlat mode": "Set scan mode (mlat mode <ble|wifi>)",
"mlat start": "Start MLAT scanning (mlat start <mac>)",
"mlat stop": "Stop MLAT scanning",
"mlat status": "Show MLAT status",
}
}
}
class HelpManager:
def __init__(self, command_registry, dev_mode: bool = False):
self.commands = command_registry
self.dev_mode = dev_mode
def _out(self, text: str):
"""Output helper that works in both CLI and TUI mode."""
Display.system_message(text)
def show(self, args: list[str]):
if args:
self._show_command_help(args[0])
else:
self._show_global_help()
def show_modules(self):
"""Show ESP commands organized by module."""
self._out("=== ESP32 COMMANDS BY MODULE ===")
self._out("")
for module_name, module_info in ESP_MODULES.items():
self._out(f"[{module_name.upper()}] - {module_info['description']}")
for cmd_name, cmd_desc in module_info["commands"].items():
self._out(f" {cmd_name:<20} {cmd_desc}")
self._out("")
self._out("Use 'help <command>' for detailed help on a specific command.")
self._out("Send commands with: send <device_id|all> <command> [args...]")
def _show_global_help(self):
self._out("=== ESPILON C2 HELP ===")
self._out("")
self._out("C2 Commands:")
self._out(" help [command] Show help or help for a specific command")
self._out(" list List connected ESP devices")
self._out(" modules List ESP commands organized by module")
self._out(" send <target> <cmd> Send a command to ESP device(s)")
self._out(" group <action> Manage device groups (add, remove, list, show)")
self._out(" active_commands List currently running commands")
self._out(" clear Clear terminal screen")
self._out(" exit Exit C2")
self._out("")
self._out("Server Commands:")
self._out(" web start|stop|status Web dashboard server")
self._out(" camera start|stop|status Camera UDP receiver")
self._out("")
self._out("ESP Commands: (use 'modules' for detailed list)")
registered_cmds = self.commands.list()
if registered_cmds:
for name in registered_cmds:
handler = self.commands.get(name)
self._out(f" {name:<15} {handler.description}")
else:
self._out(" (no registered commands - use 'send' with any ESP command)")
if self.dev_mode:
self._out("")
self._out("DEV MODE: Send arbitrary text: send <target> <any text>")
def _show_command_help(self, command_name: str):
# CLI Commands
if command_name == "list":
self._out("Help for 'list' command:")
self._out(" Usage: list")
self._out(" Description: Displays all connected ESP devices with ID, IP, status,")
self._out(" connection duration, and last seen timestamp.")
elif command_name == "send":
self._out("Help for 'send' command:")
self._out(" Usage: send <device_id|all|group <name>> <command> [args...]")
self._out(" Description: Sends a command to one or more ESP devices.")
self._out(" Examples:")
self._out(" send ESP_ABC123 reboot")
self._out(" send all wifi status")
self._out(" send group scanners mlat start AA:BB:CC:DD:EE:FF")
elif command_name == "group":
self._out("Help for 'group' command:")
self._out(" Usage: group <action> [args...]")
self._out(" Actions:")
self._out(" add <name> <id1> [id2...] Add devices to a group")
self._out(" remove <name> <id1> [id2...] Remove devices from a group")
self._out(" list List all groups")
self._out(" show <name> Show group members")
elif command_name == "web":
self._out("Help for 'web' command:")
self._out(" Usage: web <start|stop|status>")
self._out(" Description: Control the web dashboard server.")
self._out(" Actions:")
self._out(" start Start the web server (dashboard, cameras, MLAT)")
self._out(" stop Stop the web server")
self._out(" status Show server status and MLAT engine info")
self._out(" Default URL: http://127.0.0.1:8000 (configurable via .env)")
elif command_name == "camera":
self._out("Help for 'camera' command:")
self._out(" Usage: camera <start|stop|status>")
self._out(" Description: Control the camera UDP receiver.")
self._out(" Actions:")
self._out(" start Start UDP receiver for camera frames")
self._out(" stop Stop UDP receiver")
self._out(" status Show receiver stats (packets, frames, errors)")
self._out(" Default port: 5000 (configurable via .env)")
elif command_name == "modules":
self._out("Help for 'modules' command:")
self._out(" Usage: modules")
self._out(" Description: List all ESP32 commands organized by module.")
self._out(" Modules: system, network, fakeap, recon")
elif command_name in ["clear", "exit", "active_commands"]:
self._out(f"Help for '{command_name}' command:")
self._out(f" Usage: {command_name}")
descs = {
"clear": "Clear the terminal screen",
"exit": "Exit the C2 application",
"active_commands": "Show all commands currently being executed"
}
self._out(f" Description: {descs.get(command_name, '')}")
# ESP Commands (by module or registered)
else:
# Check in modules first
for module_name, module_info in ESP_MODULES.items():
if command_name in module_info["commands"]:
self._out(f"ESP Command '{command_name}' [{module_name.upper()}]:")
self._out(f" Description: {module_info['commands'][command_name]}")
self._show_esp_command_detail(command_name)
return
# Check registered commands
handler = self.commands.get(command_name)
if handler:
self._out(f"ESP Command '{command_name}':")
self._out(f" Description: {handler.description}")
if hasattr(handler, 'usage'):
self._out(f" Usage: {handler.usage}")
else:
Display.error(f"No help available for '{command_name}'.")
def _show_esp_command_detail(self, cmd: str):
"""Show detailed help for specific ESP commands."""
details = {
# MLAT subcommands
"mlat config": [
" Usage: send <device> mlat config [gps|local] <coord1> <coord2>",
" GPS mode: mlat config gps <lat> <lon> - degrees",
" Local mode: mlat config local <x> <y> - meters",
" Examples:",
" send ESP1 mlat config gps 48.8566 2.3522",
" send ESP1 mlat config local 10.0 5.5",
],
"mlat mode": [
" Usage: send <device> mlat mode <ble|wifi>",
" Example: send ESP1 mlat mode ble",
],
"mlat start": [
" Usage: send <device> mlat start <mac>",
" Example: send ESP1 mlat start AA:BB:CC:DD:EE:FF",
],
"mlat stop": [
" Usage: send <device> mlat stop",
],
"mlat status": [
" Usage: send <device> mlat status",
],
"cam_start": [
" Usage: send <device> cam_start <ip> <port>",
" Description: Start camera streaming to C2 UDP receiver",
" Example: send ESP_CAM cam_start 192.168.1.100 12345",
],
"cam_stop": [
" Usage: send <device> cam_stop",
" Description: Stop camera streaming",
],
"fakeap_start": [
" Usage: send <device> fakeap_start <ssid> [open|wpa2] [password]",
" Examples:",
" send ESP1 fakeap_start FreeWiFi",
" send ESP1 fakeap_start SecureNet wpa2 mypassword",
],
"fakeap_stop": [
" Usage: send <device> fakeap_stop",
],
"fakeap_status": [
" Usage: send <device> fakeap_status",
" Shows: AP running, portal status, sniffer status, client count",
],
"fakeap_clients": [
" Usage: send <device> fakeap_clients",
" Lists all connected clients to the fake AP",
],
"fakeap_portal_start": [
" Usage: send <device> fakeap_portal_start",
" Description: Enable captive portal (requires fakeap running)",
],
"fakeap_portal_stop": [
" Usage: send <device> fakeap_portal_stop",
],
"fakeap_sniffer_on": [
" Usage: send <device> fakeap_sniffer_on",
" Description: Enable packet sniffing",
],
"fakeap_sniffer_off": [
" Usage: send <device> fakeap_sniffer_off",
],
"ping": [
" Usage: send <device> ping <host>",
" Example: send ESP1 ping 8.8.8.8",
],
"arp_scan": [
" Usage: send <device> arp_scan",
" Description: Scan local network for hosts",
],
"proxy_start": [
" Usage: send <device> proxy_start <ip> <port>",
" Example: send ESP1 proxy_start 192.168.1.100 8080",
],
"proxy_stop": [
" Usage: send <device> proxy_stop",
],
"dos_tcp": [
" Usage: send <device> dos_tcp <ip> <port> <count>",
" Example: send ESP1 dos_tcp 192.168.1.100 80 1000",
],
"system_reboot": [
" Usage: send <device> system_reboot",
" Description: Reboot the ESP32 device",
],
"system_mem": [
" Usage: send <device> system_mem",
" Shows: heap_free, heap_min, internal_free",
],
"system_uptime": [
" Usage: send <device> system_uptime",
" Shows: uptime in days/hours/minutes/seconds",
],
}
if cmd in details:
for line in details[cmd]:
self._out(line)