Article Learn

2019小米IoT安全峰会-曾颖涛《蓝牙安全之第二战场》

Post by Pa0er at 2020-01-02 14:03:15

此次大会的第六个重磅议题来自小米AIoT安全实验室研究员-曾颖涛,他给大家带来的议题是《蓝牙安全之第二战场》。

今天的议题主要想给大家分享一下蓝牙通讯中比较少有人关注到的一些安全隐患。将从四个方面进行探讨,首先是蓝牙设备的设备联动。所谓的设备联动其实是依靠于拥有蓝牙和wifi双通道的设备,作为一个蓝牙网关,把蓝牙报文通过wifi的方式传输到云端,用户可以在户外通过云端获取家里传感器的数据。以及设置家里的温度湿度大于多少就会触发空调之类的电器,比如智能门锁触发到开锁或者开门事件后会打开家里的照明系统,让这些原本没有办法访问网络的产品具有上传数据以及联动其他设备的能力。

设备与网关端的通信主要依靠于蓝牙的广播协议,使用的是私有的协议,可以用自带无线网卡去抓取再进行解析,协议中有一个FrameCtrl字段,表示协议的参数以及表示数据是否加密等信息。剩下PID,该字段表示广播是由哪个蓝牙设备发射出来的,比如门锁,温湿度的传感器或者蓝牙的遥控。EID则表示是广播中数据内容的类型,传感器数据,设备电量,开关门事件等等类型,具体可以参考下图。

而大部分设备的蓝牙广播都没有加密,任何人都听到蓝牙广播的内容数据,可能是协议的开发者认为环境类的数据不是特别敏感就没有进行加密,实际上在配对的阶段会产生蓝牙广播密钥,但只有门锁之类的安防设备在广播事件时候才会用到这个密钥对数据进行加密。

另外广播协议是明文并没有校验,是可以任意人被伪造的,设备与网关端的鉴权只是判断了蓝牙广播的MAC地址,这个地址也是可以被修改的。再知道广播的协议后便可以伪造传感器广播数据内容,比如说伪造一个温湿度计差别比较大的数据内容。

其次,这个广播的数据加密是由设备端自己来确定的,由刚刚说的FrameCtrl字段进行表示,然后可以伪造一个门锁的报文将FrameCtrl修改为明文再传给网关,发现这样就绕过了原本的加密机制。

这里比较有危害的并不是直接去伪造数据或者事件来欺骗用户,而是影响了整个智能联动的场景。比如门锁被触发后打开家里的照明系统,传感器温度发生变化后就打开室内电器,因为这些因素导致原本没有隐患的智能电器被一环扣一环进行恶意操纵。

说完联动问题再说一下芯片厂商给我们带来的安全隐患,据分析发现产品设备固件的校验和OTA升级都是由生态链公司负责的,大部分生态链厂商都是参考芯片厂商提供的SDK例程进行开发,这样可能会导致一些安全风险。

举一个厂商A的例子,低版本的SDK开发会把固件打包成一个OTA包,包里面包含了固件的签名,但是签名只有一个版本信息以及固件的CRC16的校验码,这样别人也可以自己编译一个固件,计算固件的校验码就伪装成了一个合法的升级包了,去接管原本程序中的硬件控制逻辑。另外很多产品出厂就自带电池,比如编译一个恶意固件然后往附近的蓝牙设备升级我们的固件,把这设备带到库房或者旗舰店附近,就可能导致这一批设备变砖或者被攻击者恶意控制。但是A厂商也推出了安全的解决方案,即再新版本强制对固件进行公私钥签名的保护。

另外说一个厂商B的案例,固件前的4个字节包含硬件的设备信息以及版本信息,厂商是提供加密的,但是在分析过程中发现用B厂商芯片的生态链厂商没有一家是对这个固件进行了加密的,假如构造编译好的固件后也可以算出这些校验码的。但是厂商也推出了安全的解决方案,即在新版本加入了对固件签名的保护。

还有一些其他厂商的案例,比如去年被爆出过某个厂商所有的芯片都是用了一个硬编码的密钥去校验OTA升级者的身份,还有一些是使用了默认的密钥去加密设备的固件。

还有个是产品厂商在使用参考的例程进行开发中,原本的例程中会带有芯片控制指令,这些控制指令是没有鉴权的。即使使用了带签名的保护措施或者对固件加密保护,但也是会受芯片原厂的控制指令所影响的。有些设备通过指令可令其进入到DFU模式,在这种模式下,有些设备会在几分钟之内会恢复正常,有些着会一直处于这种状态下直到重启设备,也有很多蓝牙指令可以让设备直接宕机。

