wardriver build screenshot of wardriver

 

Introduction

I turned a Raspberry Pi 4B into a mobile signals intelligence platform that runs headless in a case, logs every Wi-Fi network it passes, captures packets, records GPS coordinates for every device it sees, and scans for cell towers. All accessible remotely from anywhere in the world through a reverse SSH tunnel.

This is a documentation of the full build from scratch.

 

The Hardware

  • Raspberry Pi 4B - the brain
  • Alfa AWUS036AXML - dual-band Wi-Fi adapter with MediaTek MT7921AU chipset, supports monitor mode natively on Linux
  • G-Mouse USB GPS antenna (u-blox 8 chipset) - shows up as /dev/ttyACM0, NMEA at 9600 baud
  • HackRF One - software defined radio covering 1 MHz to 6 GHz for cell tower scanning
  • VPS (DigitalOcean) - acts as a relay for the reverse SSH tunnel

 

Kismet Wardriving

Kismet is the wardriving engine. It runs the Alfa adapter in monitor mode and passively captures every beacon frame in range without sending a single packet. No active probing, no deauth, completely passive.

What Kismet logs per session:

  • .kismet - SQLite database with every device, MAC, SSID, encryption type, signal strength, and GPS coordinate
  • .wiglecsv - ready to upload to WiGLE.net, the global wardriving database
  • .pcapng - raw packet capture, open in Wireshark
  • .gpx - GPS track of the entire route

The web UI runs at port 2501 and shows a live map with every detected network plotted as you drive. You can access it from a phone on the same hotspot or tunnel it remotely.

Setup is automated in the wardriver repo:

git clone https://github.com/CyberDiary2/wardriver.git
cd wardriver
./setup.sh
~/start-wardriver.sh wlan1

 

The Reverse SSH Tunnel

The Pi has no fixed IP. It could be anywhere. The solution is a persistent reverse SSH tunnel using autossh. The Pi connects outbound to the VPS on boot and keeps the tunnel alive:

/etc/systemd/system/autossh-tunnel.service

ExecStart=/usr/bin/autossh -M 0 -N \
  -R 2222:localhost:22 \
  -o ServerAliveInterval=30 \
  root@xxx.xxx.xxx.xxx

On the VPS, GatewayPorts yes in sshd_config allows the forwarded port to be reachable externally.

From any laptop with the right key:

ssh -p 2222 ops@xxx.xxx.xxx.xxx

You’re in the Pi, no matter where it physically is. To view the Kismet map remotely:

ssh -L 2501:localhost:2501 -p 2222 ops@xxx.xxx.xxx.xxx
# open http://localhost:2501

 

Cell Tower Scanning

This is where it gets interesting. Wi-Fi wardriving is well-documented. Cell tower scanning with a software defined radio is less common.

Why not just use RTL-SDR?

Most cell tower tools (gr-gsm, grgsm_scanner) target GSM (2G). That network is dead in the US. AT&T shut theirs down in 2017, T-Mobile in 2022. Running grgsm_scanner finds nothing because there’s nothing left to find.

Modern US cell infrastructure is almost entirely LTE (4G) and 5G NR. That requires different tools.

HackRF One

The HackRF is a $300 software defined radio covering 1 MHz to 6 GHz with 20 MHz bandwidth. Unlike the $25 RTL-SDR (receive only), HackRF can also transmit, though we’re only doing passive receive here.

Once plugged in:

hackrf_info
# Found HackRF One - Board ID: 4, Firmware: 2023.01.1

A quick wideband sweep confirms we’re receiving, with strong signals in the 700 MHz and 850 MHz LTE bands:

hackrf_sweep -f 700:900 -l 32 -g 40 -w 500000

SoapySDR Power Scanner

hackrf_sweep gives raw power levels but can’t decode anything. I wrote a Python scanner using SoapySDR (which supports HackRF natively) that sweeps all US LTE downlink bands and reports signal presence:

lte_scan

It sweeps:

  • Band 71 (T-Mobile 600 MHz)
  • Band 12/13/17 (700 MHz - AT&T and Verizon)
  • Band 5 (850 MHz CLR)
  • Band 2 (PCS 1900 MHz)
  • Band 4 (AWS 2100 MHz)

The scanner reports average and peak power per frequency. Strong signals that stand out from the noise floor are likely LTE carriers. Run it in the car, not indoors. Walls kill 700 MHz by 20+ dB.

srsRAN - Actual LTE Decoding

Power levels tell you something is there. srsRAN tells you what it is: the cell’s MCC (country code), MNC (network code), physical cell ID, and tracking area code. That’s what you need for IMSI catcher detection.

Currently building srsRAN from source with SoapySDR support:

git clone https://github.com/srsran/srsRAN_4G.git
cd srsRAN_4G && mkdir build && cd build
cmake .. -DENABLE_SOAPYSDR=ON
make -j4

Once built, cell_search will scan LTE bands and return full cell identity for every tower in range.

 

IMSI Catcher Detection

The end goal. IMSI catchers (Stingrays) are fake cell towers used by law enforcement and sometimes hostile actors to intercept phone traffic. They work by impersonating a legitimate tower and forcing phones to connect to them.

Detection approach:

  1. Drive regular routes, build a database of legitimate towers (frequency, cell ID, signal strength, GPS location)
  2. On each pass, compare observed towers against the database
  3. Flag anything that appears outside known carrier frequency plans, shows up only temporarily, or has anomalous signal characteristics

A real Stingray on LTE is harder to detect than GSM-era IMSI catchers. LTE has better authentication. But anomalous cells still have signatures: wrong PLMN ID, frequency mismatch with registered towers, unusual downlink power patterns.

This is the next phase of the build.

 

Current State

ComponentStatus
Kismet + Alfa wardrivingWorking
u-blox GPS + gpsdWorking
Reverse SSH tunnel via VPSWorking
HackRF via SoapySDRWorking
LTE power band scannerWorking
srsRAN LTE cell decoderBuilding
IMSI catcher detectionPlanned

All autostart on boot via systemd. The Pi sits in a case, powers on, and is accessible within 30 seconds.

Code at github.com/CyberDiary2/wardriver