Repository navigation
CCSDS Protocol
PWNCUBE speaks the exact same command protocol as FlatSat — same header layout, same bit widths, same APID numbers for every command both platforms share. If you already know FlatSat's protocol, you already know PWNCUBE's.
Every packet — telecommand (TC, uplink) or telemetry (TM, downlink) — starts with a 6-byte primary header:
| Field | Bits | Meaning |
|---|---|---|
| Version | 3 | Always 000
|
| Type | 1 |
0 = TM (telemetry), 1 = TC (telecommand) |
| Secondary header flag | 1 | Not used by this platform (0) |
| APID | 11 | Application Process ID — identifies the command/telemetry type (see table below) |
| Sequence flags | 2 |
11 = unsegmented (the only mode used here) |
| Sequence count | 14 | A per-source counter — never validated on receipt by this firmware (see Attack 06 — Replay) |
| Packet data length | 16 | Payload length − 1, per the CCSDS spec |
Payload follows immediately after the header, length as declared in the header's data-length field (which is never cross-checked against what actually arrived — see Attack 02 — Fuzzing crash).
Unlike FlatSat (AES-128-ECB with a static key, enabled by default), PWNCUBE's downlink carries everything in plaintext with no encryption step at all. The only cryptographic layer that exists anywhere in this firmware is an optional AES-128-CTR mode on the uplink only, disabled by default (tier 0/1 = plaintext) — it exists for alignment with a separate, related firmware variant, not because PWNCUBE's own release configuration uses it. In practice: anyone within RF range can read every telemetry frame this board transmits, all the time, with no key required. See Attack 01 — Eavesdropping.
| APID | Name | TC | TM | Notes |
|---|---|---|---|---|
0x01 |
PING | ✓ | ✓ | Liveness check |
0x02 |
RESETC | ✓ | — | Unauthenticated reboot — leaves the internal rpmsg command channel permanently dead, not just a clean reboot; requires a physical power-cycle to recover |
0x03 |
SEND_FW | ✓ | ✓ | Firmware version disclosure |
0x04 |
SET_THRUSTER | ✓ | — | Sets thruster power (0–255, no clamping), no authentication. Never transmits a TM on success |
0x05 |
SET_BEACON_RATE | ✓ | — | Sets the beacon interval; 0 floods the downlink. Never transmits a TM on success |
0x06 |
BROADCAST_MSG | ✓ | — | A 0-byte payload triggers an integer-underflow stack overwrite — see Attack 02 |
0x07 |
FLASH | ✓ | ✓ | Reads back an embedded flash blob |
0x08 |
SEND_TM | — | ✓ | Combined sensor frame (accel/gyro/temp, BME280 temp/pressure/altitude/humidity, thruster power). Transmitted automatically every ~10.5s, not a response to a command |
0x09 |
ERROR | — | ✓ | Structurally valid reply to any APID the dispatcher doesn't recognize — useful for black-box enumeration |
0x0A |
GPS_OVERRIDE | ✓ | — | Debug hook: injects an arbitrary GPS fix (lat/lon/alt/satellite count) with zero validation or authentication |
0x0B |
TM_NAV | — | ✓ | Companion telemetry to GPS_OVERRIDE / the real GPS receiver — reports current position, fix validity, and receiver health |
0x0C |
STATUS | ✓ | ✓ | Mission snapshot: mode, thruster state, beacon interval, uptime, firmware version |
0x0D |
MISSION_MODE | ✓ | ✓ | Changes operating mode (SAFE/NOMINAL/PAYLOAD/SCIENCE/CONTINGENCY) |
0x0F |
PAYLOAD_STATUS | ✓ | ✓ | Exposes BROADCAST_MSG abuse as an unauthenticated RF relay |
0x11 |
GS_MODE | ✓ | ✓ | Enables/disables the ground-station access gate |
0x12 |
GS_ACCESS | ✓ | ✓ | The authentication handshake itself — challenge/response XORed against a static, hardcoded key |
0x13 |
GS_STATUS | ✓ | ✓ | Distance to the ground station and gate state |
Every attack in Attack Vectors targets one or more of these APIDs directly.
-
Real RF — an uplink telecommand transmitted at 918 MHz, received by
radio0, and handed to the samecommand_apid_handler()dispatch function. -
Local injection over USB — from the board's own Linux userspace,
radio_test tcsend <apid_hex> <payload_hex>builds the identical SPP packet and hands it to the exact same dispatcher, bypassing the radio entirely. This is how the USB-based attack scripts in this repo work, and it means anything demonstrated over USB reproduces identically over real RF, and vice versa — see Firmware Architecture.