GPRS Interception – how to sniff 2G mobile data

Karsten Nohl / Luca Melette explained how it works at the Chaos Computer Club Communication Camp 2011.

Camp 2011: GPRS Intercept.

A simpler tutorial can be found here

– Download sources into ~/gprs_sniffer

git clone git://
git clone git://
git clone git://

– Download ARM cross compiler

tar xf bu-2.15_gcc-3.4.3-c-c++-java_nl-1.12.0_gi-6.1.tar.bz2

– Compile and install libosmocore

cd ~/gprs_sniffer/libosmocore
autoreconf -i
sudo make install

– Compile gprsdecode

cd ~/gprs_sniffer/gprsdecode

– Prepare OsmocomBB’s burst_ind branch

cd ~/gprs_sniffer/osmocom-bb
git checkout origin/sylvain/burst_ind
git checkout d1cb8ea9b784c7acbafbb2fdcedbdf4655c2f6f5
patch -p1 < ~/gprs_sniffer/gprs_multi.patch - Compile OsmocomBB cd src export PATH=$PATH:~/gprs_sniffer/gnuarm-3.4.3/bin make - Run OsmocomBB firmware # Conect Motorola phone with USB cable cd ~/gprs_sniffer/osmocom-bb/src ./host/osmocon/osmocon -m c123xor -p /dev/ttyUSB0 ./target/firmware/board/compal_e88/layer1.compalram.bin # Switch on Motorola phone - Run OsmocomBB host software (in 2. terminal) cd ~/gprs_sniffer/osmocom-bb/src ./host/layer23/src/misc/cell_log - Adjust to active network # look for active networks in the output: cell_log.c:334 Sync ARFCN 29 (rxlev -52, 289 syncs left) cell_log.c:190 Cell: ARFCN=29 MCC=222 MNC=01 (Italy, TIM) # in this case, network is TIM, and ARFCN is 29 # kill cell_log with ctrl-c, and rerun with correct ARFCN: ./host/layer23/src/misc/layer23 -a 29 # Data channel assignments look like this layer3.c:243 GSM48 IMM ASS (ra=0x72, chan_nr=0x0a, HSN=44, MAIO=0, TS=2, SS=0, TSC=0) l1ctl.c:506 Tx Dedic.Mode Est Req (maio=0, hsn=44, chan_nr=0x0a) # Red lines indicate signal strength # In this case 3 out of 4 slots are used: l1ctl.c:261 BURST IND: @(2064231 = 1556/13/06) ( -50 dBm, SNR 255) l1ctl.c:261 BURST IND: @(2064231 = 1556/13/06) ( -50 dBm, SNR 1) l1ctl.c:261 BURST IND: @(2064231 = 1556/13/06) ( -50 dBm, SNR 255) l1ctl.c:261 BURST IND: @(2064231 = 1556/13/06) ( -50 dBm, SNR 255) # wait for session end or kill with ctrl-c # A file like "bursts_20110821_1648_29_2094723_0a.dat" is produced - Run GPRS decoder # Start Wireshark, capturing on interface "lo" ~/gprs_sniffer/gprsdecode/gprsdecode bursts_20110721_1648_29_2094723_0a.dat - Optional: Test with sample data wget ~/gprs_sniffer/gprsdecode/gprsdecode gprs_262_80_0001_0000_20110710_2251_875_494777_0f.dat wget ~/gprs_sniffer/gprsdecode/gprsdecode gprs_262_80_0001_0000_20110710_2252_875_514147_0f.dat - Optional: Build Wireshark from source svn co wireshark cd wireshark ./ ./configure make sudo make install - Optional: Uplink sniffing # the default firmware captures 4 downlink slots, # for uplink you need to compile a different firmware. # open "osmocom-bb/src/target/firmware/layer1/prim_sniff.c" # at line 288, modify #if 1 to 0 # go back to 'Compile and install libosmocore'

Leave a Reply