Android蓝牙组件缝隙连连看

颁布功夫 2018-08-15

1、概述

 

        Android系统中,蓝牙组件能够说是安全缝隙沉灾区,2017年ArmisSecurity安全团队颁布BlueBorne组合缝隙攻击链能够通过蓝牙对智能手机进行远程攻击,风险性极大。今年三月份的Android安全布告中,系统层缝隙全数都是蓝牙组件缝隙,总共10个。缝隙多散布在SDP(服务发现和谈)和BNEP(蓝牙网络封装和谈)中,并且缝隙类型多是内存越界读写。四月份的安全布告中,总共有7个蓝牙组件缝隙,多散布在AVRCP(音频/视频远程节造配置文件)和谈中。六月份和七月份Android 安全布告中依然披露了多个蓝牙组件缝隙,涉及蓝牙和谈栈中多个和谈,涉及的源码版本为6.0、 6.0.1、 7.0、 7.1.1、7.1.2、 8.0、 8.1,覆盖领域较广。

 

        本文将介绍蓝牙和谈栈中的L2CAP和谈和SMP和谈,并对CVE-2018-9359和CVE-2018-9365这两个缝隙案例进行具体分析。

 

2、和谈简介

 

2.1 L2CAP

 

        L2CAP(Logical Link Control and Adaptation Protocol)称为逻辑链路和适配和谈,是蓝牙系统中的主题和谈,位于数据链路层。L2CAP通过和谈多分复用、分段和沉组,向高层提供面向衔接和无衔接的数据服务。

 

宝运莱·(中国区)最新官方网站

 

2.1.1 L2CAP数据包体式

 

        L2CAP是基于分组的,但也遵循信路传输的通讯模型。L2CAP支持的信路有两种:面向衔接的信路和面向无衔接的信路。在面向衔接的信路中,L2CAP数据包的体式如下图所示。

 

宝运莱·(中国区)最新官方网站

 

       数据包中每个字段的注明如下所示:

 

宝运莱·(中国区)最新官方网站

 

2.1.2 L2CAP信令

 

       

两台蓝牙设备通过L2CAP和谈通讯时,所有的信令都被发送到CID为0x0001的信路中。L2CAP信令的体式如下所示。

 

宝运莱·(中国区)最新官方网站

      

  L2CAP信令中每个字段的注明如下所示:

 

宝运莱·(中国区)最新官方网站

      

  L2CAP和谈共有12种信令类型,各信令的作用如下表所示。

 

宝运莱·(中国区)最新官方网站

       

另表,多个信令能够在统一个帧中发送,如下图所示。

 

宝运莱·(中国区)最新官方网站

 

2.2 SMP

 

        SMP(Security Manage Protocol)是蓝牙和谈栈中的安全治理和谈,掌管蓝牙设备之间的配对和密钥分配。

       

SMP号令体式如下图所示。

 

宝运莱·(中国区)最新官方网站

      

  其中,Code字段为一个8bit,标识号令的类型。SMP号令的类型如下表所示。Data字段在长度上是可变的, Code字段决定Data字段的体式。

 

宝运莱·(中国区)最新官方网站

 

3、缝隙道理分析

 

3.1 CVE-2018-9359

 

(以下分析基于android-8.0.0_r4版本原码)

 

        CVE-2018-9359缝隙位于L2CAP和谈� ?�,缝隙类型是越界读� D芄煌ü雀韫俜讲几婵吹椒煜恫苟�。缝隙补丁代码位于/stack/l2cap/l2c_main.cc文件中的process_l2cap_cmd函数中,该函数重要职能是处置接管的L2CAP和谈的信令包。

 

宝运莱·(中国区)最新官方网站

       

 从代码291行起头,while循环解析L2CAP数据包中所有的COMMAND号令。首先看一下两个宏界说:STREAM_TO_UINT8从p指向的数据包中读取1个字节,p指针加1;STREAM_TO_UINT16每次从p指向的数据包中读取2个字节,p指针加2。

 

宝运莱·(中国区)最新官方网站

       

法式挪用宏顺次从p指向的数据包中读取cmd_code、id和cmd_len字段,此时p应该指向data数据域的开头。

       

 当Code=0x1,代表Command reject数据包,数据包界说如下所示。当Length不为0,data数据域中蕴含两个字段:Reason字段(2字节)和Data字段。

宝运莱·(中国区)最新官方网站

        处置Command reject数据包的分支代码如下:

 

宝运莱·(中国区)最新官方网站

      

  从代码能够看出,法式没有判断该号令包是否存在data数据域,在334行中直接使用宏读取2个字节的rej_reason。因而在内存堆中产生越界读缝隙。

 

        这里也只是产生了内存越界读取,没有将读取的数据泄露到客户端中。下面找到发送返回包的代码,查看若何产生内存泄漏。

 

