2021看雪SDC议题回顾 | 基于模拟仿真的蓝牙协议栈漏洞挖掘

发布者:Editor
发布于:2021-11-01 18:36

蓝牙协议栈在IoT安全中的重要性不言而喻,妥善的利用模拟技术能巨幅提高研究效率,并减少对工具、环境的依赖性。


贾舵先生的议题以NRF52平台的模拟为案例,深入浅出的介绍了如何结合虚拟仿真技术对物联网中的蓝牙固件进行全状态的模拟,实现动态执行与调试,并且进一步就模拟器在实际漏洞挖掘应用中的实践经验进行分享。


下面就让我们来回顾2021看雪第五届安全开发者峰会《基于模拟仿真的蓝牙协议栈漏洞挖掘》此议题的精彩内容。


图片


演讲嘉宾


图片


图片

【贾舵-阿里安全IoT安全专家】


贾舵:阿里IoT研究团队安全专家


专注物联网安全、汽车安全、虚拟化仿真技术的应用。



演讲内容


以下为速记全文:


各位来宾朋友大家好,我叫贾舵,目前在阿里做IoT的安全研究,今天我跟大家分享的议题是《基于模拟仿真的的蓝牙协议栈的漏洞挖掘》。议题分为五个部分,首先是做一个背景介绍,第二部分是我们模拟技术的实现,然后是模拟在我们漏洞挖掘中的应用,第四部分是案例展示,最后会做一个总结。



背景介绍


首先第一部分是我们的背景介绍,这部分会介绍两个内容:一是我们的IoT蓝牙协议栈;第二是我们为什么要去做模拟?


我们的智能设备目前的话是有两个明显的一个发展方向,一个是朝着我们功能化的方向,这里面典型的有我们的路由器,还有智能音箱、智能电视,以及现在比较流行的智能汽车。


另外一个方向是我们的可穿戴的方向,它逐渐是向这种小型化的一个方向发展。这里面典型的有我们无线的耳机,还有运动手环等。在这些设备里面的话,其实我们的蓝牙的应用是非常广泛的,承载我们蓝牙功能的是蓝牙协议栈,我们今天针对的是我们可穿戴方向的蓝牙协议栈,为了区分,我们称之为IoT的蓝牙协议栈。


根据它的一个应用场景的一个不同,我们 Iot的蓝牙协议栈它会区别于我们的 PC或者是操作系统,它会有一些自己的特点。


对于我们运行IOT蓝牙协议栈的一个平台,它的资源是非常有限的,体现在它的一个 CPU的资源上,还有的话是它的一个存储限制,这样要求协议栈往往是一个非常轻量化的实现。那么同时的话我们iot设备往往会要求一些实时性,那么需要一个快速的响应的能力,同时我们无线的设备往往是用移动的电池来供电,所以的话它会有一些低功耗的特性。


正是因为有这些特点的话,所以我们实际在做 IoT协议栈的应用的过程中,它往往会和我们的硬件去结合在一起,也就是我们的蓝牙SOC。我们常用的一些蓝牙SOC包括nordic的nrf52系列,还有 TI的CC系列。蓝牙协议栈其实是我们物联网中基础的一个组件之一,它的一个漏洞的话往往会影响到一个范围的设备。


图片


我们今天其实要讲的是通过模拟的方法去对它做一个漏洞挖掘方法的阐述。这里面就有一个问题,就是我们为什么要去做一个模拟?我们模拟的一个目的其实是为了解决我们物理世界的阻碍因素,建立一个我们理想的虚拟世界。


图片


当我们采用一个新的方法的时候,一定是传统的方法给我们带来一些不利的因素,实际上我们在做蓝牙的漏洞挖掘的过程中会面临一些困难,主要体现在几个方面。


首先的话是一个环境的干扰,我们周边的话其实有很多这种2.4G的设备,包括我们的耳机或者鼠标键盘,同时还有2.4G的wifi,会形成一些干扰;然后就是蓝牙自身跳频的一个影响,这会直接影响到我们对数据的一个监听。那么对于BLE蓝牙来说的话,我们可以对它的广播信道做一个非常好的监听,但是对它的数据信道的话,如果我们做一个真正的旁路监听还是比较困难的。



模拟技术实现


