WarPi, Raspberry Pi 3b for war driving, part 2

Six week update as I’ve been fine tuning the WarPi

Part 1 here

The WarPi has been working well for the past six weeks but I’ve been disappointed with its performance. It still captures hundreds more networks than my two phones on the same drive, but I was expecting more. The CSV files that I was uploading were 15k to 1MB at the largest. The sample column would have a few hundred to only a few thousand for a 10 minute file (since I’m restarting Kismet every 10 minutes).

Changes I’ve made:
1.) Dropped down to one usb wifi adapter
2.) Changed to the standard Alfa adapter
3.) Stopped converting the kismet files to csvs while war driving

Converting the kismets to csv was taking too much CPU. While it was convenient to get home and have all the files ready to upload it wasn’t worth the drain on the battery and the lost network detections. Stopping this practically doubled my samples per 10 minutes.

Changing adapters and going down to just one adapter practically had no effect. It turns out the real problem was the gpsd. I’d often get some files without any GPS data, but most of my files did have GPS. The problem was that the file didn’t have much GPS data so all the samples without valid GPS data were discarded during the conversion.

Make sure your GPS is working.

cgps -s

If your output looks like the following then you’ve got GPS problems. It might also exit with cgps: caught signal 2

cgps: caught signal 2

Make sure your GPS device is working. In my case I just cat the device or use gpsmon

cat /dev/ttyACM0
gpsmon /dev/ttyACM0

If you’re seeing data flowing in from the device then you may just need to restart gpsd. Mine isn’t working correctly on boot, so I’m restarting the service at boot with a script. I’m also restarting gpsd while restarting kismet every 10 minutes.

killall kismet
sleep 2
systemctl restart gpsd
sleep 10
ifdown eth0
sleep 5
ifup eth0
sleep 10 &&

Now a CSV for 10 minutes of data is 2MB to 4MB in size and contains 10k to 14k samples.

To do: Start adding more wifi adapters. Build a better carrying case.

WarPi – Raspberry Pi 3b+ for war driving

1.) Raspberry Pi 3b+
2.) Alfa AWUS036ACH
3.) etekcity SI-7200nd
4.) GPS vk-162
5.) ROMOSS Solo 5 10,000 mAh battery pack ( PH50-203)
6.) A button

Part 2 here

Download the latest Kali for Raspberry pi (currently 2019.3). Then burn it to your SD card using Etcher.

Connect to your pi using the ethernet and do your normal new Kali things, change your password, add a new user if you want to.

Personally, since I’m not using the GUI, I set my kali to boot into command line:

systemctl set-default multi-user.target

Now would be a good time to set up SSH only using keys.

Do some more kali stuff like update and upgrade and pray it doesn’t break.

Ensure that swapping is enabled.

Install GPS and enable GPS daemon

apt install gpsd gpsd-clients
systemctl enable gpsd

Install WiFi drivers

apt install realtek-rtl88xxau-dkms

Install Kismet from their repo

wget -O - https://www.kismetwireless.net/repos/kismet-release.gpg.key | sudo apt-key add -
echo 'deb https://www.kismetwireless.net/repos/apt/release/kali kali main' | sudo tee /etc/apt/sources.list.d/kismet.list
apt update
apt install kismet

When installing kismet be sure to add your users to the kismet group. FYI, running it as root will cause an exit code of 1 when shutting down the server (keep that in mind if you’re scripting things).

Configure kismet



Currently I’m using two 2.4 GHz adapters, the built in and the etekcity. I’m splitting the channels between the two. In the future I plan on adding a second or third 5 GHz adapter. Then I’ll switch the built in adapter to being an access point. Then I’ll be able to connect to the Raspberry Pi’s wifi and control the Pi from my phone.

At this point your should probably reboot the Pi. Ensure that the gpsd did start on boot.

ps -aux | grep gpsd

Test your GPS connection, you should see some GPS data show up.


Run Kismet


At this point I did some really lazy ways to automate things. I’ll get around to fine tuning it, but I wanted to get my Wigle.net score up, so getting the WarPi into the field was priority one.

Restart Kismet every 10 minutes using a cron jon.

crontab -e
*/10 * * * * /root/restartkismet.sh

restartkismet.sh contents

killall kismet
sleep 2
sleep 10
service networking restart
sleep 10 &&

Convert kismet files to wigle CSVs

for f in $FILES
    echo $f
    kismetdb_to_wiglecsv --in $f --out $f-.csv

Next step is to set a cron job to convert the CSVs and delete the kismet files. Until then I’m just manually cleaning it up by running the conversion shell script and then deleting:

rm Kismet*.kismet

And I’ll start uploading the CSVs automatically. But who uses APIs?

The fun thing about Raspberry Pis is that if you’re in the middle of writing to a SQLite database and you turn off the power then there’s about a 75% chance you’ll have to remove the SD card and run fsck on it. I added a button to have a graceful shutdown. It’s just a PC power switch I had laying around plugged into pin 18 and ground. Then I set up a script that I stole from: https://www.hackster.io/glowascii/raspberry-pi-shutdown-restart-button-d5fd07

I was having some problems getting the script to run. I was getting the error message, “rpi.gpio RuntimeError: This module can only be run on a Raspberry Pi!” Since I am running the 64 bit Kali I needed to update RPi.GPIO.

pip install RPi.GPIO --upgrade

Here’s the script I’m using. To get it to run at boot I put “python /home/pi/Scripts/shutdown_pi.py &” into my /etc/rc.local

import RPi.GPIO as GPIO  
import time  
import os

# Use the Broadcom SOC Pin numbers 
# Setup the Pin with Internal pullups enabled and PIN in reading mode. 
GPIO.setup(18, GPIO.IN, pull_up_down = GPIO.PUD_UP)

# Our function on what to do when the button is pressed 
def Shutdown(channel): 
   os.system("killall kismet") 
   os.system("sudo shutdown -h now")  

# Add our function to execute when the button pressed event happens 
GPIO.add_event_detect(18, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)  

# Now wait! 
while 1:  

Part 2 here