宝运莱·(中国区)最新官方网站

        从378行代码起头是解析L2CAP_CMD_CONN_REQ号令分支,379行代码,先越界读取两个字节的con_info.psm,380行代码越界读取两个字节的rcid。381行挪用l2cu_find_rcb_by_psm函数通过con_info.psm去遍历寻找注册节造块地址。这里单一介绍一下PSM这个概想。

 

        PSM全称为Protocol/ServiceMultiplexer,PSM的长度至少是2字节,它的值该当是奇数,就是最低的byte的最低位必须为1。另表,PSM的最高byte的最低位该当为0。它能够比2字节长,PSM由两个领域段组成,第一个领域段是SIG用来暗示对应protocol的,第二个领域段是动态申请的和SDP结合使用。这个值用来支持特定protocol的分歧实现。所以,在申请PSM的时辰都是从0x1001起头申请的。原因就是0x0001~0x0eff都是被SIG保留的。那么这些保留的值都各自对应了哪些protocol呢 ?具体见下图。

 

宝运莱·(中国区)最新官方网站

宝运莱·(中国区)最新官方网站

       

 代码382行判断p_rcb是否为NULL,若是为空就挪用l2cu_reject_connection函数,具体看一下该函数代码。

 

宝运莱·(中国区)最新官方网站

       

从代码520行到523行,通过宏UINT6_TO_STREAM将数据写入p指向的内存中。

 

宝运莱·(中国区)最新官方网站

       

 其中remote_cid就是之前越界读取的两个字节数据。机关好响应数据包后,代码525行挪用l2c_link_check_send_pkts将响应包发送到客户端。

       

在六月份android安全布告中,CVE-2018-9359、CVE-2018-9360、CVE-2018-9361三个缝隙的补丁是一样的。部门补丁代码如下。

 

宝运莱·(中国区)最新官方网站

      

  能够看出,补丁中增长了长度判断。若是p+2>p_next_cmd不为真,注明存在data数据域,而后才起头读取字节。

 

3.2 CVE-2018-9365

 

(以下分析基于android-8.0.0_r4版本原码)

 

CVE-2018-9365是SMP(security manager protocol)和谈中一个数组越界缝隙。该缝隙呈此刻smp_sm_event函数中,代码蹊径为:\smp\smp_main.cc。谷歌官方补丁代码如下。

 

宝运莱·(中国区)最新官方网站

      

  从补丁中能够看到,这里判断了p_cb->role是否大于1,若是大于1报错返回,补丁代码下一行就是以p_cb->role为下标在smp_entry_table数组中查找。Smp_entry_table数组界说如下。

 

宝运莱·(中国区)最新官方网站

       

能够看到,smp_entry_table数组中只有两项,一个是针对主设备,一个是针对从设备。当罕见据包通过L2CAP在SMP信路中接管到时,会挪用smp_data_received函数进行处置。Smp_data_received函数代码如下。

 

宝运莱·(中国区)最新官方网站

       

 代码146行定位到内存中SMP数据包地位。代码150行通过STREAM_TO_UINT8宏取出cmd。

 

宝运莱·(中国区)最新官方网站

        

第160行代码判断cmd的类型是否为配对要求指令或者安全要求指令。若是是,第164行起头对p_cb->role进行复造。通过名称判断,L2CA_GetBleConnRole函数应该是通过蓝牙地址获取蓝牙设备的角色信息。对于蓝牙设备来说,只有两种角色,一是主设备角色,二是从设备角色。L2CA_GetBleConnRole函数代码如下。

 

宝运莱·(中国区)最新官方网站

     第201行界说了role,同时给role赋值为HCI_ROLE_UNKNOWN。宏界说如下所示。

 

宝运莱·(中国区)最新官方网站

 

        Role先被复造为0xff,代码205行是通过蓝牙地址遍历寻找p_lcb,若是p_lcb为空,则直接返回HCI_ROLE_UNKNOWN。P_cb->role被赋值为0xff后,后续代码直接挪用了smp_sm_event函数。代码如下所示。

 

宝运莱·(中国区)最新官方网站

        挪用smp_sm_event函数,补丁前的代码在957行由于没有判断p_cb->role的大幼,导致数组越界接见。

 

宝运莱·(中国区)最新官方网站

 

4、总结

 

        通过对多个蓝牙缝隙的分析,发现Android蓝牙组件中的缝隙多是较为低级的代码bug导致的,并且缝隙多呈此刻对数据包的解析代码逻辑中。针对披露的这么多蓝牙缝隙,安卓手机用户还需实时更新官方推送的补丁,将安全隐患降低到最低。

 

5、有关链接

 

[1] https://android.googlesource.com/platform/system/bt/+/b66fc16410ff96e9119f8eb282e67960e79075c8%5E%21/#F0

[2] https://android.googlesource.com/platform/system/bt/+/ae94a4c333417a1829030c4d87a58ab7f1401308%5E%21/#F0

[3] https://blog.quarkslab.com/a-story-about-three-bluetooth-vulnerabilities-in-android.html