Building a passive IMSI catcher
An IMSI catcher is a device commonly used by law enforcement and intelligence agencies around the world to track mobile phones. They are designed to collect and log IMSI numbers, which are unique identifiers assigned to mobile phone subscriptions. Under certain circumstances, IMSI numbers can be linked back to personal identities, which inherently raises a number of privacy concerns.
The purpose of this post is to be educational - to highlight the ease of which these devices can be built, and to practically show how privacy is already being compromised today. Nothing in this post is necessarily new, and those with less than honest intentions are most certainly already using these (or similar) devices.
This post walks through the processes of building a passive IMSI catcher, which is distinctly different from traditional IMSI catchers in that it does not transmit nor does it interfere with cellular networks in any way.
Traditional IMSI catchers are illegal in most jurisdictions due to the fact that they transmit on cellular frequencies (which requires a license), and that they essentially perform a man-in-the-middle attack between a phone and mobile base station (which breaks all sorts of anti-hacking laws). A passive IMSI catcher does neither of these.
One point to note is that the personal data collected by the device (IMSI numbers) may be subject to privacy laws, so be mindful of storing/processing/sharing data this device collects. And of course, I’m not a legal expert in any way - do your own research.
How it works
The passive IMSI catcher works by capturing IMSI numbers when a phone initializes a connection to a base station. The IMSI is only disclosed during this initial connection. In an effort to protect privacy, all subsequent communication to that base station is done with a random Temporary Mobile Subscriber Identity (TMSI) number.
This means you will only collect IMSI numbers for devices as they move between base stations. Traditional IMSI catchers work differently, by spoofing a legitimate base station and forcing subscribers to connect to itself. They have the added ability to collect data about stationary devices, and can potentially have a more targeted range.
The only hardware required is a PC and SDR receiver that supports GSM frequencies. Generally this means 850/900/1,800/1,900 MHz. Most of the inexpensive RTL2832U based receivers have an upper-frequency range of about 1,700 MHz. You can get by with one of these, but of course, you won’t be able to listen to stations at 1,800 or 1,900 MHz.
The project is based on a few main components:
- GNU Radio - signal processing framework
- gr-gsm - blocks and tools for GNU Radio that process GSM transmissions
- IMSI-catcher - Python script that processes data from gr-gsm and extracts IMSI numbers
- Wireshark - can be used to view raw GSM packets from gr-gsm
I ran everything inside a Ubuntu 18.04 LTS virtual machine running on Windows 10 and had good results.
The official gr-gsm installation instructions can be found here. On Ubuntu 18.04 you can use the following commands to install the required dependencies and build+install gr-gsm.
sudo apt install gnuradio gnuradio-dev git cmake autoconf libtool pkg-config g++ gcc make libc6 \ libc6-dev libcppunit-1.14-0 libcppunit-dev swig doxygen liblog4cpp5v5 liblog4cpp5-dev python-scipy \ gr-osmosdr libosmocore libosmocore-dev # Build and install gr-gsm git clone https://git.osmocom.org/gr-gsm cd gr-gsm mkdir build cd build cmake .. make sudo make install sudo ldconfig
Install everything else
# IMSI-catcher script sudo apt install python-numpy python-scipy python-scapy git clone https://github.com/Oros42/IMSI-catcher.git # Wireshark sudo apt install wireshark tshark
Capture GSM traffic and IMSIs
A good first step to test that everything works is to run
sudo grgsm_scanner. This will scan for and list all nearby base stations. It can take about a minute before you start seeing stations.
Pick a base station to capture traffic from. Signal strength is listed in the far-right column. Numbers closer to zero represent a stronger signal. For this example, I’ll use the station on 949.8 MHz.
You can tell gr-gsm to capture traffic with
sudo grgsm_livemon -f 949.8M.
Captured GSM traffic is piped to the loopback interface and can easily be viewed in Wireshark. The
e212.imsi filter will only show packets that contain IMSI numbers.
python simple_IMSI-catcher.py --sniff command can also be used to parse IMSIs from the data stream. It’s a bit easier to read through than with Wireshark, and also matches the IMSI to a specific network operator, brand, and country.
You have a bunch of IMSI numbers. What next? Ideally you shouldn’t be able to do anything with IMSI numbers alone. Problems arise when you can associate an IMSI with an individual. Network operators and law enforcement can generally access this data at mass. Hopefully with all the proper authorizations and warrants…
However, there are various ways for private individuals and corporations to associate IMSI numbers as well. Think about correlation with other known data sets.
One often overlooked method is through mobile applications. Apps can access a device’s IMSI number (on Android), which is sometimes collected and used to serve as a unique user identifier. IMSIs can be stored alongside names, phone numbers and email addresses in customer databases. Customer databases are commonly sold to 3rd parties for marketing purposes, and of course have potential to be stolen. Now all of the sudden you have databases with IMSI numbers and names on the internet, which is bad.