espilon-source/tools/c2
2026-02-06 09:52:20 +01:00
..
cli ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
commands ε - Init Sources 2026-01-15 00:04:00 +01:00
core ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
log ε - Implentation module camera in c2 + multilateration on web front start with camera start 2026-01-27 15:11:33 +01:00
proto ε - Init Sources 2026-01-15 00:04:00 +01:00
static ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
streams ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
templates ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
tui ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
utils ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
web ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
.env.example ε - C2 implementation camera 2026-01-19 13:09:09 +01:00
c3po.py ε - TUI multi-pane Textual + camera recording frontend + device naming fix 2026-02-06 09:52:20 +01:00
README.md ε - Init Sources 2026-01-15 00:04:00 +01:00
test_udp.py ε - Implentation module camera in c2 + multilateration on web front start with camera start 2026-01-27 15:11:33 +01:00

C2 Server Documentation

TODO

TODO:


- Implementer la coexistence entre multiflasher fichier (valid-id.txt - separator "\n" - C2 will only authorize device who are register in 'valid-id.txt' or add c2 command style 'authorizeId <id>' and he will be add into id list & valid-id.txt file)


Overview

This C2 server is a Python-based control plane designed to manage a fleet of ESP devices (agents).

It provides a clean and extensible command-line interface to:

  • Manage connected devices by unique ID
  • Send commands to individual devices, groups, or all devices
  • Organize devices into logical groups
  • Display connection duration to the C2
  • Support structured commands and raw developer commands
  • Serve as a solid base for future plugins and services

The project intentionally favors simplicity, readability, and extensibility.


Architecture Overview


c2/
├── main.py # Entry point
├── core/
│ ├── device.py # Device model
│ ├── registry.py # Connected device registry
│ ├── crypto.py # Encryption wrapper
│ ├── transport.py # Message handling
│ └── groups.py # Group registry
├── commands/
│ ├── base.py # Command base class
│ ├── registry.py # Command registry
│ └── *.py # ESP command implementations
├── cli/
│ ├── cli.py # Interactive CLI
│ └── help.py # Help system
├── logs/
│ └── manager.py # ESP log handling
├── proto/
│ ├── command.proto # Protocol definition
│ └── command_pb2.py # Generated protobuf code
└── utils/
│ └── constant.py # Default script constant

Core Concepts

Device Identity

  • Each ESP device is identified by a unique esp_id
  • Devices are not identified by IP or port
  • Reconnecting devices automatically replace their previous session

Authentication Model

  • Authentication is implicit
  • If the server can successfully decrypt and parse a message, the device is considered valid
  • No explicit handshake is required
  • Fully compatible with existing firmware

Running the Server

python main.py

CLI Usage

List Connected Devices

list
*Example d'output:*

ID           IP              CONNECTED
----------------------------------------
ce4f626b     192.168.1.42    2m 14s
a91dd021     192.168.1.43    18s

The CONNECTED column shows how long the device has been connected to the c2

Help Commands

        help [commands]
*example:* help
output:

=== C2 HELP ===

CLI Commands:
  help [cmd]               Show this help
  list                     List connected ESP devices
  send <target> <command>  Send a command to ESP(s)
  group <action>           Manage ESP groups
  clear                    Clear the screen
  exit                     Exit the C2

ESP Commands:

  reboot     Reboot ESP

DEV MODE ENABLED:
  You can send arbitrary text commands:
  send <id> <any text>
  send group <name> <any text>
  send all <any text>

Help System

General Help
help

Help for a Specific ESP Command
help reboot

Help for the send Command
help send


The help output is dynamically generated from the registered commands.

Sending Commands

    send <esp_id> <command>
*example:* send ce4f626b reboot # The device named "ce4f626b" will reboot

Send to All Devices

    send all [command]
*example:* send all reboot

Send to a Group

    send group bots 
*example:* send group bots reboot

Developer Mode (RAW Commands)

When DEV_MODE = True, arbitrary text commands can be sent:

    send <id> [test 12 34]
*example:* send ce4f626b custom start stream
output **ce4f626b:** "start stream"

The commands are sent as-is inside the Command.command field.

Groups

Add Devices to a Group

    group add "group_name" <id/s>
*example:* group add bots ce4f626b a91dd021

### List Groups
```md
    group list
*Example output:*
bots: ce4f626b, a91dd021
trilat: e2, e3, e1

Show Group Members

    group show [group]
*example:* group show bots
output:
bots: ce4f626b, a91dd021

Remove a Device from a Group

group remove bots ce4f626b

Command System Adding a New ESP Command

Create a new file in commands/, for example status.py

Implement the command handler:

from commands.base import CommandHandler from proto.command_pb2 import Command

class StatusCommand(CommandHandler): name = "status" description = "Get device status"

def build(self, args):
    cmd = Command()
    cmd.command = "status"
    return cmd.SerializeToString()

Register the command in main.py:

commands.register(StatusCommand())

The command will automatically appear in:

CLI tab completion

help

send

Protocol Definition

// explain nano pb

Command

message Command {
  string command = 1;
}

Response

message Response {
  string tag = 1;
  string id = 2;
  string message = 3;
  bytes response_data = 4;
}

Log

message Log {
  string tag = 1;
  string id = 2;
  string log_message = 3;
  uint32 log_error_code = 4;
}

Communication

The communication between c2 and bots are end-to-end encrypted.
Method:

    - ChaCha20 symmetric encryption
    - Base64 transport encoding
    - Encryption logic centralized in core/crypto.py
    - Fully compatible with current ESP firmware

Design Limitations (Intentional)

    - No persistent storage (groups reset on restart)
    - No request/response correlation (request-id)
    - No permissions or role management
    - No dynamic plugin loading

These are deferred intentionally to keep the core system minimal and clean.

Suggested Future Extensions

Todo and additional features:

- Plugin system (camera, proxy, trilateration/multilateration / etc.. )
- Persistent user & group storage (JSON) (Multi-Flasher -> devices.json -> id-list.csv [Allow ID on c2])
- Idle time display (last-seen)
- Request/response correlation with request-id
- Protocol versioning

Authors

- @off-path
- @Eun0us