Skip to content
V33RUPublic

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

Repository files navigation

rfsploit

RF reconnaissance, sub-GHz protocol decoding and BLE enumeration, built for authorised lab testing and vendor approved research.

Transmit is disabled by default and stays disabled until you explicitly enable it twice: once on disk, once per command.

What it does

Area Capability
Recon Wideband spectrum sweep, noise floor estimation, peak detection
Capture IQ recording in cs8, cu8, cs16 and cf32
Analysis Burst detection, OOK and FSK pulse extraction, symbol time recovery
Sub-GHz EV1527 and HS1527, PT2262 tri-state, KeeLoq framing, Manchester, PPM
Key fobs Car/gate remote analysis: modulation, protocol, fixed vs rolling code
Aviation ADS-B on 1090 MHz: callsign, altitude, velocity, CPR position
Cellular Passive GSM/LTE downlink survey by ARFCN/EARFCN, GSM FCCH presence
BLE Advertisement scanning and GATT enumeration through the host adapter
Transmit Raw IQ replay and synthesised PWM codes, both authorisation gated

Modules

Capabilities are modules in a registry rather than hardcoded subcommands, so adding a protocol means adding one file:

rfsploit modules                 # list everything, grouped by category
rfsploit search keeloq           # find a module by protocol, band or category
rfsploit info decode/adsb        # options, types, defaults and references
rfsploit run decode/adsb duration=30

Options are OPTION=VALUE and are validated before any hardware is touched, so a typo or an out of range value fails immediately rather than halfway through a capture:

$ rfsploit run decode/adsb durartion=10
[!] decode/adsb: unknown option(s) durartion. Known options: input, duration,
    backend, lna_gain, vga_gain, amp, format, device

A module name can be abbreviated when it is unambiguous, so run subghz and run decode/subghz are the same thing.

ADS-B

Aircraft broadcast identity, position and velocity in the clear on 1090 MHz. Reception is entirely passive.

rfsploit run decode/adsb duration=30
ICAO     Callsign   Alt ft  Speed kt  Track   Latitude   Longitude  Msgs
40621D              38000                     52.25720     3.91937    12
4840D6   KLM1023                                                       3

Frames failing the 24 bit CRC are discarded rather than reported: a corrupted position is worse than no position. Positions require a matched pair of even and odd CPR frames, so an aircraft can appear with no position until both arrive. This needs a 1090 MHz antenna with a view of the sky; a sub-GHz whip will hear almost nothing.

Cellular survey

Passive reconnaissance of what cellular networks broadcast: which downlink channels are on air and what channel number they use. It transmits nothing, and it does not collect any subscriber data. This is the opposite of an IMSI catcher (see "Not included, by design").

rfsploit run recon/cellular band=b3          # LTE band 3, list active carriers
rfsploit run recon/cellular band=gsm900 confirm=true   # GSM, confirm the top hits
3 LTE carrier(s):
   EARFCN         MHz   BW MHz       dB     SNR
     1612   1846.1784    14.76    -19.0    43.9
     1311   1816.1193    18.10    -37.1    25.8

GSM channels are 200 kHz wide, so each active ARFCN is one peak. LTE carriers are 1.4 to 20 MHz wide, so they are detected as blocks of elevated power and the carrier centre is mapped to an EARFCN; the reported bandwidth is the width of that block. The band-plan arithmetic (3GPP TS 45.005 for GSM, TS 36.101 for LTE) is pinned in tests to published anchor frequencies.

confirm=true on a GSM band, or the standalone decode/gsm-fcch module, captures a channel and looks for the frequency-correction burst (FCCH), a pure tone at 67708 Hz above the carrier that only a live base station transmits. Finding it proves a real GSM downlink and measures the receiver's frequency error:

rfsploit run decode/gsm-fcch arfcn=79 band=gsm900
FCCH tone found: live GSM downlink
  tone offset   : 68320 Hz (ideal 67708)
  frequency err : 612 Hz
  tone duration : 584 us

The FCCH recurs only a few times per 235 ms multiframe and only on a network's BCCH carrier, so a single short capture can miss it; a miss does not prove the channel is dead. This is presence and timing only. It does not decode the network identity (MCC, MNC, LAC, Cell ID); that needs full GSM demodulation with a tool such as gr-gsm.

Key fob analysis

Identify a car or gate remote and classify its security. It reports the carrier, the modulation (OOK vs FSK), the decoded protocol, and whether the code is fixed or rolling. This is analysis of a remote you own.

# capture the same button twice, then compare
rfsploit run capture/iq freq=433.92M output=press1.cs8 duration=4
rfsploit run capture/iq freq=433.92M output=press2.cs8 duration=4
rfsploit run decode/keyfob input=press1.cs8 input2=press2.cs8
  modulation : OOK (AM depth 0.98, FM spread 19960 Hz, high confidence)
  decoded    :
    ev1527        24 bits  hex=B385AD  serial_hex=B385A  button_4bit=13
  security   : FIXED
  two presses of the button decoded to the same payload, so the code does not
  change; a fixed code is replayable

The fixed-vs-rolling test is passive and needs no key: press the same button twice and diff the frames. Identical every time means a fixed code (EV1527, PT2262), which is replayable. Different every time means a rolling code (KeeLoq and similar), which is not. Band presets are us (315 MHz, North America and Japan), eu (433.92 MHz, most of the world) and eu868 (868.3 MHz, Europe).

A fixed code, once confirmed on a remote you own, can be resent with the gated tx/replay module. rfsploit does not implement attacks against vehicles: no RollJam or jam-and-replay, no rolling-code prediction or key recovery, no jamming, no relay/PKE range extension, no cloning. See "Not included, by design".

Hardware

Backend Receive Transmit Requires
hackrf yes yes hackrf_transfer, hackrf_sweep
rtlsdr yes no rtl_sdr, rtl_test
soapy yes yes SoapySDR Python bindings
file yes writes to disk nothing

Every module runs a capability preflight before it touches hardware. Missing tooling, an absent device, an out of range frequency or sample rate, a receive only radio asked to transmit, or a radio already claimed by another process all fail immediately with the command that fixes them.

$ rfsploit capture -f 8G -s 2M -d 1 -w out.cs8
[!] capture cannot run on this host:
  - frequency: 8000.0000 MHz is outside the hackrf range 1-6000 MHz
    fix: retune within the device range, or use a different radio

Add -v to print every check, including the ones that passed.

Quick start, no install

rfsploit.py runs straight from a checkout. It puts src/ at the front of the import path itself, so only numpy and scipy are needed:

git clone https://github.com/V33RU/rfsploit
cd rfsploit
python3 rfsploit.py            # start the interactive console
python3 rfsploit.py devices    # or run a single command
python3 rfsploit.py sweep --start 433M --stop 435M

It is a thin entry point that hands every argument to the same CLI as the installed rfsploit command and as python3 -m rfsploit; the three are interchangeable. With no arguments it starts the console; with arguments it runs that one command and exits.

Console

The console is a command shell with module context, in the style of msfconsole. It reuses the CLI for execution, so run is exactly a rfsploit run under the hood.

$ rfsploit
rfsploit > search adsb
  decode/adsb          Decode ADS-B aircraft position, callsign and velocity on 1090 MHz
rfsploit > use decode/adsb
rfsploit(decode/adsb) > show options
rfsploit(decode/adsb) > set duration 30
rfsploit(decode/adsb) > run
Command Effect
search <term> find modules by name, band or protocol
use <module> select a module (short names work: use adsb)
show options list the module's options and current values
set <opt> <value> set an option (validated immediately)
unset <opt> clear an option back to its default
run (or exploit) run the module with the options set
info [module], back, help, exit as expected

Required options that are still unset are shown in red, advanced tuning options are hidden behind show advanced, and any shell command (sweep ..., tx-enable) also works at the prompt. Tab completion covers commands, module names and option names. Transmit modules refuse to run until tx-enable has been run and authorized is set true.

Install

git clone https://github.com/V33RU/rfsploit
cd rfsploit
pip install -e ".[ble,dev]"

Host tools for a HackRF on Debian or Ubuntu:

sudo apt install hackrf

Usage

Check what the host can do:

rfsploit devices

Survey a band and list the active carriers:

rfsploit sweep --start 433M --stop 435M --sweeps 8 --threshold 12

Record two seconds of IQ:

rfsploit capture -f 433.92M -s 2M -d 2 -w remote.cs8

Decode a captured remote:

rfsploit decode -i remote.cs8 -s 2M -f 433.92M --threshold 20

Decode straight off the radio:

rfsploit decode -f 433.92M -s 2M -d 10 --threshold 20

Inspect timing when nothing decodes:

rfsploit bursts -i remote.cs8 -s 2M --threshold 20 --extract-dir bursts/
rfsploit decode -i bursts/burst_000.cs8 -s 2M --show-pulses

Scan for BLE devices and enumerate one you own:

rfsploit ble-scan -d 10
rfsploit ble-enum AA:BB:CC:DD:EE:FF

