A newbie’s guide to Software Defined Radios on Kali Linux | Part 2: Listening to airplanes and on-call pagers
As I told you in the first part of this story, I got my hands on an SDR (Software Defined Radio) at the last Hackfest and started to learn how I could use it to listen to signals that are normally not meant to be listened to by the general public. As the second part of this story, I will demonstrate two of the most popular signals that hobbyists like to listen to. This article assumes that you are familiar with the software presented in the first part and that stl-sdr drivers and gqrx are both installed and working.
Listening to Pagers on the Ground: FLEX
FLEX is a signal used by pagers, quite surprisingly still in use by various “on-call” professionals: I have seen health emergency services, alarm systems alerting and even seen some IT emergency team receive some SQL error on this (unencrypted) channel. There are some quite interesting things happening on this frequency.
I am writing this in Canada, where the strongest FLEX signal appears to be on the 929.3 Mhz; In gqrx
look for a quite small but clear waterfall signature, with intermittent stops every 2–3 seconds. Once you think you found it, configure gqrx
to capture your frequency with these settings:
Frequency: <929.3 or other...>
Filter Width: Wide
Filter Shape: Normal
Mode: Narrow FM
And leave the rest untouched from defaults.
The next step is to demodulate the signal in order to have some actual bytes and decode the text carried by the signal. In order to do this, we need to install two dependencies: sox
and multimon-ng
:
# apt-get install sox multimon-ng
Finally, activate the UDP streaming in gqrx
by pressing the UDP
button at the bottom-right, and in a new terminal window, launch this command:
nc -l -u -p 7355 | sox -r 48000 -t raw -b 16 -c 1 -e signed-integer /dev/stdin -r 22050 -t raw -b 16 -c 1 -e signed-integer - | multimon-ng -t raw -c -a POCSAG512 -a POCSAG1200 -a POCSAG2400 -a FLEX -a SCOPE -f alpha /dev/stdin
Note that this should all be on the same line since it’s a piped command, but I decided to separate the three commands for clarity. Here, Netcat ( nc
) is used to capture the packets that have been captured and sent using gqrx
while sox
transforms those bytes to a format multimon-ng
is able to receive.
When all is done, you should have a setup looking like this:
Here I have been careful to choose a moment where there were no personal information captured, but there are plenty, so just be careful with what you do with these when listening to FLEX communications. As stated earlier, these communications are unencrypted and often carry pretty sensible thing (as it is meant to warn people that are “on call” that there is a problem somewhere…). Also, note that if you don’t have a white window appearing after the triple-piped command, something is wrong. Perhaps you should verify if gqrx
is still sending on the UDP channel. Also, some versions of Netcat do not require the last -p
for the UDP port, so be aware of this as it can cause some problems.
Listening to Planes in the Sky: ADS-B
ADS-B is a signal that pretty-much every commercial airplane emits in order for control towers around the world to be able to track the position and speed of airplanes (in addition to classic radar technology, of course). It operates at the 1 090 Mhz frequency and there are plenty of decoders out-there, which could be explained by the (strange) popularity of plane spotting, a hobby that consists of photographing and keeping track of airplanes
On Kali Linux, I suggest starting by just installing dump1090-mutability
which comes directly in the repositories:
# apt-get install dump1090-mutability
It’s not the most recent version of dump1090
and even the authors are redirecting people to FlightAware’s version since the development there is still ongoing. That said, I found it to be the easiest way and it still works pretty well, even if some adjustment have to be made for all the features to work on Kali. You should still be able to try it as-is and begin to see messages looking like this:
# dump1090-mutability
...
*8dc07f3d580f06a95a2a37046e16;
CRC: 000000
RSSI: -16.5 dBFS
Score: 1800
Time: 64072988.17us
DF:17 AA:C07F3D CA:5 ME:580F06A95A2A37
Extended Squitter Airborne position (barometric altitude) (11)
ICAO Address: C07F3D (Mode S / ADS-B)
Air/Ground: airborne
Altitude: 1800 ft barometric
CPR type: Airborne
CPR odd flag: odd
CPR NUCp/NIC: 7
CPR latitude: 46.77182 (87213)
CPR longitude: -71.25794 (10807)
CPR decoding: global
As you can see in this example, this comes from an airplane flying at 1800 feet of altitude at latitude 46.77182 and longitude -71.25794. dump1090
only shows what it was able to decode here, but most of the time after a couple of messages (they are not all the same) you will also be able to see the airplane’s speed and flight number.
There is also a nice feature of dump1090
that displays the gathered information on a map, with their respective flight numbers and country of provenance; to do this, you must enable and start lighthttpd
modules relative to dump1090
. Here are the commands you have to execute to enable dump1090
‘s Web server:
# lighty-enable-mod dump1090
# mkdir /run/dump1090-mutability/
You can verify that the module is enabled by verifying if you have a file similar to this in /etc/lighthttpd/conf-enabled/89-dump1090.conf
:
# Allows access to the static files that provide the dump1090 map view,
# and also to the dynamically-generated json parts that contain aircraft
# data and are periodically written by the dump1090 daemon.url.redirect += (
"^/dump1090/$" => "/dump1090/gmap.html",
"^/dump1090$" => "/dump1090/gmap.html"
)alias.url += (
"/dump1090/data/" => "/run/dump1090-mutability/",
"/dump1090/" => "/usr/share/dump1090-mutability/html/"
)# The stat cache must be disabled, as aircraft.json changes
# frequently and lighttpd's stat cache often ends up with the
# wrong content length.
server.stat-cache-engine = "disable"
And next, just restart dump1090-mutability
with this option:
dump1090-mutability --write-json /run/dump1090-mutability/
If all went well, you should be able to navigate to http://localhost/dump1090/gmap.html
:
Conclusion
I hope I demonstrated that lots of information floating around on frequencies that were not meant to be public or easily listenable for everyday folks are now very easily accessible with a simple 30$ USB dongle.
Now, all this information is not encrypted or authenticated (although there is a checksum for error-correction). This means a malicious actor could emit on those same frequencies and inject false information in communication channels we thought were safe from tampering. I will demonstrate in a future story how it’s possible to emit on an arbitrary frequency using only a RaspberryPi and some open-source libraries.
Stay tuned and happy hacking!