草庐IT

Android蓝牙协议栈漏洞剖析

OPPO安珀实验室 2023-03-28 原文

1.背景介绍

蓝牙协议相对于其他通信协议如WIFI(802.11)、传统TCP/IP议协等来说,更为复杂,目前蓝牙核心规范(5.3)高达3085页。蓝牙的这种复杂性使得对蓝牙的各个协议的实现进行安全测试与审计变得相对困难,从而导致协议的实现和使用容易出现较多的安全漏洞。但是从另一方面来说,它的复杂性也会要求研究员或攻击者进行漏洞挖掘的技术门槛变得相对更高,需要突破的难点也会更多。

图1 蓝牙核心规范说明书封面

图2 蓝牙协议栈架构

如图2所示,蓝牙协议栈主要分为两个部分:Host和Controller。Host主要包含链路层之上的整个蓝牙协议栈,包含传输层L2CAP以及在它之上的多种应用层协议,是蓝牙协议栈的核心部分。Controller主要与硬件驱动打交道,偏底层。本文主要关注的是Host层各协议的实现安全。

从Android系统发展历史上来看,其蓝牙协议栈也一直是安全研究的重点目标。2017年Armis安全团队公布BlueBorne组合漏洞攻击链可以通过蓝牙对智能手机进行远程攻击,危害性极大。2020年Android爆出BlueFrag漏洞,攻击者可以通过该漏洞实现远程零交互的远程代码执行。

OPPO安珀实验室一直致力于参与维护整个Android系统生态安全,因此也对Android蓝牙协议栈展开了深入的研究。至今我们已向Google Android安全团队提报了多个蓝牙协议栈实现安全漏洞,这次将依次介绍我们团队发现的三个不同Android蓝牙协议模块漏洞:CVE-2020-27024(SMP协议)、CVE-2021-0918(GATT协议)、CVE-2021-39805(L2CAP协议)。

2.CVE-2020-27024

2.1 SMP协议简介

SMP(Security Manage Protocol)安全管理协议定义了配对和密钥分发的过程实现,然后使用密钥对链路通信数据进行加密。SMP被用在LE设备或蓝牙双模设备中。如图3所示,SMP协议工作流程大致分为几个阶段:

Step1:特征交换

配对特征交换,即交换各自都支持哪些配对特性,比如支不支持Secure Connection(安全连接),支不支持MITM,支不支持OOB(Out of Band:带外),以及它的输入输出能力(IO capabilities)等。

Step2:密钥产生

该阶段双方将协商生成产生STK/LTK:

LE Legacy pairing:产生Short Term Key(短期密钥)。

LE Secure Connection:产生Long Term Key(长期密钥)。

Step3:密钥分发

该阶段分发一些其他用途的Key,像Identity Resolving Key(IRK),这个Key是用于Random Address解析。当分发这些Key时,此阶段链路是必须要加密的,若不加密,将导致密钥直接泄漏。加密使用的密钥是用第二阶段产生的STK或LTK,或者双模下直接共享使用BR/EDR配对产生的Key。

Step4:链路加密

通过使用STK/LTK密钥对整个蓝牙通信链路进行加密。

SMP协议整个配对流程如下图所示,其中配对发起方角色为主设备类型(MASTER),接收方为角色为从设备类型(SLAVE)。

图3 SMP协议工作流程

2.2  漏洞剖析

CVE-2020-27024是SMP协议中一个数组越界漏洞。SMP协议使用预定义的L2CAP_SMP_CID(0x06)、L2CAP_SMP_BR_CID(0x07)通道,位于L2CAP协议层之上。如图4所示,SMP协议栈smp_l2cap_if_init()函数负责注册SMP数据报文接收回调处理函数,分别为处理BLE蓝牙SMP报文的smp_data_received()函数,以及处理BR蓝牙SMP报文的smp_br_data_received()函数。

图4 Android蓝牙协议栈SMP协议的初始化代码段

由BR蓝牙通信链接传入的SMP数据包将交由smp_br_data_received()函数[ 代码位于/system/bt/stack/smp/smp_l2c.cc]处理。当SMP协议栈接收到对端发起的配对请求SMP数据包SMP_OPCODE_PAIRING_REQ(0x01)时,报文处理流程则将到达以下图5的代码段。

图5 smp_br_data_received()函数代码段

当smp_br_data_received()函数处理完成后,它调用smp_br_state_machine_event()函数 [代码位于/system/bt/stack/smp/smp_br_main.cc ],该函数代码实现如图6所示。