Machine readable output for any command:

rfsploit sweep --start 433M --stop 435M -o sweep.json --json

Transmit

Transmit requires two independent steps, so no single command can key the radio:

rfsploit tx-enable                     # writes the authorisation file, once
rfsploit replay -i remote.cs8 -f 433.92M -s 2M --i-am-authorized
rfsploit transmit-code 101100111000010110101101 -f 433.92M --te 350 --i-am-authorized
rfsploit tx-disable                    # revoke

tx-status reports the current state. Transmitting outside the common ISM bands is not blocked, but it is called out in the output.

Sending a synthesised code rather than replaying raw IQ is the stronger proof: if the receiver acts on transmit-code, the recovered bits and symbol time were correct, which a raw replay does not establish.

Reading the output

decode reports the protocol, bit count, hex, recovered symbol time and how many times the frame repeated. A frame seen once carries a note saying so: remotes normally repeat, and a single frame is more likely to be a decoding artefact than a real code.

Burst detection estimates its noise floor from the capture itself, which fails on a fully occupied band. When the result looks unreliable the tool says so rather than presenting it as clean:

[!] The threshold did not cleanly separate signal from noise. Adjust --threshold
    and re-run. A dynamic range under 3 dB means the capture is either dead air
    or one unbroken carrier.

Truncated symbols at a capture boundary are dropped, never guessed. A decoder returns the bits it observed or nothing at all.

Limits

  • KeeLoq frames are parsed, not decrypted. The hopping code needs the manufacturer key, and the rolling counter means a captured frame the receiver has already seen will not replay.
  • BLE goes through the host Bluetooth adapter, not the SDR. A HackRF cannot follow a BLE connection: it hops 1600 times a second across 40 channels, which needs an Ubertooth One, nRF52840 or similar. Scanning and GATT enumeration work because the host adapter connects as an ordinary central.
  • ble-enum reports characteristics that advertise a write property over an unpaired connection. It does not write to them. Confirm the effect against your own device before treating that as a finding.
  • The RTL-SDR and SoapySDR backends are implemented but were not verified against hardware, since neither was available on the development host. The HackRF and BLE paths were verified end to end.
  • ADS-B decoding is verified against published Mode S frames and against synthesised RF, but no live aircraft were received on the development host: a sweep of 1085 to 1095 MHz showed flat noise, meaning nothing was reaching the antenna. The decode path is proven, the receive path is not.
  • The GSM FCCH detector was verified two ways: against synthesised tones (clean, frequency-shifted, low-SNR, noise and random-traffic cases) and against live base stations on the development host, where it confirmed three GSM downlinks and measured their frequency error. Over-air detection is per-capture and intermittent, so a miss is not proof of absence.

Not included, by design

  • No IMSI catcher. That is an active fake base station: it forces phones belonging to uninvolved people to attach to it. It targets third parties rather than equipment under test, and is illegal in most jurisdictions.
  • No GPS spoofing or jamming, which breaks navigation for aircraft, shipping and road traffic well beyond any test bench.
  • No vehicle attacks. The key fob module classifies fixed vs rolling codes but implements none of the techniques that steal cars: no RollJam or jam-and-replay, no rolling-code prediction or counter desync, no cryptographic key recovery wired to a transmitter, no relay / passive-entry range extension, no fixed-code brute force (De Bruijn / OpenSesame), and no fob cloning. Replaying a fixed code on a remote you own, through the gated tx/replay module, is the one transmit path, and it is for your own equipment.

Passive receive and decode of broadcast navigation, aviation, cellular and satellite signals is in scope. The cellular survey reads only what a network beacons to everyone (which channels are active, what channel number they use). Subscriber identifiers are not collected.

Roadmap

  • Aviation and maritime: ADS-B is done, AIS on 162 MHz is next
  • Satellite downlinks: NOAA APT and Meteor LRPT weather imagery, Inmarsat STD-C
  • Cellular: survey is done; GSM system-information decode (MCC/MNC/LAC/CID) via a gr-gsm passthrough when that tooling is present
  • Utility and telemetry: rtl_433 style sensors, TPMS, POCSAG and FLEX paging

Tests

pytest

The decoder tests need no radio. They synthesise a known signal, push it through the full receive path with added noise, and assert the exact bits come back. EV1527 recovery is verified down to 5 dB SNR.

Scope

For equipment you own or have written authorisation to test. Transmitting on licensed spectrum without authorisation is illegal in most jurisdictions. Keep transmit work in a shielded or attenuated setup.

License

MIT. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages