Detecting IMSI Catchers

Detecting IMSI Catchers

I was wondering how and if IMSI Catchers can be detected and how much work it would be to support that in OsmocomBB. The only problem is that I have not seen any IMSI Catchers, have not written one and have read too little about it.

So how does an IMSI Catcher operate? Well, I have no idea and need to speculate. In contrast to a real network it is only meant to be used by a few Mobile Stations (MS), it is supposed to be the most attractive Cell, by nature it should have more SDCCH than TCH.
The next step in thinking is to figure out how to achieve some of the above goals. As it should only work with a few handsets the System Information might/should contain an Access Class allowing only certain IMSIs to attach, one should see a lot of Location Updating Reject messages or unanswered messages. To be the most attractive cell the signal strength should be higher than the others, the channel configuration might be guessable by looking at the RACH and see which kind of channels are requested and assigned (keeping track of them).
The next thing would be to use a database like OpenCellID, or some other database and check if the LAC/CI has been seen in this area, comparing the SI to the other SIs of the same operator…
I plan to start such a thing as it is mostly about statistic and stochastic and I have become too rosty on these topics. The question is how likely (t-test) is that this SIx is coming from the real network, how likely is that this RACH pattern is coming from the real network.
any ideas and comments?
MGCP Road to Stability

MGCP Road to Stability

I have spend the last week differently than I had planned. I have been to Iceland, the Hotel still didn’t restart their DVB-S receivers or renewed their smartcards. So 13/16 Channels are stuck in different set-top box messages and only RTLII of Switzerland, BBC and Eurosport are fully functional. The sad part is thet one could receive China’s CCTV program here…

I have spend the last week working on the MGCP Gateway of OpenBSC to allocate the network and the BSC/BTS port separately, to add a feature to forward the RTP stream from the BTS IN/OUT, NET IN/OUT to another system. On this different system one can use something like GStreamer to decode the stream and listen to it. This can be useful to debug when the voice doesn’t arrive where it should.
In a network simulation with Linux’s netem we have tried to simulate a bad vsat link and wanted to see how big the latency/jitter can be to still have an acceptable voice call and now I will play a bit with RTP jitterbuffers… This allows me to look at GStreamer once again to see if their jitter buffer is finally working.
Progress in OpenBSC

Progress in OpenBSC

This is just a small list of things that have happened in OpenBSC:
  • Introduce a GSM 08.08 BSC API to separate channel management from the MSC Code. This has also killed reference counting of our logical channels and we release channels a lot faster.
  • Toying with USSD. I started to play with ASN.1 and generate USSD messages, right now we can send a unstructuredSS-Notify down to the Cellphone and play with the alerting types, sending a notifySS as part of the Setup message is not liked by phones yet.
  • Splitting out the SCCP code into a new libosmo-sccp library, I have also put my MTP-Level3 code in there, so maybe we should call that library libosmo-ss7.
  • I was writing my first C Node in Erlang to parse SCCP messages in C and return the result to erlang to Erlang code.
  • The mgcp code can now dynamically loop/unloop the stream, patching the SSRC, seqno and timestamp.
In the next couple of days/weeks I want to continue working on the BSC API and then completly nuke the current on-waves/bsc-master branch as everything is merged back to master in a way better structure than it was in the branch. But today I am trying to make my code and the nanoBTS crash…. and figure out why it is doing that.
HTC Desire/Android GSM Protocol Issue

HTC Desire/Android GSM Protocol Issue

I was playing with ASN1 and Supplementary Services over the Weekend. My goal was to provide extended user information during a call setup. So the first step was searching for information of how it could look like, this involved going through the GSM Spec, the 2nd part was wrestling with asn1c to generate some dummy data (as I couldn’t find a trace doing that), the 3rd part was being able to generate that from OpenBSC and send it to the phone.

Well, long story short. It doesn’t work, the better phones ignore the data I am sending, all the others refuse to show incoming calls, the Phone failing the most is a HTC Desire with Android. First of all OpenBSC has a pretty simple USSD implementation and it doesn’t like that, now when you place a phone call (while Android decides to do a USSD request in the background), OpenBSC will close the channel, not do any Call-Control and on the Android one screen shows the call is terminated, in the decoration it is still active, then the wakeup/sleep logic gets confused, you can not hang-up and then the phone is restarting.
The executive summary: Not implementing USSD in your network (we send an error and such) can make Android phones reboot if someone is placing a call at the time android retries to send the USSD query.
GPRS issue resolved

GPRS issue resolved

Hi,

with some more debugging and fun with wireshark scripting and looking a pretty obvious issue has been resolved. Now GPRS for us is actually using IP, UDP, NS (some simple address and type of the messages), BSSGP (protocol between SGSN and BSS) and for actual data there is LLC at the end of the BSSGP. The LLC is part of the BSSGP payload as TLV (Tag, Length, Value).
I created a simple setup that worked. It involved getting the traffic from the BTS, relayed with a simple smalltalk script (I had to do some fixes to GNU Smalltalk), and then send it to another SGSN. With a small variation of sending the data through our proxy I made the nanoBTS crash.
From observations I found that the other SGSN is padding the FLOW-CONTROL-BVC-ACK and FLOW-CONTROL-MS-ACK packets to 28 bytes, but padding/not padding had no effect on the crash.
The next observation was (before I tried doing it manually) that I now have each packet twice, once coming from the SGSN and how it looks after our proxy, apparently the proxy truncated the UDP packets….
So what errors have happened?
  1. The nanoBTS accesses random memory with short LLC frames and crashes, instead of crashing it should send a STATUS (I think BSSGP) returning our
  2. The wireshark BSSGP dissector does not check the size of the LLC frame (I created a bug report with a patch)..
  3. The proxy code was not reading the whole datagram and we had to increase the size, according to the spec the maximum size is 1600 byte for Framerelay… we now have a slightly bigger message…
RR Channel Release and USSD

RR Channel Release and USSD

Traditionally we have a struct gsm_lchan representing a logical channel. It has a given type based on the physical allocation (SDCCH, TCH/H, TCH/F), a given mode (traffic or signalling) and the trx and timeslot it is on. We also have a struct gsm_subscr representing a GSM Subscriber in our combined HLR/VLR. Whenever a Channel is used for a subscriber we are taking a reference count and assign the subscriber to the lchan. Whenever releasing the lchan we check the subscriber pointer and if it is set send a proper RR Channel Release and a SACH Deactivate.

For the real OpenBSC BSC we have no HLR/VLR in process, we have no local database as I am paranoid on running out of diskspace on a system that should work without maintainenance. But this means that on a channel release I am not running through the GSM04.08 RR Channel Release and so far this has worked out well. Well until we have figured out that USSD is broken. The workaround for now was to create one dummy GSM Subscriber and assign it to the channels, the proper fix is on the way by a proper split between BSC and MSC functionality but that is taking quite some time.

GSM RACH Bursts and Paging Requests

GSM RACH Bursts and Paging Requests

Yesterday I had the pleasure of trying OpenBSC on a real network and the result was desaster, but honestly what else to expect when trying it the first time. It is not that OpenBSC was crashing, leaking memory, or not recovering from failure it is just the load of the network was differrent than what I assumed and that leads to problems.

What happens is one is seeing a lot of location updating requests, which will load the SDCCH but that is really fine and we have seen such things at the Chaos Congress, what is different is the result of location updating requests, the network will flood us with paging requests… Right now we are sending up to 20 paging requests every two seconds… The first thing to notice is that this too much for the nanoBTS, it is sending us a nice CCCH/ACCH/BCCH overload warning which we do not handle (we should start two timers and throttle the amount of messages we send) the other part is… if we are out of SDCCHs and ask 20 more phones a second to get one… We have created the RACH DoS that Dieter Spaar has done with a Mobile Station.

The Random Access Request contains the channel type and one to IIRC four bits of random numbers, so even if we have a free channel… it can happen that two phones believe that we have assigned a channel to it… and then we see RF Failures, which in turn will trigger the phone to try again (or we page it again)… and then nothing will work….

The other observation is that if our cell is really busy we should start to assign TCHs to fullfill location updating requests….

So the changes I need to make is to change the paging to not page as much as we physically can stuff into the PACCH but as to how much of the responses we can handle (pretty obvious?) and the other is to allocate a “bigger” channel in case we have no smaller channel… E.g. use number of free channels divided by X for paging requests…

Hacking on OpenBSC

Hacking on OpenBSC

I was invited to visit the On-Waves (they have a shiny new website) office in Paris this week and I was quite busy hacking away on the OpenBSC codebase. On-Waves allows me to play a bit with their MSC and learn more about GSM and in exchange OpenBSC gains a more and more complete and stable GSM A-Interface.

When developing code for OpenBSC we are mostly sitting very close to the BTS, only have one active subscriber, test one thing, restart, test another thing, restart but with any piece of software I’m writing, I want OpenBSC to be rock solid, run unattended for years, have no memory leaks, deal with the nanoBTS going away and coming back, the MSC going away and coming, all this at any point in time. So far events like Hacking at Random and the Congress are the ideal testing ground as many different handsets, subscribers, etc are the ideal playground.

My testing was limited to a small set of handsets connected via USB and executing AT commands for call handling and sending SMS. I’m addressing subscribers on the same cell. That means whenever I do a call I have mobile originated and mobile terminated testing covered and this is done by funny chat scripts that work most of the time. The next thing is to simulate failure, for some stuff where a specific layer3 message would be send, we have to wait for a more complete OsmocomBB, so what I can easily do is to cut off TCP connections. I have done this with another piece of weird shell magic. I use the output of $RANDOM and treat it as seconds and then use a kill -SUGUSR2 `pidof bsc_msc_ip` to close the MSC connection at a random time. And then I let it running and wait for failures.

I have fixed a bug/issue in the way we do release a channel. There are multiple things involved. First of all is instructing the BTS that a given channel on a timeslot is open or closing it (RF Channel Release of RSL), the other part is that on the channel one can have logical applications running (SAPI), this can be call control (SAPI=0) and SMS (SAPI=3). When opening a connection to a Mobile Station (MS) the SAPI=0 is always established, when attempting to deliver a SMS we need to open SAPI=3 first. Now our issue with bringing this down was that whenever we got a SAPI release confirm (we asked for the release and it was released) or release indication (the MS closed it) and we used to respond with a RF Channel Release. Now when trying to bringdown a connection were we delivered a SMS we would issue a RF Channel Release twice and the nanoBTS ACKed it twice! To make matter worse, whenever we get a RF Channel Release ACK we mark it as free. We had this small window when we got the first RF Channel Release ACK, allocated the channel again, and then get the second RF Channel Release ACK. I have fixed this issue in multiple ways. The first is to use the T3111 timer to wait until we issue the RF Channel Release, the second is to handle (RF) failures by “blocking” the lchan for a short second to receive multiple errors and release acks and the last bit is to properly bring down the channel. When we have SAPI!=0 we bring that down first, then we send SACH deactivate, followed by SAPI=0 release and then finally we send the RF Channel Release. This makes things more reliable on our side but we need to fix some more things. There is a FIXME inside the gsm_04_08_utils.c that mentions the start of a T3109 timer. In any case when sending a SAPI release the BTS will answer with success or a timeout and we handle both.

Today I addressed losing the RSL or OML connection to the nanoBTS and making sure we are reconnecting and not leaking any memory. This took me most of the day to get stable and I have found a bug or such inside the osmocore/select.c when releasing a bsc_fd that is the last one of the list. The difficulty here is making sure we do not leak memory, close all file descriptors, close all channels that take place on the RSL connection and make sure that when the BTS is up again we can use the channels that were allocated during the failure. To help with testing I added two commands to our vty interface to drop the OML or the RSL connection on a given BTS. The other part that was helpful is to use Linux’s Netfilter and drop packets on a TCP connection and to wait for a failure. Now I can simulate most of the network failures easily and could build some trust.

And my final wishlist item would be to have like 16 GTA02 boards, use FS0 on each and run a simple script to dial, send SMS, pickup phonecalls this would allow me to heavily test the networking in an automated way. On top of that would be to have a OsmocoreBB enabled Calypso or C123 and then I could even send messages that are normally not send at all. And thanks to FreeSoftware development I’m sure we are going to reach that goal.

Explorations in the field of GSM

Explorations in the field of GSM

Something like 14 months ago I had no idea about GSM protocols, 12 months ago I was implementing paging for OpenBSC, beginning from last summer I explored SS7 and SCCP, wrote a simple SCCP stack for On-Waves. Started to implement the GSM A Interface for OpenBSC, the last week I saw myself learning more about MTP Level3. With the Osmocom I start to explore GSM Layer 1 (TDMA, bursts, syncing), GSM Layer 2 (LAPDm) and on GSM Layer3 we mostly see the counterpart of OpenBSC.

I feel like I am back to school (in the positive way) and I have learned a lot in the recent year and looking forward I will learn more about protocols used at the MSC side and such. I’m very excited about what the future is going to be like. Will we have a complete GSM Network (BTS, BSC, MSC, MS, SMSC, GPRS gateway(s)) with GPL software by the end of the year?

Tale of a day/morning

Tale of a day/morning

My debug build of libQtWebKit finished and I thought the horror of linking a huge library is over and that I could start to debug. Turned out that gdb was segfaulting when launching my application. Eeeek., google… well googling for gdb and crash is not really finding gdb things. Okay so I was using cvs to get the latest version of gdb, compiling… *crash*. It seemed to crash in demangling, so just in case I was updating binutils and rebuilding gdb. same crash. Hmmm, let us try a debug build… hmmm. Okay one of these 300 char symbols, using the libiberty/testsuite it worked fine… hmmm. using valgrind… using it again and reading the output… oh stack overflow… Turns out alloca is a nice api… there is no error checking and no way to get a breakpoint set… even with -fno-builtin…I was kicking out alloca on my stracktrace from the crash and made it go away, filed a bug and attached a patch, let us see how long this takes to end up in a version. Fixed my QtWebKit within 30 seconds after seeing the stack trace…

I spent the other half of the day/morning with copying the Q.713 data structure into a headerfile and sketching out my header file for a SCCP lite GSM A-Interface implementation. I hope I can publish this soon. Before starting to implement this I will go back to do some WebKit performance analysis…

And with all the GNU bashing going on, I wonder if GNOME 3.0 will be called NOME 3.0… This reminds me of Goethe and the “Die Geister, die ich ruf werd ich nicht mehr los”.