图6 smp_br_state_machine_event()函数代码段

首先我们可从图7中看到全局变量smp_br_entry_table数组的SIZE其实为2。

图7 smp_br_entry_table数组定义

从图6中的代码段我们可以看到由于smp_br_state_machine_event()函数在一开始执行tSMP_BR_ENTRY_TBL entry_table = smp_br_entry_table[p_cb->role]语句时并未对p_cb->role的最大值进行合法性判断,反而是取值后再判断p_cb->role的合法性。当攻击者恶意造成p_cb->role出现取值大于2的情况时,将导致smp_br_state_machine_event()函数entry_table赋值语句出现内存OOB越界读的异常。

3.CVE-2021-0918

3.1 GATT协议简介

GATT是 Generic Attributes的缩写,中文是通用属性,它是低功耗蓝牙BLE设备之间进行通信的协议。GATT定义了一种多层的数据结构,已连接的低功耗蓝牙设备用它来进行通信,其定义的多层数据结构简要概括起来就是服务(service)可以包含多个特征(characteristic),每个特征包含属性(properties)和值(value),还可以包含多个描述(descriptor)。

GATT基于ATT协议(属性协议)来承载的,属性协议主要用来发现、读写、通知和指示属性。

图8 GATT协议交互图

在ATT层协议框架内,拥有一组属性的设备称为服务端(Server),读写该属性值的设备称为客户端(Client),Server和Client通过ATT PDU进行交互;

其中Attribute Protocol PDU报文格式如图9所示。其中Opcode:操作码(消息类型,1字节大小); Attribute Parameters:ATT参数(变长); Authentication Signature:身份验证签名。

图9 Attribute Protocol PDU报文格式

ATT消息各种类型多达30多种,其中常见的消息类型包含表1中的6种类型,如下表所示。后续介绍的Android蓝牙协议栈GATT漏洞也就是存于Notification消息类型处理函数代码当中的。

表1 Attribute Protocol PDU的类型表

PDU类型

发送方

描述信息

请求/Request

Client

客户端向服务器请求数据

回复/Response

Server

服务器对上面请求的回复

命令/Command

Client

客户端向服务器发送命令-无回复

通知/Notification

Server

服务器对特征数值向客户端发起通知-无回复

指示/Indication

Server

服务器对特征数值指示发送给客户端

确认/Confirmation

Client

客户端对指示的应答

3.2  漏洞剖析

CVE-2021-0918是Android系统GATT蓝牙协议栈处理Notification类型报文时存在的一个内存OOB越界读写安全漏洞。

蓝牙协议GATT报文数据核心处理函数位于gatt_data_process()函数[system\bt\stack\gatt\gatt_main.cc]。如图10所示,该函数通过op_code值类型判断,决定该报文是来自client端还是server端,然后分别调用不同的函数处理接口gatt_server_handle_client_req及gatt_client_handle_server_rsp函数。

图10 gatt_data_process()代码段

通过分析该代码我们发现可以通过精心构造opcode值(如GATT_HANDLE_VALUE_IND:0x1D、GATT_HANDLE_VALUE_NOTIF:0x1B、GATT_HANDLE_MULTI_VALUE_NOTIF:0x23)来控制函数执行调用到gatt_client_handle_server_rsp()函数。其中GATT_HANDLE_MULTI_VALUE_NOTIF类型是后续触发漏洞的报文类型。

图11 gatt_client_handle_server_rsp()代码段

最后gatt_client_handle_server_rsp()将调用到gatt_process_notification()函数。该漏洞问题代码是就位于system/bt/stack/gatt/gatt_cl.cc文件内的gatt_process_notification()函数,该函数是负责对接收到的gatt协议notification类型通知报文进行解析处理。

图12 gatt_process_notification()代码段

首先介绍下Android蓝牙协议栈里常用的解析报文内容的宏定义:STREAM_TO_INT8(u8, p)从p指向的报文中读取1个字节,保存到u8类型变量当中,p指针加1;STREAM_TO_UINT16(u16, p)每次从p指向报文中读取2个字节,保存到u16类型变量当中,p指针加2。STREAM_TO_ARRAY(a, p, len)负责从p指向的报文内容读取len字节长度的数据,保存到数组变量a空间中,p指针加len长度。另外tGATT_VALUE value变量类型的结构体构造如图13所示。

图13 tGATT_VALUE结构体