第二个部分是我们调试上的困难。我们如果想去通过硬件去建立一个完整的一个调试环境的话,还是有一定难度的,主要受限于硬件对调试的一个限制,还有就是硬件自身的一个熔断机制。第三个方面是我们工具的一个依赖性,在我们漏洞挖掘的过程中会应用到很多的工具软件和硬件,我们很多精力要去做这个软件跟硬件的稳定性的维护,这就导致我们没有办法去专注数据本身的一个操作。


另外工具的依赖性也会造成我们测试范围的受限,这个图的是我们 BLE蓝牙的一个协议结构图,我们常用的一些测试的工具,比如说nrf52 dongle和cc系列的dongle,还有一些USB蓝牙的适配器的话,他们是基于一个hci接口来控制,我们 PC端的话可以通过一些协议栈的工具去做一个访问,那么最后实现对我们应用的属性蓝牙属性的一个读和写。


那么这里面的话,因为我们这些工具其实是建立在物理层和链路层上的,链路层的逻辑其实是固化在我们的硬件工具当中的,这就导致我们没有办法对链路层去做一个测试。那第二个的话就是我们这些工具的话,一般是通过 hci接口来去访问的,hci接口本身它是一个功能性的接口,它并不是一个测试接口,所以本身也会受到一些限制。我们通过模拟的手段就是为了将我们一些复杂问题简单化,这个图的话是我们在物理环节中想对蓝牙协议栈的测试场景,这里面可能会用到一些软件无线电或者ubertooth等。


对于我们这个图的本质,其实是为了做蓝牙数据的一个交互,对于我们安全研究者来说的话,我们最希望的其实是有一个接口,通过这个接口的话做协议的一个交互,达到我们测试的过程。


实现这个过程的转换,其实就是我们需要做的模拟实现的部分,也就是我们第二个内容要讲的模拟技术。这一块的话我会讲两个内容,一个是对我们模拟对象的分析,第二个是我们模拟的设计方法。


首先刚才我们讲了几个蓝牙的SOC的平台,这里面我们会以 nrf52作为对标的模拟对象,这里面有一些参数可以看一下,在这里面我们其实最关心的还是协议栈的问题。


nrf52平台目前有两个应用比较广泛的蓝牙协议栈,一个是 softdevice,这是nordic官方的一个协议战,是有商业化的。


第二个的话是一个开源的协议栈叫Zephyr,这个也是非常活跃,由现在的一个社区去维护的。这是我们整体的一个设计思路,我们模拟器的话是基于 qemu5.1的版本,建立在 arm的架构的模拟基础之上,我们模拟的目标是基于Zephyr和SoftDevice的应用固件,当然也可以包含我们普通的基于这个平台的固件,那么具体怎么实现?


从硬件的一个角度来讲的话,我们的固件其实可以分为两个层次,一个部分是我们固件里面其实是大量的这种arm的指令,这些指令的话它会对我们的特定的一些数据做一些读写的操作,形成我们对外设的访问。


这些外设的话可能会包括比如GPIO、I2C或UART这些,我们要实现一个模拟的话,首先我们要对它的一个CPU的核心做一个模拟,qemu目前已经对Cortex-M4的一个内核做了支持,我们可以直接拿来用。


以此为基础,我们可以做一些基础硬件模拟的扩展,包括内存中断还有寄存器,但是这些还是远远不够的。


图片


在模拟实现的过程中,最重要的是我们 SOC外设的模拟,对外设模拟其实是区分我们模拟器是不是能够用在MCU上的重要指标,模拟器是针对于PC的还是针对于MCU的,很关键的就在于外设的功能,这一块也是我们后面重点会去模拟的一个对象。我们模拟的对象是一个固件,所以我们首先要对固件做一个分析,这里面还是以 SoftDevice的协议栈为例,一个使用SoftDevice作为应用的一个完整部件,它的结构是这样的,会包含两个部分,一部分是我们的应用层的代码固件,然后第二部分是协议栈本身,他们之间会通过一个svc的指令去做一个调用,SoftDEvice其实就是我们协议站实现的一个部分,它是不开源的,所以需要我们去做一个逆向分析。


通过分析,我们要确定我们模拟什么以及模拟到什么程度,首先我们要知道我们模拟什么,这里面的话其实要去知道的是它使用了哪些外设,对于硬件来说的话,特定的外设其实是映射到特定的地址上,根据这个特点的话,我们可以通过数据手册去查找他用了哪些外设,然后做一些统计。单纯知道这些的话还是不够的,那么对于我们每一个外设来讲的话,它的逻辑还是非常复杂的。


