前言
在过去的几周时间里,我从多个方面对GSM的安全性进行了调查和研究,例如GSM通信协议中存在的漏洞。除此之外,我还对目前世界上应用最为广泛的BTS软件进行了安全审计。在这篇文章中,我将会给大家介绍一下我在这款开源产品中所发现的多个漏洞,这些漏洞将允许攻击者入侵基站收发信台(BTS),并远程控制它的信号收发模块。
背景知识
一个基站收发信台(BTS)是由软件和无线电设备组成的,它是智能手机连接GSM、UMTS、以及LTE网络时必不可少的关键组件。BTS主要分为基带单元、载频单元和控制单元三部分。基带单元主要用于话音和数据速率适配以及信道编码等;载频单元主要用于调制/解调与发射机/接收机间的耦合;控制单元则用于BTS的操作与维护。BTS中存储编码算法A5和密钥Kc,用于解密接收到的密文形式的用户数据和信令数据(包括解密)。
它相当于Wi-Fi网络中的无线接入点,它负责管理Um接口的通信过程。Um接口是MS(MobileStation,移动台)和BTS之间的接口,通过该接口,MS完成与网络侧的通信,完成分组数据传送、移动性管理、会话管理、无线资源管理等多方面的功能。Um接口是GSM/GPRS/EDGE网络中,MS与网络之间的接口,也被称为空中接口(AirInterface)。Um接口用于传输MS与网络之间的信令信息和业务信息。具体如图一所示:
图一:MS与BTS的连接
BTS的底层软件实际上是一个信号收发器,而它就是无线硬件设备的直接接口。它主要负责频率调谐,并处理GMSK(高斯最小移频键控)数据的调制与解调。简而言之,它主要负责的是将无线电波转化成数字信号。BTS其余逻辑单元的通信和同步操作都是由图二所示的三个UDP数据包负责处理的。
图二:信号收发模块以及用来与BTS其余逻辑单元进行通信的三个UDP数据包
其如上图所示,“ClockSocket”数据包主要负责进行时间同步;BTS会使用“CommandSocket”数据包来向信号收发器发送控制命令;最后,“DataSocket”数据包负责将GSM数据包从BTS通过无线电信号广播出去,然后接收返回的响应信息。其中,信号收发器模块中的“UDPSocket”类主要负责处理上述三个信道的通信过程。
我们的分析表明,目前大多数BTS软件所使用的都是同一个(或者极其相似的)收发器代码库。因此,基本上这些BTS软件都会受到相同漏洞的影响。恶意攻击者可以利用这些漏洞来远程控制信号收发器模块,从而影响BTS的正常功能。
不仅如此,攻击者还有可能向收发器模块发送GSM数据脉冲,然后对移动用户进行各种网络攻击,例如IMSI分离、加密降级、以及拒绝服务攻击等等。
为了让信号收发器模块能够接收并处理攻击者发送的信息,发送至数据信道套接字的UDP数据包必须遵循下列格式:
当信号收发器模块接收到了这些数据包之后,它会解码这些数据包,然后使用GMSK来进行信号调制。最终,不同内容的信号脉冲将会被发送到与之相连的移动台(MS)。
即便是下方列表中标注的产品只使用了GMS或者UMTS网络,但是它们的信号收发器模块(这是一个独立组件)本身却是基本相同的。所以我们推测,负责处理LTE连接的BTS软件同样也使用了类似的信号收发器代码。
受影响产品
-YateBTS<= 5.0.0
-OpenBTS<= 4.0.0
-OpenBTS-UMTS<= 1.0.0
-Osmo-TRX/Osmo-BTS<= 0.1.10
-以及其他使用了相同信号收发器代码的产品
相关厂商
-Legba股份有限公司(YateBTS)
-RangeNetworks(OpenBTS和OpenBTS-UMTS)
-OsmoCOM(Osmo-TRX和Osmo-BTS)
问题一:过度暴露的服务绑定
概述
这个漏洞存在于上述产品的网络库中,这个问题导致信号收发器的UDPsockets地址绑定到了0.0.0.0,但是这三个信号收发器的地址应该绑定到用户设置的地址上(默认为127.0.0.1)。这也就意味着,攻击者可以利用这些地址来与BTS系统进行连接,并从信号收发器中接收(发送)数据包。除此之外,访问这些暴露了UDP网络套接字的服务其安全性将无法得到保障,因为任何身份验证机制都无法保证这些服务的安全。
图三:三个信号收发器的套接字地址全部绑定到了地址0.0.0.0
影响
攻击者可以使用IP连接来发送UDP数据包,并获取BTS的所有功能。这也就意味着,攻击者可以实现远程控制、GSM流量劫持、获取用户的通信数据、DoS拒绝服务攻击,甚至还会发生更加糟糕的事情。
细节披露
我们可以在UDPSocket类的构造器中找到引起这个漏洞的根本原因。在源文件“CommonLibs/Sockets.cpp”中,你可以找到“UDPSocket::open”方法,而正是这个方法中的错误代码才导致了这个漏洞的存在。值得注意的是,所有受影响的产品中都包含有这份源文件。下面这段代码就是漏洞代码:
从上面的代码段中我们可以看到,系统将绑定的地址保存到了mDestination类的成员变量中,但是UDPSocket::open方法的实现方式却是这样的:
尽管UDPSocket类提供了一个构造参数来指定服务器所要绑定的IP地址,但是这部分数据却被代码忽略了。正如上图第272行代码所示,通信socket被绑定到了INADDR_ANY,然而并没有使用mDestination地址变量。
问题二:基于栈的远程缓冲区溢出
概述
攻击者可以通过向设备的控制信道发送一个较大的UDP数据包来引起栈缓冲区的溢出。
影响
攻击者可以实现远程代码执行(RCE)或者对设备发动拒绝服务(DoS)攻击。
细节披露
控制信道是由源文件Transceiver.cpp中的Transceiver::driveControl方法控制的。这部分代码如下所示:
注意代码中数据包的缓存空间,这部分空间存在于方法栈中,其大小被定义为100字节(MAX_PACKET_LENGTH)。
接下来,我们对源文件Sockets.cpp中声明的DatagramSocket::read方法(DatagramSocket类是UDPSocket类的父类)进行了分析,结果我们发现了下列信息:
我们可以看到,代码读取的是MAX_UDP_LENGTH所代表的长度,并非MAX_PACKET_LENGTH变量的值。而MAX_UDP_LENGTH的值是在Sockets.h源文件中定义的,如下图所示:
因此,攻击者只需要向信号收发器发送一个大小超过100字节的UDP数据包,就可以成功在目标设备上引起栈溢出。图四显示的是该漏洞所引发的错误调试信息:
图四:由于UDP数据包过大所导致的数据包切分错误
问题三:未经身份验证的远程控制
概述
控制信道并没有引入任何形式的身份验证机制。再加上‘问题一’使得其部分信息暴露在了外部网络中,所以恶意攻击者就可以利用这个漏洞来远程控制信号收发器模块。
影响
攻击者可以:
-通过关闭模块来实现拒绝服务攻击。
-通过修改无线电信号频率来阻塞信号发送。
-通过“SETBSIC”命令远程劫持BTS。
细节披露
控制信道使用源文件Transceiver.cpp中的Transceiver::driveControl方法来处理UDP协议。该协议暴露的部分功能包括:
-开启或关闭TRX模块:CMDPOWERON / CMD POWEROFF
-更改TRX的无线频率:CMDRXTUNE frequency / CMD TXTUNE frequency
-设置GSM信号的验证信息:CMDSETBSIC value
攻击者只需要向服务器的5701端口发送一个简单的UDP数据包,就可以远程执行上面这些
结论,缓解方案,以及建议
通过这篇文章,想必大家已经了解了这些代码漏洞和身份验证机制的缺乏将会如何影响上述的这些BTS产品了。而且不仅如此,攻击者甚至还可以利用这些漏洞来发动大规模的网络攻击。
我们强烈建议厂商赶紧采取下列的缓解措施,以提升相应产品的安全性能:
1. 更新你的BTS软件,如果收到了更新补丁推送,请尽快安装补丁程序。
2. 将用于控制操作和数据转换的socket地址绑定到本地接口(127.0.0.1)。
3. 防火墙:阻止流经端口5701(控制端口)和端口5702(数据端口)的所有外部网络流量。
4. 引入身份验证系统,以防止没有权限的攻击者通过BTS控制端口来登录服务器或访问网络。
5. 修复代码中的缓冲区大小问题。
6. 进行额外的代码审计。
* 参考来源:ZIMPERIUMzLabs