A newbie’s guide to Software Defined Radios on Kali Linux | Part 2: Listening to airplanes and on-call pagers

Maxime Leblanc
poka-techblog
Published in
6 min readMar 7, 2019

--

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

Credit: Tech for Fun

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:

gqrx capturing FLEX communications

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

By Matti Blume — Own work, CC BY-SA 4.0

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 :

dump1090-mutability in action on Kali Linux

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!

--

--