Skip to content

Overview

Espilon is an ESP32 embedded agent framework for security research. A device running Espilon boots into a minimal runtime - crypto, transport, and the ESPM module loader - with zero hardcoded behavior. Every capability is delivered at runtime as a signed C module, compiled offline and injected into IRAM over an encrypted Management Protocol channel. A power cycle leaves nothing behind.

Authorized Use Only

Espilon is a security research tool. Deployment against devices or networks you do not own or have no explicit written authorization to test is illegal. Use only in controlled environments, authorized engagements, or educational contexts.

The three components

Component Language Role
Espilon-Firmware C / ESP-IDF 5.3.2 The agent: a hollow-shell firmware with the ESPM loader and crypto stack
C3PO Python 3.11+ The operator: a Qt6 app combining a Management Protocol server, module compiler, and provisioner
ESPM C The module system (ABI + loader), kept in espilon-test/ESPM and copied into the firmware

Architecture

flowchart LR
    subgraph OP["C3PO operator (Qt6 + asyncio)"]
        V["Fleet / Device / Modules / Data / Keystore / Provision"]
        SRV["Management Protocol server :2626"]
        MC["compile + sign + inject"]
    end
    subgraph T["Transport"]
        WIFI["WiFi STA"]
        GPRS["GPRS / PPP"]
    end
    subgraph AG["ESP32 agent"]
        FW["Hollow shell<br/>crypto + transport + ESPM"]
        MOD["IRAM modules<br/>(injected at runtime)"]
    end
    SRV ---|"ChaCha20-Poly1305 + protobuf"| WIFI & GPRS
    WIFI & GPRS --- FW
    MC -->|"signed ELF"| FW
    FW --> MOD

The agent connects outbound to C3PO over TCP. C3PO authenticates each connection during a silent handshake (no plaintext device id), derives a per-device session key, and registers the device. The operator then sends commands and injects modules.

How it works

  1. Provision. C3PO generates a per-device 32-byte master_key, builds firmware, writes the encrypted config, flashes the device, and records the key in keys.json.
  2. Boot. The firmware derives its keys from master_key, wipes the master from RAM, decrypts its config, and connects to the Management Protocol server.
  3. Operate. From the Device view you run built-in commands and inject modules from the catalog.
  4. Inject. C3PO compiles a module for the device's chip, signs it (HMAC-SHA256), and streams it in; the firmware verifies, relocates, and runs it from IRAM.
  5. Clean up. Stopping a module or power-cycling the device zeroes its RAM. Nothing offensive persists.

Key properties

  • Hollow shell. No credentials and no capabilities in the binary at rest.
  • Encrypted C2. ChaCha20-Poly1305 with per-device keys; signed modules; encrypted NVS config.
  • Strong isolation. Per-module watchdogs and Xtensa panic isolation.
  • No trace. Modules live only in RAM unless explicitly persisted.

Next steps