基于OpenBTS和USRP B210搭建GSM网络

写在前面

最近需要在SDR环境中验证目标终端中的GSM协议实现漏洞,本文记录下环境的搭建(踩坑)过程。最开始是尝试根据Grant大佬的博客尝试安装,其中对于GSM环境的搭建原文采用的是YateBTS+BladeRF或者USRP N210的组合,然而,在根据文章安装YateBTS时访问不了官方的SVN库,并且似乎最新版的YateBTS不再支持UHD驱动,因此最后选择了使用OpenBTS+USRP B210的方式。

参考:

  • https://www.twblogs.net/a/5b8661f72b71775d1cd52363/?lang=zh-cn

  • https://blog.white-alone.com/OpenBTS使用指南/

  • https://www.miralishahidi.ir/resources/Open BTS Application Suite.pdf

背景知识

首先在SDR方面比较小白,先去了解了下当前主流的集中SDR软件+硬件的组合,其中常见硬件有:

  • HackRF
  • BladeRF
  • LimeSDR
  • PlutoSDR
  • USRP

这些硬件支持的频率范围、带宽等不仅相同,价格也有高有低,根据具体需求选择即可。此外,对于开源的基站项目,由于横跨2G-5G的不同版本,具体选取哪个开源实现也是根据需求而定

2G:

  • YateBTS+BladeRF
  • OpenBTS+USRP
  • OpenBSC + (USRP、Fairwaves UmTRX、LimeSDR)

3G:

  • Accelerate3g5
  • OpenBTS

4G

  • Open Air Interface (OAI) +USRP
  • OpenLTE (BladeRF USRP)
  • SRSRAN+USRP

5G

  • OAI-5G

最后由于前边的尝试,最后选择OpenBTS+USRP B210进行安装

GSM SDR环境搭建

系统-Ubuntu16.04 LTS

选择使用Ubuntu16.04 LTS的虚拟机作为安装系统(最好选择纯净系统+原始的源,我这边换了国内源之后出现了有些依赖包找不到的问题,手动一个个寻找巨麻烦)

安装UHD

  • 首先从github上clone UHD的开源项目,并将其切换为3.14.0.0的分支
git clone https://github.com/EttusResearch/uhd
cd uhd
git checkout v3.14.0.0
  • 其次就是编译和安装了
首先安装依赖
sudo apt-get -y install git swig cmake doxygen build-essential libboost-all-dev libtool libusb-1.0-0 libusb-1.0-0-dev libudev-dev libncurses5-dev libfftw3-bin libfftw3-dev libfftw3-doc libcppunit-1.13-0v5 libcppunit-dev libcppunit-doc ncurses-bin cpufrequtils python-numpy python-numpy-doc python-numpy-dbg python-scipy python-docutils qt4-bin-dbg qt4-default qt4-doc libqt4-dev libqt4-dev-bin python-qt4 python-qt4-dbg python-qt4-dev python-qt4-doc python-qt4-doc libqwt6abi1 libfftw3-bin libfftw3-dev libfftw3-doc ncurses-bin libncurses5 libncurses5-dev libncurses5-dbg libfontconfig1-dev libxrender-dev libpulse-dev swig g++ automake autoconf libtool python-dev libfftw3-dev libcppunit-dev libboost-all-dev libusb-dev libusb-1.0-0-dev fort77 libsdl1.2-dev python-wxgtk3.0 git-core libqt4-dev python-numpy ccache python-opengl libgsl-dev python-cheetah python-mako python-lxml doxygen qt4-default qt4-dev-tools libusb-1.0-0-dev libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools python-qwt5-qt4 cmake git-core wget libxi-dev gtk2-engines-pixbuf r-base-dev python-tk liborc-0.4-0 liborc-0.4-dev libasound2-dev python-gtk2 libzmq-dev libzmq1 python-requests python-sphinx libcomedi-dev python-zmq python-setuptools
其次
cd uhd/host
mkdir build
cd build
cmake ../
make -j 8
    
make test # 测试
sudo make install # 这里使用root权限安装不然会失败
  • 设置环境变量
在build目录下
sudo ldconfig
export LD_LIBRARY_PATH=/usr/local/lib
然后运行脚本安装所需镜像
sudo /usr/local/lib/uhd/utils/uhd_images_downloader.py
  • 测试是否安装成功
sudo uhd_find_devices
--------------------------------------------------
-- UHD Device 0
--------------------------------------------------
Device Address:
    serial: 171830
    name: 
    product: B210
    type: b200

安装OpenBTS

参考官方的安装文档,首先安装依赖

git clone https://github.com/PentHertz/OpenBTS.git
$ cd OpenBTS
$ # Optionally, checkout 5.1.0 branch which is the stable one with `git checkout 5.1.0`
$ ./preinstall.sh # note that for now libcoredumper will show some failures but we quickly bypass them forcing the compilation

