semaeopus

A realistic CubeSat hacking platform. Build a FlatSat from breadboards and Pi Picos, or run it in a software-only simulator on your laptop. Learn satellite communications security by attacking your own spacecraft.

Try it now  → View on GitHub README
v0.2 · L00–L12 runnable ISM 433 / 915 MHz CCSDS-lite over 2-GFSK 37 tests passing ~ $35 BOM

$what is it

Semaeopus models the TT&C link (telemetry, tracking and command) of a real CubeSat closely enough that lessons transfer to flight hardware — yet builds from through-hole modules on a solderless breadboard. The on-air protocol is a deliberately simplified version of CCSDS Space Packet, carried over 2-GFSK on the CC1101 — the same shape of stack flown today.

Two halves of the link

Build both the satellite and the ground station. Then build a second ground station — the attacker — and watch the same protocol from the wrong end.

Four security levels

Ships at L0 (cleartext, no auth) so attacks are trivial. Bump SECURITY_LEVEL through L1 (HMAC), L2 (HMAC + counter), L3 (AES-CTR + HMAC) as the curriculum progresses.

Hardware-free path

A UDP-multicast "ether" runs the same firmware as the flight build. Plus a synthetic GFSK IQ recording for the SDR lessons. Start before parts arrive.

Legal by default

433.92 MHz EU ISM or 915 MHz US Part 15.247, with a 17 cm whip and 0 dBm. Reaches across the bench, not your neighbour.

$try it now

Three independent paths. Pick whichever matches the gear you already have.

A · no hardware

simulator

Virtual satellite + virtual ground stations over UDP. Replay and inject work end-to-end.

$ git clone https://github.com/haxorthematrix/semaeopus
$ cd semaeopus
$ pip install pyserial pytest
$ python -m sim.virtual_satellite &
$ python -m groundstation.operator.gs --sim
op> ping
op> safe
# in another terminal — forge a FORCE_SAFE
$ python -m groundstation.attacker.inject \
       --sim --apid 0xFF
B · no SDR

synthetic RF

A 2.7-second .cu8 recording of a 2-GFSK Semaeopus session, ready for GNU Radio / inspectrum / gqrx.

$ python -m tools.generate_iq
# writes captures/baseline.iq + .jsonl
$ gqrx                            # File → I/Q file…
# or follow lessons/L02_demod_gnuradio.md
#
# The JSONL oracle has the decoded
# frames — compare against your demod.
C · real hardware

flat-sat build

~ $35 of through-hole parts. No PCBs, no SMD soldering — breadboard + Dupont wires only. Seven bring-up scripts verify each subsystem before you flash the full firmware.

# BOM: Pi Pico + CC1101 + BME280
#      + MPU6050 + INA219 + DS3231
#      + SSD1306 OLED + breadboard
$ mpremote connect /dev/ttyACM0 \
       run bringup/02_i2c_scan.py
$ mpremote cp -r firmware/satellite/. :/
$ python -m groundstation.operator.gs \
       --port /dev/ttyACM1

$bill of materials

Three sub-builds. All through-hole or pre-soldered breakouts — no PCB fab, no SMD soldering. Specific Amazon links →  ·  hardware/ folder.

satellite · ~$35

flat-sat

  • Raspberry Pi Pico (or Pico W / 2 / 2 W)
  • CC1101 433/915 MHz module (E07-M1101D)
  • SSD1306 0.96″ I²C OLED
  • BME280 — temp / pressure / humidity
  • MPU6050 — IMU (ADCS analogue)
  • INA219 — power telemetry
  • DS3231 RTC + CR2032
  • 2× LEDs, 2× 220 Ω resistors
  • Half-size breadboard + Dupont kit
  • 17 cm ¼-wave whip wire
operator GS · ~$20

ground station

  • Raspberry Pi Pico
  • CC1101 module (match satellite band)
  • SSD1306 OLED — link status
  • Half-size breadboard + Dupont
  • 17 cm ¼-wave whip wire
  • USB cable → laptop
attacker · $45 / $360

two tiers

Tier 1 (~ $45) — sufficient for L00–L09:

  • RTL-SDR v3 + telescopic antenna
  • Pi Pico + CC1101 for active TX

Tier 2 (~ $360 total) — unlocks L10 jamming + GPS spoofing:

  • + HackRF One + ANT500

$dependencies

Python 3.11+ is the only hard requirement. Everything else is by path.

Required (any path)

pyserial, pytest. pip install pyserial pytest.

TUI dashboard (optional)

textual, rich. Adds the live operator UI with link status + telemetry panes.

SDR / GNU Radio path

gnuradio ≥ 3.10, gr-satellites, rtl-sdr, optionally hackrf, gqrx, inspectrum.

Security level 3

pycryptodome for AES-128-CTR on the host (MicroPython has it built in).

Hardware path

mpremote to push code to the Pi Pico, plus a MicroPython UF2 (1.22+).

Tested on

macOS 14+, Ubuntu 22.04+. Windows works via WSL2 for the GNU Radio path; native PowerShell for everything else.

$architecture

Same protocol on every path. The simulator swaps the CC1101 PHY for a UDP socket; everything above that is bit-identical.

┌─────────────────┐                         ┌─────────────────────┐
│ "SATELLITE"     │                         │ OPERATOR GROUND     │
│ (FlatSat)       │   <── 433/915 MHz ──>   │ STATION             │
│                 │       ISM downlink      │                     │
│ Pi Pico + CC1101│       ISM uplink        │ Pi Pico + CC1101    │
│ + housekeeping  │                         │  ↕ USB-serial       │
│ sensors & disp  │                         │ Laptop: gs-operator │
└─────────────────┘                         └─────────────────────┘
         ▲
         │                                  ┌─────────────────────┐
         │                                  │ ATTACKER STATION    │
         └──── eavesdrop / inject ─────────►│                     │
                                            │ RTL-SDR v3 (RX)     │
                                            │ + Pi Pico + CC1101  │
                                            │   or HackRF (TX/RX) │
                                            │ Laptop: gs-attacker │
                                            │ + GNU Radio         │
                                            └─────────────────────┘

$curriculum

A 12-step path from "see the signal" to "take over an authenticated link". All 13 lessons (L00–L12) are written and runnable today.

#TitleSim only?
L00Build & first beaconpartial
L01Spectrum surveyuse IQ
L02Demod in GNU Radiouse IQ
L03Frame sync & CRCuse IQ
L04Telemetry decodeyes
L05Replay attackyes
L06Command injectionyes
L07HMAC bypass via replay (L1)yes
L08Counter-bound HMAC (L2)yes
L09Timing side-channel — recovers full HMAC tagyes
L10Encryption + jam & replaypartial
L11Beacon spoofingyes
L12Capstoneyes

$safety & ethics

// read before transmitting

Defaults are 0 dBm on 433.920 MHz with a 17 cm whip — within EU/R1 ISM limits and an order of magnitude below US Part 15. Switch to 915 MHz for US compliance.

No external power amplifiers. No transmissions on amateur satellite frequencies (435–438 MHz UHF).

Practice attacks only on systems you own, or with explicit written permission. The point of Semaeopus is to make you better at defending real spacecraft — not to provide tooling for harming them.