图片


对于 IoT协议栈来说,为了实现一些非常高效的一些操作,往往会跟我们的硬件做一些联动和结合。因此的话我们要对一些关键的逻辑去做一个逆向的分析,这里面是对它的一个广播的逻辑,蓝牙的广播做了一个逆向分析以后的结果,在广播的逻辑当中,它使用了三个主要的外设,分别是 RTC、Timer定时器,还有 Radio的一个功能。广播它其实是有一个广播周期的周期,一般会在60毫秒到1秒之间,这个是由RTC模块来维护的。


同时对于单个的一个广播周期内的话,也有它会在三个不同的信道上进行广播,这一部分是由 timer来维护,对于我们radio的话,它主要是做数据的收发处理,当我们有蓝牙数据请求过来的时候,他要做一个response的操作,这里面我们讲到的这三个模块,是通过我们的硬件事件、硬件的中断,还有PPI这三个部分进行一个连接的,PPI是我们 nrf52里面特有的一个外设,它的一个功能是可以实现把我们硬件的事件和我们硬件的动作进行一个连接。


这样的话其实就可以实现一个自动化的操作,实际上在整个的广播的逻辑当中,80%的工作是硬件自动来完成的,从另一个角度来说,也就是说我们80%的逻辑需要我们去做模拟的一个实现。


图片


在对这个部件的分析过程当中,我们也发现了一些反调试的现象,它的基本的逻辑是这样的,当我们在做调试的过程中,在我们断点以后,我们的PC指针它停止了,它的指令流停止了,但是它的硬件外设其实还是在跑,这里面典型的就是一个定时器,定时器在运行的过程中它会产生一个时间差,时间差如果被我们的固件去检测到的话,它会产生一个错误。具体的话其实是两种表现形式,一种的话它会直接读我们的定时器的一个数值做一个比较,第二种的话就更隐蔽,它会设定一个预期的值。


那么在检测点去查看这个有没有一些超时事件。反调式怎么会影响到模拟的实现,是因为我们在模拟的过程中,其实所有的模拟器其实它的模拟的速度其实是不均等的,这样的话就会产生一个时间差,这个时间差的话在一定概率上就是触发这些问题。


那当然我们针对这个也做了一些解决的方法,因为误差是是我们模拟导致的,所以可以通过提高硬件的一个精度,模拟的精度来解决。还有的话我们可以适当的去降低定时器的一个频率,增加时间的一个冗余。


最后,我们也可以去对它的特定的一些逻辑做一些补丁或者修改,实际上在最后的模拟实现过程当中,从结果来看,我们只需要做一处的这种补丁,所以的话最后它整个固件的话还是比较完整的。

图片


这是我们固件分析以后统计的这些外设的一个模拟的情况,实际上最后我们是对13个主要的外设做了模拟,外设功能的覆盖度达到了80%,这个程度已经完全可以支撑我们协议栈固件的运行,这些外设里面其实可以分为两类,一类是我们强依赖的外设。


就是说我们必须要去实现,如果不实现的话,我们的固件可能会卡死或者是报错,或者说进入一些非预期的一些逻辑,这些是我们不希望看到的。


第二个的话就是通信接口,通信接口的话它反映在我们的固件跟外部的设备的交互上,典型的是我们的SPI的接口还有I2C的接口,当然也包括蓝牙接口。


图片


那么这些外设具体是怎么实现?首先外设模拟的本质是对地址读写的一个实例化,我们固件对我们硬件的一个访问往往是通过特定的一些地址读写来操作的,所以的话我们要实现模拟的话,其实是对读写过程进行赋能。


我们在模拟的过程当中,我们对固件的一些读写操作会进行过滤,通过模拟器的一些callback的机制,然后过渡到我们外设的实现当中,我们的外设实现过程当中,除了要对这个地址的读写进行数据的一个反馈,还有保存的话,其实最关键的其实要对他它读写硬件行为做一个模拟,这是我们非常核心的一个部分。


图片


在所有的外设里面,其实我们最关心的还是蓝牙,实现蓝牙的一个模拟的话,其实是实现它的一个组包跟拆包的一个过程,它的组包跟拆包其实发生在我们的硬件层,因此在硬件模拟的时候,我们就可以做一个组包拆包的实现,其实我们模拟的是蓝牙的一个物理层。但是对于蓝牙来讲的话,仅仅这些还是不够的,因为蓝牙它不可能去单独的存在,它一定是两个或两个以上的设备存在的,因为它要建立一个连接的交互,那么这里面的话我们通过一个接口来实现,通过 interface接口来实现。