编译安装OpenBTS

$ ./autogen.sh
$ ./configure --with-uhd # use different options for other drivers
$ make -j$(nproc)
$ sudo make install
$ sudo ldconfig

在make这里我遇到了一些报错,修改了如下两个地方

  • 将下边代码中的(BctbxLogFunc) 删掉
void MySipInterface::msiInit()
{
	siInit();
	// Start the ortp stuff. 
	ortp_init();
	ortp_scheduler_init();
	// FIXME -- Can we coordinate this with the global logger?
	//ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);

	ortp_set_log_handler((BctbxLogFunc) ortpLogFunc);

	mDriveThread.start((void *(*)(void*))driveLoop2, &gSipInterface );
	mPeriodicServiceThread.start((void *(*)(void*))periodicServiceLoop, &gSipInterface );
}
  • 将下边代码中的强制类型转换中的(void *)删掉
rtp_session_signal_connect(mSession,"timestamp_jump",(RtpCallback)ourRtpTimestampJumpCallback,(void *) dialogId);

然后即可成功编译,运行固件

$ uhd_usrp_probe 
[INFO] [UHD] linux; GNU C++ version 11.2.0; Boost_107400; UHD_4.1.0.5-3
[INFO] [B200] Loading firmware image: /usr/share/uhd/images/usrp_b200_fw.hex...
[INFO] [B200] Detected Device: B210
[INFO] [B200] Loading FPGA image: /usr/share/uhd/images/usrp_b210_fpga.bin...
[...]

设置流量转发

sudo su 
echo 1 >> /proc/sys/net/ipv4/ip_forward

配置iptables规则,/etc/OpenBTS/iptables.rules 配置规则文件内容如下:

# Generated by iptables-save v1.4.4
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Generated by iptables-save v1.4.4
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

根据情况设置为自己的网卡

sudo iptables-restore < /etc/OpenBTS/iptables.rules
iptables -t nat -L -n -v

启动OpenBTS

上述组件全部安装完毕后,需要启动以下组件以连接USRP B210以及手机

配置数据库

cd apps
sudo sqlite3 -init OpenBTS.example.sql /etc/OpenBTS/OpenBTS.db ".quit"

cd subscriberRegistry/apps
sudo sqlite3 -init sipauthserve.example.sql /etc/OpenBTS/sipauthserve.db ".quit"

cd smqueue/smqueue
sudo sqlite3 -init smqueue.example.sql /etc/OpenBTS/smqueue.db ".quit"

启动transceiver连接SDR硬件

cd Transceiver52M/
sudo ./transceiver

执行OpenBTS启动基站

cd apps/
sudo ./OpenBTS

启用短信服务

cd smqueue/smqueue
sudo ./smqueue

启动鉴权服务

cd subscriberRegistry/apps
sudo ./sipauthserve

启动OpenBTS终端控制台

cd ./apps
sudo ./OpenBTSCLI 

根据参考链接,刚搭建完成的基站由于天线功率过大以及手机跟基站的距离太近等原因,可能会导致手机不能正常加入到基站,这时需要配置加入基站的条件以及设置天线功率:

开启任意终端准入

OpenBTS> config Control.LUR.OpenRegistration .*
Control.LUR.OpenRegistration changed from "" to ".*"

设置天线功率

如果手机可以搜索到基站,就表明网络状态良好,但如果有较强的无线干扰,也就是噪声干扰俗称底噪,手机和基站的链路就可能会有问题。可以用noise命令检查噪声强度:

OpenBTS> noise
noise RSSI is -60 dB wrt full scale
MS RSSI target is -50 dB wrt full scale
WARNING: the current noise level is approaching the MS RSSI target, uplink connectivity will be extremely limited.

表示检测到的背景噪声RSSI信号强度为-71dB,这个数值越小表明底噪越少。配置的RSSI信号强度为-50dB,也就是说,基站所能提供的最高信号强度为 21 dB。一个好的差值意味着上行链路质量不错。两个数据的差值不同反馈信息也不同,如果差值小于10db,那么就会像前一个反馈的警告信息,提示噪声干扰强度已经接近所配的RSSI,上行链路质量非常有限。如果差值小于0db,会有警告提示噪声干扰比配置的RSSI信号还强,无法建立上行链路。

OpenBTS> devconfig GSM.Radio.RxGain 18
GSM.Radio.RxGain changed from "50" to "18"
GSM.Radio.RxGain is static; change takes effect on restart

设置频段

OpenBTS> config GSM.Radio.Band 900
GSM.Radio.Band changed from "850" to "900"
GSM.Radio.Band is static; change takes effect on restart 

设置欢迎短信

config Control.LUR.NormalRegistration.Message Welcome to BTS 1

