Evaluating GSM A5/1 security on hopping channels

Paper: Evaluating_GSM_hopping_V1.2.pdf

github source code for hopping airprobe: https://github.com/BogdanDIA/airprobe-hopping

I thought I should put my USRP at work and also exercise some of the gnuradio features that I plan to use in the future.

I got interested by the GSM security reading some of the stories about GSM A5/1 and how it has been cracked by some smart guys. I knew about Airprobe and the fact that it does not have support for GSM hopping channels and I thought that adding support for that will help the community to advance the research in the security on this matter.

That was it and after couple of weeks of work the support for hopping channels in Airprobe is ready. There are many things to do in order to make it fully automatic but the whole point is to use it for security research not for unattended use.

I captured the whole story in the following paper, the source is available as patches to Airprobe here: Evaluating_GSM_hopping, Evaluating_GSM_hopping_V1.1.pdf, Evaluating_GSM_hopping_V1.2

Patches for airprobe: airprobe_hopping.tgz

Very important note: One some machines the pfb check for N/i oversampling ratio does not work. You will get the following error:

RuntimeError: gr_pfb_channelizer: oversample rate must be N/i for i in [1, N].

The only fix I have for now is commenting the check inΒ  gr-filter/lib/pfb_channelizer_ccf_impl.cc and rebuilding gnuradio:

//if(fltp != 0.0)

//throw std::invalid_argument(“pfb_channelizer: oversample rate must be N/i for i in [1, N]”);

LE: seems on gnuradio 3.7 this does not happen anymore

