Repository navigation
Attack Vectors
PWNCUBE inherits FlatSat's documented vulnerability catalog (30+ findings) — same protocol, same architecture, same bug classes, ported deliberately. Of those, 8 have been built into standalone, hardware-validated attack scripts, each validated on real hardware — not simulated, not theoretical — covering every major exploitation class (auth bypass, injection, replay, spoofing, DoS). The scripts live in a companion Attacks/ repository (to be published separately). Where an attack has both a USB variant (talking to the board's own Linux userspace over the gadget console) and a real-RF variant (HackRF uplink transmission, RTL-SDR downlink reception), both are included; the USB path and the RF path exercise the exact same firmware dispatch code (see CCSDS Protocol), so results transfer directly between the two.
Every script lives in its own numbered folder with a steps.txt (USB) and/or steps_rf.txt (RF) runbook containing exact commands and real captured output.
Black-box discovery: sweep a range of APIDs, sending a small probe to each, and classify the response. The firmware always replies with a structurally valid ERROR frame (0x009) to an APID it doesn't recognize — so every probe is informative, whether or not the command exists.
Finding: zero rate-limiting, zero authentication gate on reconnaissance-class traffic. An attacker can map the entire command surface before ever sending a "real" command.
Fully passive: listen to the downlink (916 MHz) and decode whatever arrives, no transmission at all.
Finding: PWNCUBE transmits everything in the clear — sensor telemetry, mission status, ground-station distance, even the authentication challenge/response from the GS handshake. Unlike FlatSat (which at least requires knowing a static AES key), PWNCUBE's downlink needs no cryptographic step whatsoever to read. Confirmed on real hardware: 24 packets captured and fully decoded in under a minute, including STATUS, GS_STATUS (ground-station coordinates visible in the clear), and PING.
A single BROADCAST_MSG (0x06) telecommand with a 0-byte payload triggers an integer underflow in the firmware's message-length calculation, producing a stack buffer overwrite in the real-time core.
uint16_t mlen = pdlen - 2; /* underflows to ~65535 when pdlen < 2 */
memcpy(mbuf, pkt->data + 2, mlen); /* stack smash */Finding: critical severity. One malformed packet, no authentication required, crashes the RISC-V real-time core. Confirmed on real hardware: the internal rpmsg command channel between the two cores dies permanently after the crash (dmesg: rockchip-mailbox: The mailbox channel is busy, repeating indefinitely) — the Linux side stays alive, but no command reaches the flight-critical core again until a physical power-cycle. This is a stronger outcome than FlatSat's equivalent bug, which only causes a clean reboot.
SET_THRUSTER (0x04) sets real thruster power (0–255, no clamping) with zero authentication — not a bug, the command works exactly as designed; the vulnerability is the complete absence of a ground-station authorization requirement on an actuator command.
Finding: confirmed on real hardware across multiple sessions — thruster power changed on demand (e.g. [10,10] → [255,10]) with no credentials, no handshake.
A debug hook, GPS_OVERRIDE (0x0A), injects an arbitrary latitude/longitude/altitude/satellite-count directly into the firmware's shared position state, with zero plausibility checking and zero rate-of-change limiting — a spoofed fix can jump anywhere on Earth instantaneously, as often as desired.
Finding: confirmed on real hardware; the injected fix is reflected immediately in mission telemetry and (once the real GPS receiver is also in the picture — see Hardware Anatomy) takes precedence over the real receiver's own fix whenever the override is active, by design — see Firmware/docs/peripherals/gps-neo6m.md for exactly how the two sources are kept separate.
The ground-station "auth" handshake (GS_ACCESS, 0x12) is a challenge/response scheme where the expected response is simply challenge XOR 0xC0DEFACE — a static, hardcoded key baked into the firmware binary. The challenge itself is transmitted in the clear (see Attack 01), so a single observed handshake is enough to recover the key trivially, with no cryptanalysis required.
Finding: confirmed end-to-end on real hardware — capture or predict a challenge, XOR it against the known key, submit the forged response, and the gate opens (gate_open=True), granting a 300-second authenticated session with zero real credentials.
The firmware's telecommand sequence counter is never validated on receipt — a byte-for-byte identical packet can be retransmitted and re-executed with no rejection.
Finding: confirmed on real hardware two independent ways — sending the identical PING twice (both over USB and over real RF) produces two separate executions, provable because the firmware's own outgoing telemetry sequence counter advances both times (e.g. 233 → 235), proof of two real executions rather than one cached response.
The simplest packet in the whole dossier: RESETC (0x02), no payload, no authentication.
Finding: worse than a clean reboot. Confirmed on real hardware, repeatedly: after RESETC, the internal rpmsg channel to the real-time core is left permanently dead — identical symptom to Attack 02 (mailbox channel is busy in dmesg, looping indefinitely). The Linux console stays responsive, but the flight-critical command path never recovers without a physical power-cycle. An unauthenticated reset command, on this firmware, is functionally a permanent denial-of-service against the spacecraft's own command channel.
Two of these eight attacks (02 and 07) leave the board's internal command channel dead until someone physically power-cycles it. If you're running these live, plan for that — don't chain either of them into another attack that needs the rpmsg channel without a power-cycle in between, and if you're demonstrating both in one session, budget for two separate recoveries, not one.