终端管理

cd NodeManager/
python2 ./nmcli.py sipauthserve subscribers create "Redmi Note 12 Turbo" IMSI460110123456789 123456
python2 ./nmcli.py sipauthserve subscribers read

查看注册的手机:

OpenBTS> tmsis
IMSI TMSI IMEI AUTH CREATED ACCESSED TMSI_ASSIGNED

我理解这个步骤应该只是为接入的的中断在当前网络注册相应的电话号。前边设置允许任意终端准入时,只需要把蜂窝网络设置为仅GSM即可接入当前OpenBTS

短消息测试

启动短消息服务时, 我们就可以给任意终端发送短信,并且在设备初次接入网络时,收到我们上述设置的欢迎短信。在手机中,写一条短信发给411。这是smqueue中的一个简码处理流程,只管回显,不管其他接收、网络及用户信息等整个流程所用任何信息。发送给411的短信的可以是任意内容,可以是任意的文字或者数字或者字母。这个可以用来帮你确认哪条消息在回应时候出错。编写一条发往411短信,点击发送,几秒钟之后,应该会出现应答

使用命令行发送短信

OpenBTS> sendsms XXXXXXX AAAAA "You are arrested"
message submitted for delivery

其中XXXXXXX是设备的IMSI号码,AAAAAA是虚拟的手机号(显示为发送方),注意不支持中文内容

互相发送短信:

  • 设备之间也可以互相发送短信,比如两台都在该网络中注册的手机设备,通过手机号即可向对方发送消息

电话测试

Asterisk配置

 sudo asterisk -r

拨打电话600在经过一段语音后,会回传你发送过去的语音信息

两个手机通话

这里默认使用apt安装的Asterisk,在/etc/asterisk下的配置文件看起来非常不好配置,网上找的博客也没有介绍,后来偶然间发现github上有人配置好的文件,配合前文参考链接,在sip.conf添加

;openbts
[IMSI001010123456789]
callerid=12580
canreinvite=no
type=friend
context=sip-external
allow=gsm
host=dynamic
dtmfmode=info

[IMSI460110123456789]
callerid=10123
canreinvite=no
type=friend
context=sip-external
allow=gsm
host=dynamic
dtmfmode=info

在extensions.conf添加

[sip-external]
exten => 100,1,Dial(SIP/0000FFFF0001) ; Replace 0000FFFF0001 with your device name


exten => 101,1,Dial(SIP/0000FFFF0002) ; Replace 0000FFFF0002 with your device name


exten => 200,1,Answer()
   same => n,Playback(hello-world)
   same => n,Hangup()


exten => 201,1,Goto(TestMenu,start,1) ; add this to the end of the
                                      ; [LocalSets] context
exten => 12580,1,Dial(SIP/IMSI001010123456789@127.0.0.1:5062) ; Replace 0000FFFF0002 with your device name
exten => 10123,1,Dial(SIP/IMSI460110123456789@127.0.0.1:5062) ; Replace 0000FFFF0002 with your device name

GSM抓包&重放

捕获GSM报文(未实现)

根据[手册](https://www.miralishahidi.ir/resources/Open BTS Application Suite.pdf) 6.5章节中的提示,需要手动开启GSM流量转发才能用wireshark捕获到GSM流量。因此需要运行以下命令:

OpenBTS> rawconfig Control.GSMTAP 1
OpenBTS> rawconfig Control.GPRS 1

但是我这里只能捕获到RR协议的报文以及SMS协议的报文,MM、CC等L3层的报文还是捕获不到(大概是因为具体的payload都是在sip协议里边发过去的)。

报文篡改

  • OpenBTS的官方手册

[https://www.miralishahidi.ir/resources/Open%20BTS%20Project.pdf](https://www.miralishahidi.ir/resources/Open BTS Project.pdf)

根据架构推测OpenBTS是这样实现通话逻辑的:发起通话请求是手机1->BTS->手机2,其中手机1->BTS用GSM消息通信,BTS将SETUP请求解析并包装成SIP报文,根据asterisk的配置找到手机2,基于解析的SIP报文,包装成GSM报文发送给手机2。

由上可知一个可行的思路为直接修改BTS代码,让其直接发送加了payload的报文。

日志监控

  • 拨打*#9900# 可以进入三星的日志系统sysdump,可以dump一些有意思的日志(暂未深入研究),这篇文章说了下怎么本地激活sysdump中的两个特殊功能(暂时没用到)
  • 使用adb的logcat(FIRMWIRE作者曾在talk中用这个观察到设备崩溃)

真机调试?

可以参考Synacktiv的文章,通过TEE的漏洞,重写modem固件,将一个调试器写到不用的代码段中实现调试功能:

  • SSTIC 2020 How to design a baseband debugger
  • 17
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值