25 thoughts on “Evaluating GSM A5/1 security on hopping channels

  1. Thx for reply, i am now an owner of N210 but i would like to know more about what exactly was this modifications made. Can you share patches, howto or whole modified code? In another blog post, or email?

  2. Hi, thank you for the patches, but I’m still struggling to make the airprobe work and was wondering if you could give me some advice.

    First of all, i’m using USRP N210, GNURadio + UHD works

    I cloned the airprobe from repository, applied patches with “git apply” and tried to compile the whole thing. But i’m getting a lot of compilation errors. I tried adding boost libraries but that didn’t solve the problem.

    What other libraries do I need ?

    I’m trying to make this work on ubuntu 12.04 (32bit).

    Any help will be greatly appreciated.

  3. Hi,
    Great work Man… πŸ™‚

    if your patch can also work with old USRP or USRP1
    means if can we implement frequency hoping on old USRP or USRP1 as well

    Kindest Regards,

  4. oh, my god
    it is incredible , I saw your code for gsm.i and so on… also your channelizer (pfb) are great. i search 2 years ago for this problem. best regard bro i am so exciting.

  5. Hello Reza,

    can you help me with my question ?If this script will work with old USRP i.e. USRP1 or it will work on N210 only?

    rgds,
    Dev

  6. Probably the script will not work directly with USRP1 due to some differences (e.g. clock value). It needs to be modified for USRP1.

    Good luck,
    Bogdan

  7. Hi,
    I applied patches to Airprobe and compiled without any problem.
    then I edited “capture_decode_channelized2.py” and set CONFIGURATION=”0B” , CA=”1″ , C0=”1″ , to produce the data streams for channel 1 and receive output of decoded messages in Wireshark, when I entered “sudo ./capture_decode_channelized2.py > o.txt” in terminal, the followings problems occured:
    first of all, after running the mentioned bash command, why my USRP N210 device does not transfer data into localhost? in fact, I can not receive any GSMTAP packets on localhost by wireshark and I don’t know where is the source of this issue.
    second, Is it possible for you to help me more on these parameters: “CONFIGURATION” “CA” “M” “MAIO” “HSN” “KEY”

    Best Regards,
    E.Y

  8. Hello Dear Admin

    I test your procedure but i face with some problem.

    –At fisrt calculate most powerfull channel :

    >> ./kal -s GSM900 -g 100
    ——————————————————————————————————————
    — Opening a USRP2/N-Series device…
    — Current recv frame size: 1472 bytes
    — Current send frame size: 1472 bytes

    kal: Scanning for GSM-900 base stations.
    — Loaded /home/reza/.uhd/cal/rx_iq_cal_v0.2_E6R1BWAXW.csv
    chan: 1 (935.2MHz + 278Hz) power: 1046.94
    chan: 3 (935.6MHz + 267Hz) power: 609.37
    chan: 5 (936.0MHz + 317Hz) power: 747.36
    chan: 10 (937.0MHz + 237Hz) power: 586.40
    chan: 45 (944.0MHz + 293Hz) power: 886.09
    ——————————————————————————————————————

    –then we patched your job and then keeo old version of airprobe.

    >>uhd_rx_cfile -g 76 -f 940000000 –samp-rate=10000000 out/out.cf -N 900000000

    >>airprobe-hop/gsm-receiver/src/python$ ./channelize2.py –inputfile=”out/out.cf” –arfcn25 –srate=10000000 –decimation=17 –nchannels=50 –nsamples=900000000

    ——————————————————————————————————————
    Number of taps: 4545
    Number of channels: 50
    Taps per channel: 91.0
    pfb oversampling: 2.94117647059
    >>> gr_fir_ccf: using SSE
    Run time: 930.963995
    —————————————————————————————————————–

    –and then change configuration as below (also change in many modes, also just channel 1):

    CONFIGURATION=”0B”
    CA=”1 2 3 5 10 12 49″ #all possible channel
    C0=”1″
    ######Not Important yet#############
    MA=”07″
    MAIO=2
    HSN=2
    ####################################
    KEY=”00 00 00 00 00 00 00 00″
    NSAMPLES=900000000

    but in channel 1 I can not extract 0B information (it extract so bad) , I use old version of airprobe with same file ( out_1.cf) and now all information extract very well.

    >>airprobe-hop/gsm-receiver/src/python$ ./capture_decode_channelize2.sh
    result:weak

    >>airprobe/gsm-receiver/src/python$./go_usrp2.sh ~/airprobe-development/airprobe-hop/gsm-receiver/src/python/out/out_1.cf 170 2S
    result : very good

    –“system information 1” and “immediate Assignment” extracted vey well by old version and this parameter come:

    CONFIGURATION=”2S”
    CA=”1 26 30″
    C0=”1″
    MA=”06″
    MAIO=0
    HSN=56
    KEY=”00 00 00 00 00 00 00 00″
    NSAMPLES=900000000

    –i found key after that, again when set key in patched version i can not see anything but in old version everything are clear:

    >>airprobe-hop/gsm-receiver/src/python$ ./capture_decode_channelize2.sh
    result:weak

    >>airprobe/gsm-receiver/src/python$./go_usrp2.sh ~/airprobe-development/airprobe-hop/gsm-receiver/src/python/out/out_1.cf 170 2S 5A30179A092C12B9
    result : very good

    when use it with old version of airprobe, I see “Assignment Command” and change parameter according to below:

    CONFIGURATION=”4T”
    CA=”1 26 30″
    C0=”1″
    MA=”06″
    MAIO=0
    HSN=56
    KEY=”5A 30 17 9A 09 2C 12 B9″
    NSAMPLES=900000000

    I can not extract the voice
    —————————————————————————————————————–
    summery:
    in extracting 0B and 2S channel information, so later after finding the key in 2S and 4T channel configuration, your output are not shown. but old version of gsm-receiver dispaly all of them exactly.

    please help me in finding solution.
    Best Regard

  9. Hi Reza,

    what you did seem correct. The old airprobe should work similar with the patched airprobe for 0B channel.
    You could try to debug to see what is the problem.

    Bogdan

  10. Hi admin

    can this PROG decode EFR and AMR voice?

    would you release a USRP1 patch ? thankyou.

    Kindest Regards

  11. Dear Bogdan,
    Can u plz tell me about the parameters you are using with uhd_rx_cfile,
    i am having no out put in wireshark when i run go_usrp2.sh with my captured file

    Besr regards,
    Muhammad Farrukh

  12. Hi Dear Admin and thanks for reply.

    I debug some. your idea for using multiple source and one gsm_receiver_cf was interesting.

    in returning “cai” for input_items[cai] also change input_items to desire source path.

    I think MA[MAI]=MA[cai] and as a result you use CA list equal MA list. in fact when MAI=0 program to first ARFCN in CA list and change to input_item[0]. for example :

    CA={1 26 30}
    and then as result in some part of running MAI=0 then code selet ARFCN=1 and use input_item[0] after that when MAI calculate as 2, select ARFCN=26 and use input_item[1].

    but i think we have serious problem and it is when we put key, program run from first of cfile (not after “Assignment command”) also before cipher start and change channel, so it cannot follow hop correctly. Am I right?

    how can i mark cfile to follow hop right after “Assignment Commmand” ?

    Thanks in advanced
    Best regard

  13. Sorry I make big mistake.

    I think when we using frame number, program never calculate wrong MAI. πŸ™‚

    But by now i can not extract voice . πŸ™

  14. Hi

    Is there any plan to set up a fork repos on github or anywhere with all the patch apply, this could attract more people interested in this field. Really would like to dig in it, plan to buy my n210 by the end of the month.

    Great Job btw

  15. Hi YO3IIU,

    this is on4bhm.

    i’ve got a problem with your code:
    gsm_receive100_channelize.py gives me error
    File “../lib/gsm.py”, line 229 in receiver_cf
    TypeError: Receiver_cf() takes at most 5 arguments (9 given)

    what can cause this?

    can yoy help me?

    kind regards
    73’s

  16. Hi again dear admin

    Can you share cfile that you are using in your document.
    It will be very helpful, plaese.

    thanks in advanced

  17. hey Reza,

    can u tell plz tell me that how you use uhd_rx_cfile to capture the gsm channel I am actually having problrm with the rate to set, or you have modified airprobe code to work with your capture file recorded with n210?

  18. Hello,

    did anyone get this this pfb over sampling ratio error

    File “/usr/local/lib/python2.7/dist-packages/gnuradio/gr/gnuradio_core_filter.py”, line 1387, in pfb_channelizer_ccf
    return _gnuradio_core_filter.pfb_channelizer_ccf(*args, **kwargs)
    RuntimeError: gr_pfb_channelizer: oversample rate must be N/i for i in [1, N]

    here are the parameters

    CA=”26 29 32 35 38 41 50″
    C0=”50″
    MA=”3f”
    min_ARFCN: 26
    max_ARFCN: 50
    Center ARFCN: 38
    Center frequency: 942600000khz
    Sampling rate: 10000000
    Number of samples: 56000000
    C0 position: 6
    Number of taps: 4545
    Number of channels: 50
    Taps per channel: 91.0
    pfb oversampling: 2.94117647059

    any help regarding this problem will be appreciated?

    Regards
    Muhammad Farrukh

  19. Hello Farrukh,

    see the new comment in the last part of the post. There is a problem in gnuradio that can be fixed easily by commenting some code in pfb code.

    Bogdan

  20. Hello Guys,

    what version of gnuradio did you use? I have installed gnuradio 3.7 and I have trouble with compiling gsm-receiver.
    ./configure tells me

    No package ‘gnuradio-core’ found

    Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix.

    I added /usr/local/lib/pkgconfig and /usr/local/lib64/pkgconfig to the path but I still get the same warning. I think gnuradio-core has been replaced somehow from gnuradio 3.6 to 3.7. Does anyone of you have a solution?

  21. Hi,

    1. I plan to use multiple RTL SDR sticks to capture all ARFCNs being used for hopping, then write a script which can follow the hopping sequence to decipher the data. (audio + sms)

    2. Can your airprobe-hopping handle this presently ? Is there any problem you see in the above mentioned aim ? I plan to capture diff arfcn using diff pc presently

    Thanks

  22. Hi,
    I try to decode a cfile using go.sh,but it return an error:
    [root@localhost python]# ./go.sh /home/peterwang/workspace/rtl_sdr_capture.cfile 64 0B
    Traceback (most recent call last):
    File “./gsm_receive.py”, line 119, in
    main()
    File “./gsm_receive.py”, line 114, in main
    gsm_receiver_first_blood().run()
    File “./gsm_receive.py”, line 41, in __init__
    self.filtr = self._set_filter()
    File “./gsm_receive.py”, line 72, in _set_filter
    filter_taps = filter.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING)
    AttributeError: ‘module’ object has no attribute ‘firdes’

    How to fix this?
    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *