其实GSM网络不安全的事实早就已经在国内外安全圈子里家喻户晓了,早几年我也关注了一下,不过那时候主要还是很原理性的了解上,那时以为GSM Sniffing需要非常昂贵的设备。事实上10年左右这一块技术就已经比较成熟了,国外到了12年就已经有了完整的开源方案实现(osmocom项目),国内的大神在13年就非常详细地公开了如何实现GSM SMS Sniffing,所以现在个人要做到GSM SMS Sniffing实际上比较简单,成本也很低廉。
虽然14年已经玩了一段时间GSM Sniffing,但一直觉得这个话题很敏感,加上工作之后可用的时间也越来越少(主要是越来越懒),所以没有好好的记录一下。最近某公安部门都可以公开采购监听软件了,我们玩玩已经公开那么多年的过时技术应该不会被查水表吧~
好了,废话说完了,下面开始正文:
一、原理篇
这一块因为我不是专业的,只能班门弄斧摘弄一点大概的原理糊弄一下大家^_^:
I. 1、什么是GSM
全球移动通信系统,即GSM(Global System for Mobile Communications),是当前应用最为广泛的移动电话标准,GSM是一个蜂窝网络,蜂窝网络的原因,是因为一个数学结论,即以相同半径的圆形覆盖平面, 当圆心处于正六边形网格的各正六边形中心,也就是当圆心处于正三角网格的格点时所用圆的数量最少。作为运营商,为了考虑成本,不会建设大量多余的基站。
GSM传输过程加密采用A5算法。A5算法1989年由法国人开发,是一种序列密码,它是欧洲GSM标准中规定的加密算法,专用于数字蜂窝移动电话的加密,用于对从电话到基站连接的加密。A5的特点是效率高,适合硬件上高效实现。A5发展至今,有A5/1、A5/2、A5/3、A5/4、A5/5、A5/6、A5/7等7个版本,目前GSM终端一般都支持A5/1和A5/3,A5/4以上基本不涉及。值得注意的是,A5/2是被有后门的版本,2006年后被强制叫停,终端不允许支持A5/2。
我们国家移动和联通的2G电话网络采用的是GSM,在国内几乎是不加密的。
II. 2、一些名词
MS:Mobile Station,移动终端;
IMSI:International Mobile Subscriber Identity,国际移动用户标识号,是TD系统分给用户的唯一标识号,它存储在SIM卡、HLR/VLR中,最多由15个数字组成;
MCC:Mobile Country Code,是移动用户的国家号,中国是460;
MNC:Mobile Network Code ,是移动用户的所属PLMN网号,中国移动为00、02,中国联通为01;
MSIN:Mobile Subscriber Identification Number,是移动用户标识;
NMSI:National Mobile Subscriber Identification,是在某一国家内MS唯一的识别码;
BTS:Base Transceiver Station,基站收发器;
BSC:Base Station Controller,基站控制器;
MSC:Mobile Switching Center,移动交换中心。移动网络完成呼叫连接、过区切换控制、无线信道管理等功能的设备,同时也是移动网与公用电话交换网(PSTN)、综合业务数字网(ISDN)等固定网的接口设备;
HLR:Home location register。保存用户的基本信息,如你的SIM的卡号、手机号码、签约信息等,和动态信息,如当前的位置、是否已经关机等;
VLR:Visiting location register,保存的是用户的动态信息和状态信息,以及从HLR下载的用户的签约信息;
CCCH:Common Control CHannel,公共控制信道。是一种“一点对多点”的双向控制信道,其用途是在呼叫接续阶段,传输链路连接所需要的控制信令与信息。
III. 3、手机和基站的那些事
下面是手机(插有效SIM卡)开机之后与附近最强基站的交互过程:
MS向系统请信令信道(SDCCH); //MS倾向信号强的BTS,算法基站定,故有伪基站攻击
MSC收到手机发来的IMSI可及消息;
MSC将IMSI可及信息再发送给VLR,VLR将IMSI不可及标记更新为IMSI可及;
VLR反馈MSC可及信息信号;
MSC再将反馈信号发给手机。
怎么样,晕了吧?看不懂没关系,接下去看,基站子系统(简称基站BS)由基站收发台(BTS)和基站控制器(BSC)组成;网络子系 统由移动交换中心(MSC)和操作维护中心(OMC)以及原地位置寄存器(HLR)、访问 位置寄存器(VLR)、鉴权中心(AUC)和设备标志寄存器(EIR)等组成。其中原地位置寄存器(HLR里面存放着本地的手机号信息,而访问位置寄存器(VLR)存放着外地来的手机号信息。通过判断手机号的归属地,就可以区分本地和外地手机了,这就是区分归属地的原因了。
当你拨打电话的时候,首先会给基站请求,基站判断出这个手机号的所在的基站,然后与基站、目标手机建立连接,对于目标在本地,数据只在本地的基站系统中传输,相当于计算机中的局域网,故资费便宜,当目标手机不在本地时,就需要连接外地的基站,传输距离长,过程相对复杂,故资费较高。这是曾经手机长途费的根本原因,同样漫游费用反之。
基站会不停的对外广播自己的信号及相关信息,手机只要搜索信号,选择相应的连接上去即可,在连接过程就会完成上面的注册过程。当自己的手机正常关机时,也会给基站发送注销信息,这样别人拨打你的电话,就会提示已关机。假如自己的手机突然断电,会意外的断开与基站的连接,基站那面没有完成正常的注销操作,这样别人拨打你的电话,就会提示暂时无法接通或者不在服务区。
说到这里,开始进入正题了,任何一部手机(无论有没有插有效的SIM卡)面对一个大基站,基站本身并不会对特定的方向的信号与你通信,而是以向四周广播的形式,发送信号。那么就可以说,我们的手机实际上也是可以接收到其他手机的信号,对的,就是这样,包括你经常用的WIFI也是这样,不像有线有一个专门的线路,只要把收到的信号给解密了(SMS协议在国内是明文传输的),就可以嗅探别人的短信、语音通话(现阶段很难,不是真正理解)。甚至可以假冒其他人的身份通话(当然,前提是可以突破目前的鉴权手段,当然电信可以更改来电显示号码是有特殊原因的)。
IV. 4、关于OsmocomBB
OsmocomBB是国外一个开源项目,是GSM协议栈(Protocols stack)的开源实现,全称是Open source mobile communication Baseband.目的是要实现手机端从物理层(layer1)到layer3的三层实现,这一块都是大神们在贡献,作为小菜可以简单地把它理解为是一个手机ROM+一个控制ROM平台的组合,刷入ROM的设备可以让我们从物理层上控制和筛选周围基站发来的任何信息。
对于OsmocomBB的使用,国内的中文资料已经比较完善了,虽然在乌云里面报告运营商一直置之不理,但是随着短信内容的明文传输越来越多人知道,攻击成本越来越低廉,相信运营商迟早会有所作为。
二、硬件篇
既然是要用OsmocomBB来实现GSM的嗅探,硬件的要求自然也要根据OsmocomBB来,开头就说了全套下来成本不高,不高到什么程度呢?我们来看看OsmocomBB的[](https://bb.osmocom.org/trac/wiki/Hardware)硬件需求:
OsmocomBB支持的手机一部,
手机配套的耳机线一根,
杜邦线若干,
USB转TTL模块一个。
合在一起总成本大约60RMB,我们这里就采用国内大神们经常用的一套硬件:
手机选用摩托罗拉的C118
USB转TTL模块用CP2102。
如果不愿意动手做传输的数据线,某宝上有现成的做好的C118数据线,大概10RMB。
数据线与CP2102模块连接的时候注意线序:
红 TXD //TXD是发送数据的引脚
白 RXD //RXD是接收数据的引脚
蓝 GND //GND是接地引脚
连接好之后插上电脑的一个USB接口,数据线连接到插了电池未开机状态的C118上,像上图这样RXD与GND的灯亮起来说明连接正常。
三、软件篇
开始说到软件准备了,OsmocomBB嗅探平台是运行在Linux下的,你可以安装任意一个Linux的发行版来搭建他,由于我平时用的Archlinux,而且事实证明在Archlinux上编译OsmocomBB是更麻烦一些的,所以就以Archlinux来说明,我用的是64位的Archlinux,如果你是新装,或者想在虚拟机里体验,请选择32位以减少折腾且方便转移,下面步骤如果没有特别说明,当前目录为~root,需要ROOT权限。
首先第一步,针对Archlinux 安装需要的编译准备环境
pacman -S libtool automake autoconf wget git-core pkg-config make gcc git libpcsclite svn
针对Archlinux,需要先将texinfo替换成4.13a,因为默认源里面texinfo5会导致gcc的文档无法编译,
wget http://ftp.gnu.org/gnu/texinfo/texinfo-4.13a.tar.gz
tar xvf texinfo-4.13a.tar.gz
cd texinfo-4.13a
./configure
make
make install
接着,由于由于Archlinux的源里没有shtool,需要自己下载编译安装
wget ftp://ftp.gnu.org/gnu/shtool/shtool-2.0.8.tar.gz
cd shtool-2.0.8
./configure
make
make install
-Archlinux到此为止,以下为其他系统的-
PS:针对CentOS安装需要的编译准备环境
yum install wget zlib-devel mpfr-devel gcc automake texinfo
cd src
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-0.8.1.tar.gz
tar zxvf mpc-0.8.1.tar.gz
cd mpc-0.8.1
./configure
make
make check
make install
echo "/usr/local/lib/" >> /etc/ld.so.conf.d/mpc.conf
ldconfig
PS1:针对Kali/Ubuntu/Debian安装需要的编译准备环境
apt-get install build-essential libgmp3-dev libmpfr-dev libx11-6 libx11-dev texinfo flex bison libncurses5 libncurses5-dbg libncurses5-dev libncursesw5 libncursesw5-dbg libncursesw5-dev zlibc zlib1g-dev libmpfr4 libmpc-dev libpcsclite-dev
aptitude install libtool shtool automake autoconf git-core pkg-config make gcc
开始编译GnuARM ToolChain
wget http://gnuarm.com/bu-2.15_gcc-3.4.3-c-c++-java_nl-1.12.0_gi-6.1.tar.bz2
tar xvf bu-2.15_gcc-3.4.3-c-c++-java_nl-1.12.0_gi-6.1.tar.bz2
chmod u+x gnu-arm-build.2.sh
./gnu-arm-build.2.sh
编译完成之后把ArmTool的bin目录加入环境变量
vi打开 ~/.bashrc 在最后一样加入 export PATH=$PATH:/path/to/the/bin
注意$PATH:冒号后面接的/path/to/the/bin是你自己编译出来ArmTool的bin目录的绝对路径。
做完上面的准备工作就可以开始编译osmocom核心库文件了,先git拉取libosmocore的源码,由于众所周知的原因git clone下来很可能需要自备梯子~
推荐用proxychains配合shadowsocks加速拉取。
git clone git://git.osmocom.org/libosmocore.git
cd libosmocore/
autoreconf -i
./configure
make
make install
这里因为Archlinux的原因需要修复安装路径,大概是由于Archlinux下autoreconf无论如何都无法正确通过,osmocom核心库被安装到了/usr/local/lib/下。需要把库手动复制到/usr/lib/里,否则待会儿运行osmocon会提示 libosmocore.so.4 找不到
ldconfig
cp -Rf /usr/local/lib/* /usr/lib/
终于到了重头戏OsmocomBB,同样由于众所周知的原因git clone下来很可能需要自备梯子~再次推荐用proxychains配合shadowsocks加速拉取。
cd ~
git clone git://git.osmocom.org/osmocom-bb.git
cd ~/osmocom-bb
git pull --rebase
git checkout --track origin/luca/gsmmap //切换版本,这个版本是目前最稳定的
cd src
make
这就开始编译了……漫长等待之后,不出意外的话就编译成功了,如果出了意外的话请根据错误提示找原因……
PS0:遇到上图这种l1ctl.o错误十有八九是Armtool编译得不对,请重新编译。
PS1:如果出现类似src/target/firmware/include/asm/swab.h:32: Error: no such instruction之类的错误,这是ArmTool的bin目录没在PATH里导致的,请检查PATH中是否存在arm-elf-gcc,并按上面要求添加。
PS2:如果在Leaving directory '/root/os/osmocom-bb/src/host/layer23/src/common'处出错,请git更新一下osmocom-bb的源码
PS3:如果是在虚拟机里建议先激活USB设备,并在母机上配置一下串口设置。
PS4:上面提到的所有软件和工具的源码,为方便各位TX我已经打包好了,如果搭建梯子有困难的话可以直接用我提供的ARMTOOL包
四、实战篇
好了,完成上面的步骤,你就已经可以开始你的GSM SMS Sniffing实战了。
osmocon是刷入固件,并与固件通信的程序,使用方法(注意C118选compal_e88/layer1.compalram.bin这个固件)
~/osmocom-bb/src/host/osmocon/osmocon -m c123xor -p /dev/ttyUSB0 ~/osmocom-bb/src/target/firmware/board/compal_e88/layer1.compalram.bin
将手机与电脑连接好,执行好上面的命令之后,在C118关机状态下短按电源键就会开始对C118进行软刷机,刷机成功之后C118会自动开机,并在屏幕上显示Osmocon-BB字样。
上面三张图是软刷机成功的样子
cell_log是一个扫描有效运营商频率,并收集BCCH上基本信息的工具,在C118软刷机成功启动之后,我们可以用它来获取运营商的ARFCN、MNC和MCC等信息。这里不需要gprs数据,直接使用这个参数:
~/osmocom-bb/src/host/layer23/src/misc/cell_log --only-scan
以上图的情况选取信号最强的ARFCN,(<000e> cell_log.c:248 Cell: ARFCN=1022 PWR=-64dB MCC=460 MNC=00 (China, China Mo bile)),确定这个ARFCN就可以开始抓取Common Control Channel (CCCH)了
~/osmocom-bb/src/host/layer23/src/misc/ccch_scan -i 127.0.0.1 -a 1022
一般这种4位的ARFCN都是为了给移动4G/3G号码降级时使用准备的~
看到ccch_scan开始输出burst内容后,这时候的GSM协议已经被封装上了TCP-IP,就通过wireshark过滤gsm_sms包来看通过附近的下行短信了
wireshark -k -i lo -f 'port 4729'
这里wireshark可以自己装好前端,在GUI界面下优雅的翻阅,不过为了更加高效可以直接用脚本将短信包分析出来丢到数据库里存起来,例如参考Le4F的做法,根据Le4F的脚本我稍微修改了一下方便自己使用,就不拿出来献丑了。
PS:如果你使用的是Vmware9虚拟机,出现连接USB时提示设备正在使用,无法正常连接,这十有八九是因为USB3.0的原因。请将USB转TTL转换器换插到USB2.0的接口上,问题即可解决。如果一定要用USB3.0的接口,需要折腾一堆的事情。
五、后续篇
成功的TX会发现几个问题,
V. 1、什么是下行短信?为什么嗅探到的都是下行的短信?
基站发到手机端的是下行短信,手机发送到基站的是上行短信。回到原理篇,C118毕竟是一部手机,所以要嗅探到下行的短信相对容易,只需要把不是给自己的内容不丢弃再分析就好了。但是要嗅探到上行的短信,需要C118伪装成基站,一来要增加手机功率或靠近基站,再者需要硬件上的改装移除C118上的一个RX过滤器,同时需要在代码里增加ARFCN的上行偏移。据说曾经在OsmocomBB中Uplink sniffing 是有实现的,不过后来嗅探相关的代码被移除了(在国外的论坛中有提到,貌似target_dsp中还有些),
VI. 2、为什么下行短信里怎么没有短信接收者的号码?
关于SMS协议传输的基本原理太复杂,很难一下说清楚。
根据大神们的说法,简单来讲,短信接收者的号码、IMEI等数据,只有在手机和基站进行"Location Update"时才会在网络中出现,并且是以加密形式进行验证的,验证成功之后每个合法用户都会类似HASH一样生成一串验证编码,平时接收短信时,系统根据最近更新的这串验证编码判断接收者的所处基站,发送下行短信,所以下行短信中没有接收者的号码信息。这有点类似调试QQ登陆(以及其他OAuth方式一样),验证之后通过Openid和Access Token鉴权身份,不能直接知道用户的QQ号码。想要拿到接受者的号码,需要破解A5/1算法并还原出"Location Update"时的原文。Airprobe项目里有介绍如何破解A5/1算法找到Kc:https://srlabs.de/airprobe-how-to/ 只不过需要价格昂贵的USRP2...上行短信这一块还是可以实现的,只是相对麻烦一点,看看前段时间沸沸扬扬的伪基站就知道这些技术已经成功地在黑市商用了。
VII. 3、为什么把手机调成2G了也嗅探不到自己的短息?
在所有操作成功的前提下,能嗅探到别人的短信却抓不到自己的大概是因为抓取的ARFCN和手机选择的ARFCN不是同一个,一个区域可能有几个到十几个可以注册的ARFCN,原则上手机一般会自动选择信号最强的ARFCN注册,但是具体注册哪里一个还是有手机系统来确定,所以要完整抓取一个区域内所有的下行短信,需要“一机对一基”,这一块有相应的OsmocomBB版本如果有时间再详细写一下。
目前已经成功地在Nexus 7上把OsmocomBB编译出来,编译一个支持OTG的CP210x驱动的内核刷入之后就可以移动作战了。前两天看到NetHunter支持Nexus 7,一并刷入试试看……
VIII. 4、如何查看ARFCN?
打开手机的拨号界面,输入按照下表输入后进入工程模式,选择GSM Cell Environment->GSM Cell Info->GSM Serving Cell,就可以看到目前手机连接的基站ARFCN值了。
iPhone 全系列 *3001#12345#*
Samsung (Android): *#*#197328640#*#* or *#0011#
HTC (Android): *#*#7262626#*#*
通用(Android) *#*#4636#*#*
To be continue....