那么对于这个接口的话,基于接口协议,可以在模拟器的主体外部去做一些脚本的编程,从而我们对蓝牙协议的一个通信。这个结构其实也是有一定的灵活性跟扩展性的。基于这个接口的话,我们除了蓝牙,我们还可以扩展一些其他的外部设备,比如说spi的flash,还有一些按键交互,甚至还有 LCD的一个显示。这是我们模拟以后蓝牙数据的一个体现,它是一个我们自己定义的json的格式是一个非常易读的。


图片


这里面我们一个具体的例子来讲解,那么这是一个真实的固件模拟的案例,那么对于这个固件的目标设备,它其实外面接了两个芯片,一个spi flash用来存储一些数据,还有I2C的控制器用来做一些机械的控制,当然还有蓝牙的通信。我们在做设备模拟的过程中,我们可以基于一些高级的语言去来做编程,一般安全人员喜欢用这种Python的格式,我们可以用Python来实现三个设备的模拟,进而实现一个电路级别的模拟。


那么它模拟的结果是什么样的?这里面我列举了一些它的数据日志,从这一点来看,我们可以看到固件对我们spi flash还有 I2C的数据的一个读写,这里面比较关键的就是我们蓝牙的数据,蓝牙大多数它还是一个 client server的模型,我们这里面也是用一个方向进行了标识。


刚才介绍的就是我们模拟实现的一个过程,分别讲了我们模拟器主体的一个实现,还有我们外部设备的模拟。



漏洞挖掘方法


下面的话第三部分就是讲模拟技术如何应用到漏洞挖掘中?

图片


首先,模拟在蓝牙漏洞挖掘当中其实有两个非常直接的意义,首先说可能给我们建立一个比较好的动态分析的环境,第二个的话就是可以高效率的建立自定义交互数据。


这是我们虚拟环境中的一个概况,这里面包含几个部分,首先是物理设备,物理设备可以认为是我们的被挖掘的真实的设备,或者说我们可以理解为固件,那么模拟器主体的话就是我们 CPU的模拟,还有外设的一个模拟实现,外部设备的一个模拟就是我们刚才讲的基于通信接口来做的,比如说LCD或者flash或者eeproom这些,同时的话针对外部设备的模拟,我们也会增加一些可视化的一个辅助,这样的话更形象的把我们固件所对外表现出来的行为进行一个直观表现。


作为一个安全研究者的话,其实是模拟器的一个使用者,那么我们固件在模拟的过程中,它与外界的所有的交互都会通过 interface接口来体现出来,我们安全的人员可以去接口去做监听或者分析,还有进一步的做修改和反馈,达到测试的目的。


图片


那么具体针对这个接口,我们从蓝牙来讲,这里面主要是有两种表现形式,一种是Guest to Geust,首先Guest的意思就是说是我们的模拟器,其实这是一个中间人模拟的场景,我们需要同时模拟两个固件,分别是固件一还有固件二,同时通过一个中间的脚本对他们所产生的蓝牙数据做一个连接,在这个连接过程当中我们就可以去过滤我们感兴趣的字段,然后去做一些修改,甚至做一些重复的一些操作,这种场景的话就比较适合我们同时对蓝牙的中心设备,还有外围设备去做同步的这种分析。


图片


第二的话是Guest to Host,它是一种点对点的模拟,Host指的就是我们的 PC端,在这里面的话我们只需要模拟单一的一个固件,同时的话基于我们刚才讲的接口协议,我们可以编写一些测试脚本,这里面的话是对BLE蓝牙的connect请求的一个fuzz的一个场景,它其实是对我们连接数据包中的AccessAddr,还有ChannelMap的字段做了一个fuzz的测试。


同时我们的模拟器在对这个漏洞的验证,还有调试的过程中也是支持比较好的。首先我们直接可以基于 shell环境来做漏洞的验证,对于已知的一些CVE的话,我们可以直接在命令行里面跑,即使一些复杂的话,我们其实也可以编写一些简单的脚本来做。


图片


我们对调试的一个支持,还是基于 qemu的 GDB调试。我这里面我们做了一个东西,就是说把程序的断点跟我们的硬件模拟做了一个强绑定。当我们这个断点的时候,我们的硬件状态其实是真正的去暂停了,像我们刚才讲的这种基于时间的这种反调试的话,它就不再起作用,起到了一个去反调试的效果。


我自己的话也是基于这些方法去做了一些研究,然后发现了一些问题,这些这几个漏洞的话都是非接触式的漏洞,因为今天我们主要还是以概括的方法为主,所以对于这一部分就不做详细的介绍。



案例演示


第4部分是做一个案例的演示,我们刚才讲了,其实蓝牙模拟交互有两种方式,这里面也会有两个演示,首先是一个中间人的案例,中间人的话肯定是一个三个角色去存在的,首先这里面我们要有一个蓝牙的中心设备,然后第二个的话是蓝牙的一个周边设备,然后我们通过一个中间脚本把这个数据做一个交互的连接,从而建立两个固件的一个通信,实现一个连接。基于这个的话,我们可以针对特定的去报文去做一个修改和重放。


图片

(此处为视频,点击文末阅读原文前往下载ppt查看)


中间人的这种场景的话,其实如果我们在物理环境中想去实现的话,其实目前来看还是比较困难的。


然后第二个案例:


图片

(此处为视频,点击文末阅读原文前往下载ppt查看)


这个案例的话我们是找了一个具体的漏洞,这里面的话首先我们去运行一个有漏洞的固件,然后我们去运行我们验证脚本。这是一个链路层的漏洞,在模拟器里面是非常容易去验证的,但是在我们物理环境中其实还是有一定困难的。原因就在于我们刚才讲的就是链路层的一个逻辑,很多是固化在我们的工具固件本身的,这样的话我们如果在物理环境中想去做验证的话,很多时候需要去做对做一些SOC的编程和工具固件的修改。



总结、规划


最后的话是对我们今天讲的内容做一个总结。


图片


首先我们今天讲了一种嵌入式平台的这种精确模拟的一种方法,我们今天通过 nrf52还有蓝牙协议栈对我们模拟技术在漏洞的挖掘、验证,还有分析过程当中的实际意义其实做了一些阐述,从结果来看,我觉得还是比较乐观的,模拟技术在实际的安全研究中,能够增加研究的便利性,并为真实环境提供有价值参考。


实际上除了蓝牙协议栈,同样适用于普通的MCU固件和RTOS固件的模拟,也可以应用在RTOS和普通MCU固件的软件上的漏洞挖掘,整体的思想和方法是一致的。都是以模拟为基础和出发点,讲测试数据附加到代码执行过程中,实现一个测试的目的。


实际上关于这部分研究后续仍然有很多工作要做,未来会增加新的硬件平台和IOT协议栈的模拟,不局限于nRF的平台和蓝牙协议栈另一个,因为MCU的类型和架构是比较杂乱的,需要新的MCU架构的模拟,目前已经对STM8这个MCU架构做了全面的支持。基于蓝牙通信的这种框架,可以模拟更多的外部设备,最后实现一个外部设备的集合库。进一步的会使得模拟过程更便利和具有灵活性,这部分开发会独立于模拟器本身,作为一个扩展。


模拟技术在IOT的批量化的漏洞分析、验证、自动化漏洞挖掘中是有优势的,为了发挥模拟技术最大的优越性,后续会考虑增加一些漏洞检测的工具进来,去覆盖一个漏洞的管理周期。同时的话我们会对它的外部设备做一个扩展的集合,那么模拟技术其实在我们自动化跟批量化上其实也是非常有优势的,后面的话我们可能会考虑结合沟通的检测工具进行。


图片


最后对目前我们团队的项目做一个介绍,目前我们团队在做一个IoT-Matrix的项目,这张图是它的一个技术路线。首先这个项目是针对IOT设备的漏洞验证和挖掘的应用场景,目标是实现对一切IOT设备固件的模拟,包括基于linux-base的模拟,和硬件设备的全模拟。


IoT碎片化是比较严重的,为了解决这个问题,我们也划分了很多分支路线,今天分享的内容其实是IoT-matrix中的MCU的模拟一个案例。实际上去实现模拟一切的目标其实还是非常困难的,还有很多东西要做,对这些东西感兴趣的话也可以跟我们去做一个交流和沟通。


声明:该文观点仅代表作者本人,转载请注明来自看雪