下面分享一些蓝牙硬件的安全问题。

这是以硬件安全芯片为例搭建的开发环境。蓝牙芯片跟安全芯片之间的通信用的是硬件I2C进行数据交互,双方会通过一种ECC公私钥对的方式运算得到共享密钥,接着设备会根据OOB的数据和共享密钥进行运算得到设备的主密钥,然后在完成绑定后设备会产生一个随机值randKey去把主密钥进行加密,然后将加密后的数据存放到加密芯片的存储空间中,这里有一个隐患是由蓝牙芯片去保存加密用到的randKey,这个是可以通过一些方法读取出来的。

产品开发者为了防止蓝牙芯片中的数据被人恶意读取会设置相关的读保护寄存器,这样就不能通过调试接口去直接读取芯片Flash中的数据了。但是A厂商前几年被曝出有芯片上面的缺陷,没有办法直接读出数据但是可以操作一些寄存器,在寄存器中找到原本程序的LDR读取指令,再修改寄存器的读取地址去指向我们想读取的Flash地址,这样就可以绕过原本的读取保护了,在类似架构的芯片也出现过这个问题,不过在A厂商新版本硬件中也已经修复了。具体的操作是通过Jlink的方式连接蓝牙芯片,然后中断原本的程序逻辑进行单步调试,再执行下一步操作时发现R0寄存器数据发生了改变。我们认为刚刚进行了读取数据的操作,把R4寄存器以及PC指针指回刚才的地址,把刚才指令数据进行反汇编分析,发现就是我们找的LDR的指令。通过反复通过跳回到LDR的地址后每次可以读取四个字节数据,通过这种方式可以将所有数据进行读出。芯片采用的是FDS存储方式,默认配置会在Flash中开辟8K的存储空间,用于存放刚才提到的randKey以及token,广播密钥等信息,可以通过判断FDS的标志符去确认数据的起始空间和结束空间,然后通过记录id就可以找到randKey了。

因为加密芯片跟蓝牙芯片之间的通讯是明文的I2C通讯方式,并且它只是对指令进行了CRC的校验,我们可以用自己的开发板去构造一个读取数据的指令,然后就可以把加密后的密文读取出来,有了蓝牙芯片读取出来的randKey就能解开密文得到主密钥。

最后说一下蓝牙审计的框架,每个硬件产品上线之前都会经过我们安全审计,而且大部分产品要进行重复性比较高的审计过程,为此我们搭建了一个BlueEye的审计框架,通过爬取后台每个产品的固件,就可以得知产品所采用的芯片方案的特征,然后可以从它的固件里面判断有没有OTA签名,或者有没有对固件进行加密的一些安全措施,图中红色区域是有存在问题的产品,可以在设备还没有拿到手的情况下进行分析,并且提前得到一些OTA的安全风险信息。

其次抓蓝牙设备的广播包还是比较麻烦的,因为周围有很多蓝牙设备,很难确认手头上设备蓝牙的MAC地址。我们通过可以写程序去解析蓝牙私有广播协议,通过这种方式知道周围有哪些设备,采用了什么方案,有没有进行验证签名,正在广播什么数据内容,有没有控制指令上面的安全问题,可以通过这种方式减少重复性比较高的工作。

这是整体的审计框架,有部分功能还在开发中,比如我们希望能通过相同芯片的开发版的方案模拟产品固件,然后可以在没有拿到手的情况下对产品进行简单的安全测试,并且扫描固件版本之类的信息判断会不会存在一些历史已知漏洞。在拿到设备之后扫描蓝牙开放的UUID,确定芯片的方案,以及进行数据包的嗅探。另外我们可以通过3个BLE Dongle抓取GATT层的控制指令,并对这些指令进行重放或者逆向的分析,然后人工只要比较简单的操作就可以对这些设备进行安全的审计。

另外我们产品面临着各种各样的安全风险,比如说芯片厂商的,设备厂商的,蓝牙协议层的,比如一些接入米家的产品设备厂商,我们是要求他们强制地参考SDK的开发标准去开发,但是也会有一些厂商没有按照标准进行判断,比如没有校验控制者身份之类。其次是我们自己的私有协议也不是特别强壮还有一些不完善的地方,我们希望建立起一个比较好的认证体系,把OTA升级放入米家蓝牙登录之后,它的升级固件必须带有米家的签名,控制指令之前要判断米家的登录状态,另外我们希望利用BLE MESH的组网技术去保证连接层的安全,同时想通过这种机制降低一些不严格遵守安全开发规范的厂商被攻击的安全风险。

—   联系我们   —

新浪微博

公众号