Rayhunter — deploying and reading an IMSI-catcher detector¶
Investigated 2026-08-26 against Rayhunter v0.12.0. Every claim below about what ships and what it needs was checked against the repository and the release artifact; the two things not tested are named at the end.
What Rayhunter is, and why it is in rf-security and not rf-research¶
Rayhunter is the EFF's detector for IMSI catchers — cell-site simulators, also called stingrays. It runs on a cheap mobile hotspot, watches the cellular control traffic that device already sees, and flags patterns characteristic of a simulator rather than a real network.
It is a defensive tool. It detects surveillance; it does not conduct it. It transmits nothing, emulates no network, and collects no identifiers belonging to anyone but the device it runs on.
That matters for where it lands, and the topic adjacency will confuse people:
DragonOS's cellular/EW cluster and Rayhunter both say "IMSI catcher" and are
opposites. Rayhunter belongs in rf-security, ungated. The transmit-capable
cellular stacks that Q-008 governs are a different kind of thing and none of
the D-021 risk categories fits Rayhunter — it does not transmit, does not
intercept communications not addressed to the device, and does not touch anyone
else's systems.
EFF publishes its own legal note with the project, which is worth reading and is not reproduced or interpreted here.
What we can and cannot install¶
Rayhunter itself is firmware for a hotspot. We cannot install it, in the same way we cannot install a radio's firmware by running apt. What Hammunition can do is provide the host side: the tooling that deploys it, the tooling that reads what it produced, and documentation for the parts in between.
| Piece | Where it runs | Can we install it? |
|---|---|---|
rayhunter-daemon |
on the hotspot | No — deployed to the device by the installer |
installer |
your machine | Yes — prebuilt Linux binary |
rayhunter-check |
your machine | Yes — same release artifact |
tools/*.py |
your machine | Yes — Python, needs a venv |
| PCAP analysis | your machine | Yes — wireshark/tshark, already Tier 1 |
The cargo question — measured, and the answer is no¶
D-014 records cargo at zero occurrences across the inventoried sources
and says backends are justified by measurement rather than convention. Rayhunter
looked like the first real counter-example: it is a Rust project, 2.6 MB of it,
with Cargo.toml and Cargo.lock at the repository root.
It is not a counter-example. Upstream publishes prebuilt binaries for every platform it supports:
rayhunter-v0.12.0-linux-x64.zip + .sha256
rayhunter-v0.12.0-linux-aarch64.zip + .sha256
rayhunter-v0.12.0-linux-armv7.zip + .sha256
The linux-x64 zip contains the installer, the rayhunter-check analyser
built for five platforms, the rayhunter-daemon that gets deployed to the
device, and the init scripts. Nothing is compiled on the user's machine.
cargo stays at zero. The binary backend, which is already required for 1.0,
covers this completely. D-014 is satisfied on its own terms: we looked for a
unit that requires cargo, the most promising candidate does not, and the measured
count does not move.
Rayhunter is also the first upstream in this entire project that publishes
checksums. SCOPE.md says of the pin/hash database that "not one of them
publishes checksums we can inherit" — across AHRL's 63 archives, 73Linux,
Skywave and DragonOS. Rayhunter publishes a .sha256 beside every asset.
Verified here:
published: 2472e86bcdc9fb6023996c06555365daee849a9fbbaa59900083ae3544bc54ee
computed: 2472e86bcdc9fb6023996c06555365daee849a9fbbaa59900083ae3544bc54ee
That is one manifest we can write with an inherited hash instead of a hash we pinned ourselves, and it is worth saying which project made that possible.
No adb package is needed either. The installer statically links EFF's fork
of the adb_client Rust crate and speaks USB directly through nusb. There is
no dependency on Android platform-tools.
Supported hardware¶
From upstream's own device list. Availability varies by region and by what the device's cellular bands support where you are — check that before buying.
| Device | Status | Region |
|---|---|---|
| Orbic RC400L (also branded Kajeet RC400L) | Recommended | Americas |
| TP-Link M7350 | Recommended | Africa, Europe, Middle East — works in the Americas, usually costs more |
| Wingtech CT2MHS01 | Functional | Americas |
| T-Mobile TMOHS1 | Functional | Americas |
| TP-Link M7310 | Functional | Africa, Europe, Middle East |
| PinePhone / PinePhone Pro | Functional | Global |
| FY UZ801 | Functional | Asia, Europe |
| Moxee hotspot | Functional | Americas |
The underlying requirement is a Qualcomm modem exposing /dev/diag, which
is why the list grows by community contribution rather than by vendor support.
The workflow, end to end¶
1. Get the release, and check it¶
curl -LO https://github.com/EFForg/rayhunter/releases/download/v0.12.0/rayhunter-v0.12.0-linux-x64.zip
curl -LO https://github.com/EFForg/rayhunter/releases/download/v0.12.0/rayhunter-v0.12.0-linux-x64.zip.sha256
sha256sum -c rayhunter-v0.12.0-linux-x64.zip.sha256
unzip rayhunter-v0.12.0-linux-x64.zip
Do the sha256sum -c step. Upstream went to the trouble of publishing it.
2. Deploy to the device¶
Connect to the hotspot over Wi-Fi or USB tethering and confirm you can reach its
admin page — http://192.168.1.1 for the Orbic, http://192.168.0.1 for the
TP-Link. Then:
./installer tplink for TP-Link hardware; ./installer --help lists the rest.
The device reboots itself when the installer finishes.
3. Read what it found¶
Rayhunter serves a web interface from the device. Captures come off as QMDL (Qualcomm diagnostic logs) and PCAP.
rayhunter-check— the offline analyser, shipped in the same zip. Run it against a downloaded capture to re-run the detection heuristics on your own machine rather than on the hotspot's very limited CPU.wireshark/tshark— for the PCAP side. Both are inrf-securityalready.tools/*.pyin the repository —asn1grep.py,nasparse.py,pcap_check.py, with arequirements.txt. A venv, not a system install.
What this means for the catalog¶
A rayhunter manifest is straightforward and unusually clean:
method: binary, per-architecture install blocks selecting the right zip —Selectoralready expresses that, and the three Linux artifacts map tox86_64,aarch64andarmv7l.sha256inherited from upstream rather than pinned by us. First one.- No
apt_repos, nosystem_modifications, noconfig_files. - Belongs to
rf-security, ungated. update.probe: github_releaseagainstEFForg/rayhunter.
One open point for the manifest. The installer talks to USB directly through
nusb rather than through adb, so it may need udev rules or root for raw USB
access to the hotspot in bootloader or diagnostic mode. Upstream's Linux
instructions mention neither, and this has not been tested against hardware — so
the manifest should not assert a udev rule it has not seen work. Note it, test
it, then write it.
What was not tested¶
- No device. Nothing here was deployed to an Orbic, a TP-Link or anything else. The workflow is upstream's, reproduced accurately; it is not a report of having run it.
rayhunter-checkwas not executed. Its presence in the archive is confirmed by listing the zip; its behaviour is not.- No capture was analysed, so nothing is claimed about detection quality, false-positive rates, or what its output looks like.
- The udev question above is open, and is the one thing most likely to bite a first-time user on Linux.
Per D-018, these are named rather than smoothed over. The checksum verification and the archive contents were tested, and those are the two claims this document actually leans on.