我们可以看到gatt_process_notification()函数内当op_code值为GATT_HANDLE_MULTI_VALUE_NOTIF类型时,value.len变量值是可以通过报文内长度字段来控制的,此时如果value.len长度大于实际数据长度len时且小于GATT_MAX_ATTR_LEN(固定值为600),后续STREAM_TO_ARRAY(value.value, p, value.len)这行代码将导致一个OOB越界读的异常内存拷贝操作。如图14所示,后续gatt_process_notification函数在循环解析报文内的多个notification消息时,由于未对解析出的value.len的长度做最大长度(不能超过GATT_MAX_ATTR_LEN)合法性校验,将导致STREAM_TO_ARRAY(value.value, p, value.len)出现内存OOB越界写的风险。

图14 gatt_process_notification()后续代码段

4  CVE-2021-39805

4.1 L2CAP协议简介

L2CAP(Logical Link Control and Adaptation Protocol)称为逻辑链路和适配协议,是蓝牙系统中的核心协议。L2CAP通过协议多分复用、分段和重组,向高层提供面向连接和无连接的数据服务。

图15 L2CAP协议交互图

L2CAP基于信道的概念,信道的每一个端点被称为信道标识符(CID),同设备间CID可复用,但本地设备CID不可复用。 L2CAP是基于分组的,但也遵循信道传输的通信模型。对端设备上两个L2CAP实体间传递的信号命令(Signaling Commands)这些信号命令通过Signaling Channel来传输,对于ACL-U逻辑链路应该使用CID 0x0001, 而对于LE-U则应该使用CID 0x0005。如L2CAP LE Signalling Channel信令通道,用于控制LE面向连接的数据信道,并可对这些LE信道的特性变化进行协商(LE-U),后续介绍的漏洞就位于L2CAP LE Signalling Channel通道信令的处理代码中。蓝牙规范定义的CID如图16所示。

图16 BLE信道CID

L2CAP数据包的格式如下图所示。

图17 L2CAP数据包的格式

L2CAP信令报文格式如下所示。

图18 L2CAP信令报文格式

4.2  漏洞剖析

CVE-2021-39805是L2CAP协议中一个数组越界读漏洞。问题代码位于l2cap蓝牙协议栈system\bt\stack\l2cap\l2c_ble.cc文件中的l2cble_process_sig_cmd函数。该函数主要负责解析处理LE的信令通道控制报文。

图19 l2cble_process_sig_cmd()代码段

当L2CAP层处理基于信用的增强型流控模式的重新配置的回复(L2CAP_CMD_CREDIT_BASED_RECONFIG_RES,0x1A)报文时,其未进行包长度判断,导致内存信息泄露。顾名思义,这个回复就是响应重新配置的请求(request)报文,这个(request)请求是为了重新配置该通道的MTU和MPS的,其结构如图18。图19就是响应的回复报文。

图20基于信用的增强型流控模式的重新配置请求

图21基于信用的增强型流控模式的重新配置回复

Android在2020年8月左右添加了对基于信用的增强型流控模式的支持,此漏洞代码就从那时起一直存在,如图22所示。这段代码段中,STREAM_TO_UINT16从回复报文去取result字段的值,但是取之前未判断此时回复的报文是否已经没有多余的数据了。因此,若精心构造一个该回复数据包,那么就会触发到这个地方导致OOB Read。且这个被赋值的result字段后续会返回给发送方,导致内存信息泄露。

图22 l2cble_process_sig_cmd()后续代码段

5.总结与展望

Android系统中蓝牙协议栈演进分为几个阶段,最早android使用是Linux蓝牙协议栈BlueZ。从Android 4.2开始,Google便在Android源码中推出了它和博通公司一起开发的BlueDroid以替代BlueZ。当前Android使用的蓝牙协议栈版本名为Fluoride,而Google正在开发的下一代蓝牙协议栈叫做Gabeldorsh,并使用Rust编程语言进行开发。 目前Fluoride蓝牙协议栈基本上还是使用C/C++语言来实现的,由于蓝牙报文的协议解析处理涉及大量的内存操作,加上蓝牙协议的多样性和复杂性,以及历史上多家公司代码融合等各类原因,导致安卓蓝牙协议栈爆出过很多严重RCE漏洞。而Gabeldorsh可以利用Rust语言本身的特性减少内存型漏洞的产生。这就导致今后对蓝牙协议栈的漏洞挖掘更会集中于逻辑性漏洞,如协议本身的逻辑问题、条件竞争、设计缺陷等方面,这就更加要求该领域的漏洞挖掘研究员具有更加深厚的蓝牙技术知识栈,漏洞挖掘的技术门槛也会更高、需要突破的难点也会更多。

6.参考链接

《Bluetooth核心规范》:https://www.bluetooth.com/specifications/specs/core-specification-5-3/

《Pixel 更新公告 - 2020 年 12 月》:https://source.android.com/security/bulletin/pixel/2020-12-01?hl=zh-cn

《Android 安全公告 - 2021 年 11 月》:https://source.android.com/security/bulletin/2021-11-01

《Android 安全公告 - 2022 年 4 月》:https://source.android.com/security/bulletin/2022-04-01

有关Android蓝牙协议栈漏洞剖析的更多相关文章

  1. Tomcat AJP 文件包含漏洞(CVE-2020-1938) - 2

    目录1.漏洞简介2、AJP13协议介绍Tomcat主要有两大功能:3.Tomcat远程文件包含漏洞分析4.漏洞复现 5、漏洞分析6.RCE实现的原理1.漏洞简介2020年2月20日,公开CNVD的漏洞公告中发现ApacheTomcat文件包含漏洞(CVE-2020-1938)。ApacheTomcat是Apache开源组织开发的用于处理HTTP服务的项目。ApacheTomcat服务器中被发现存在文件包含漏洞,攻击者可利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件。该漏洞是一个单独的文件包含漏洞,依赖于Tomcat的AJP(定向包协议)。AJP自身存在一定缺陷,导致存在可控

  2. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. ruby - HTTP POST 上的 SSL 错误(未知协议(protocol)) - 2

    尝试通过SSL连接到ImgurAPI时出现错误。这是代码和错误:API_URI=URI.parse('https://api.imgur.com')API_PUBLIC_KEY='Client-ID--'ENDPOINTS={:image=>'/3/image',:gallery=>'/3/gallery'}#Public:Uploadanimage##args-Theimagepathfortheimagetoupload#defupload(image_path)http=Net::HTTP.new(API_URI.host)http.use_ssl=truehttp.verify

  5. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

  6. 什么是0day漏洞?如何预防0day攻击? - 2

    什么是0day漏洞?0day漏洞,是指已经被发现,但是还未被公开,同时官方还没有相关补丁的漏洞;通俗的讲,就是除了黑客,没人知道他的存在,其往往具有很大的突发性、破坏性、致命性。0day漏洞之所以称为0day,正是因为其补丁永远晚于攻击。所以攻击者利用0day漏洞攻击的成功率极高,往往可以达到目的并全身而退,而防守方却一无所知,只有在漏洞公布之后,才后知后觉,却为时已晚。“后知后觉、反应迟钝”就是当前安全防护面对0day攻击的真实写照!为了方便大家理解,中科三方为大家梳理当前安全防护模式下,一个漏洞从发现到解决的三个时间节点:T0:此时漏洞即0day漏洞,是已经被发现,还未被公开,官方还没有相

  7. 网络实验之RIPV2协议(一) - 2

    一、RIPV2协议简介  RIP(RoutingInformationProtocol)路由协议是一种相对古老,在小型以及同介质网络中得到了广泛应用的一种路由协议。RIP采用距离向量算法,是一种距离向量协议。RIP-1是有类别路由协议(ClassfulRoutingProtocol),它只支持以广播方式发布协议报文。RIP-1的协议报文无法携带掩码信息,它只能识别A、B、C类这样的自然网段的路由,因此RIP-1不支持非连续子网(DiscontiguousSubnet)。RIP-2是一种无类别路由协议(ClasslessRoutingProtocol),支持路由标记,在路由策略中可根据路由标记对

  8. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  9. Android 10.0 设置默认launcher后安装另外launcher后默认Launcher失效的功能修复 - 2

    1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La

  10. AiBote 2022 新研发的自动化框架,支持 Android 和 Windows 系统。速度非常快 - 2

    Ai-Bot基于流行的Node.js和JavaScript语言的一款新自动化框架,支持Windows和Android自动化。1、Windowsxpath元素定位算法支持支持Windows应用、.NET、WPF、Qt、Java和Electron客户端程序和ie、edgechrome浏览器2、Android支持原生APP和H5界面,元素定位速度是appium十倍,无线远程自动化操作多台安卓设备3、基于opencv图色算法,支持找图和多点找色,1080*2340全分辨率找图50MS以内4、内置免费OCR人工智能技术,无限制获取图片文字和找字功能。5、框架协议开源,除官方node.jsSDK外,用户可

随机推荐