基于802.11Fuzz技术的研究
转自安全客
关于无线的Fuzz最开始接触了解时,国内基本毛线都搜不到。经过几个月的资料搜集和学习,将大约全网的fuzz资料整理翻译分析并读懂写下,就为填补国内空白,也希望无线爱好者能多多交流。
在各个安全领域的漏洞挖掘方法中,Fuzz都挺流行的. Fuzz是一种黑盒软件测试技术,这基本上是使用畸形或半自动化的方式在一个畸形的数据注入发现执行错误,运用在协议也比较多。当源代码是不可用的时候,还是不错的,在802.11协议方面,Fuzzing的层面也比较多,特别是针对驱动和接入点的。
802.11的 State machine ,802.11标准规定的State machine
这里有‘State1 ,State2,State3’这三个状态。它这写的比较模糊,不太容易懂,翻译过来有点懵逼。其实这三个State的本意该是:
State1:是用于访问点的客户端设备的初始状态。
State2:是通过对访问点进行身份验证的身份验证状态。
State3:是一个授权发送接受数据通信帧并通过无线接入点和有线网络的关联的状态转换过程,然后反馈802.11Frames.
上面都提到了,802.11标准规定状态机必须在固件或者驱动中实现,许多的驱动管理的状态为了保证它的运行,都采用例如一个AP接受了Assoc请求后,只包括一个网络配置名称,这三个状态是很重要的,Fuzz的思路就是从这三个State机制中来。
802.11还定义了三种帧类型(就是上面那Class):
Class1 Frames:允许从State1、2和3探测请求/响应,beacon,身份验证请求/响应/解除认证
Class2 Frames:只有经过身份验证,可以从State2和3(重新)Assoc请求/响应/解除关联
Class3 Frames:只有在Assoc请求下,可以能在State3内解除认证
每个State都可以进行fuzzing,但是第一个肯定是比后两个容易,因为后面两个都提到了需要成功认证的协议。
(两个图,第一个详细点,那个能看懂就看那个就行了)
一、Access Points Fuzzing 802.11 的介绍:
1、Fuzzing原理
无线协议里面,Beacon是802.11里面的一个重要组成部分,它涵盖了几乎所有AP的重要配置信息。
下面举个ApFuzzing框架的例子,就是通过构建畸形数据包,并将针对Wi-Fi 设备,然后发现已知和未知的漏洞。
Fuzzing802.11接入点,类似于802.11 client的fuzzing。无线客户端功能由接入点解析
802.11个访问点栈将解析大量的802.11的数据包:
*Probe request
*Authentication requests
*Association requests
*Crypted and unencrypted data frames
*Control frames
还有一些其他协议接入点可以fuzzing:
WPA/WPA2 handshakes
基于EAP的认证
基于State的Fuzzing
State1进行成功的身份验证请求
State2 进行成功的关联请求
State3是基于认证成功的密钥交换
2.Fuzzing 举例
Scapy是一个开放源代码的网络编程语言,它是基于Python,可以重放数据,捕获分析,产生随机数据包。可以根据自己的测试需求去改变,好像好多东西都需要它的支持,用处挺大的。有人基于Scapy写了一个叫做wifuzz的工具,写的接入点挺全的,能够fuzz出一些堆栈错误或者Crash,支持的接入点:
我选了个auth 模式的FUZZ,它会将FUZZ出来的的数据保存到一个路径下供我们查看。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$ sudo python wifuzz.py -s fuzztest auth Thur Sep 26 21:41:36 2016 {MAIN} Target SSID: fuzztest; Interface: wlan0; Ping timeout: 60;PCAP directory: /dev/shm; Test mode? False; Fuzzer(s): auth; Thur Sep 26 21:41:36 2016 {WIFI} Waiting for a beacon from SSID=[fuzztest] Thur Sep 26 21:41:36 2016 {WIFI} Beacon from SSID=[fuzztest] found (MAC=[11:22:33:44:55:66]) Thur Sep 26 21:41:36 2016 {WIFI} Starting fuzz 'auth' Thur Sep 26 21:41:36 2016 {WIFI} [R00001] Sending packets 1-100 Thur Sep 26 21:41:50 2016 {WIFI} [R00001] Checking if the AP is still up... Thur Sep 26 21:41:50 2016 {WIFI} Waiting for a beacon from SSID=[fuzztest] Thur Sep 26 21:41:50 2016 {WIFI} Beacon from SSID=[fuzztest] found (MAC=[11:22:33:44:55:66]) Thur Sep 26 21:41:50 2016 {WIFI} [R00002] Sending packets 101-200 Thur Sep 26 21:42:04 2016 {WIFI} [R00002] Checking if the AP is still up... Thur Sep 26 21:42:04 2016 {WIFI} Waiting for a beacon from SSID=[fuzztest] Thur Sep 26 21:42:04 2016 {WIFI} Beacon from SSID=[fuzztest] found (MAC=[11:22:33:44:55:66]) Thur Sep 26 21:42:04 2016 {WIFI} [R00003] Sending packets 201-300 Thur Sep 26 21:42:18 2016 {WIFI} [R00003] Checking if the AP is still up... Thur Sep 26 21:42:18 2016 {WIFI} Waiting for a beacon from SSID=[fuzztest] Thur Sep 26 21:42:19 2016 {WIFI} Beacon from SSID=[fuzztest] found (MAC=[11:22:33:44:55:66]) Thur Sep 26 21:42:19 2016 {WIFI} [R00004] Sending packets 301-400 Thur Sep 26 21:42:42 2016 {WIFI} [R00004] recv() timeout exceeded! (packet #325) Thur Sep 26 21:42:42 2016 {WIFI} [R00004] Checking if the AP is still up... Thur Sep 26 21:42:42 2016 {WIFI} Waiting for a beacon from SSID=[fuzztest] Thur Sep 26 10:40:42 2016 {WIFI} [!] The AP does not respond anymore. Latest test-case has been written to '/dev/shm/wifuzz-69erb.pcap' |
再来个Beacon的内容配置:
在Metasploit中呢,有一个专门用于fuzz Beacon的模块,不过要自己安装Lorcon2这个无线注入模块。https://github.com/gitpan/Net-Lorcon2 安装后要配置好环境变量,这时候容易出错,细心点就行了。
因为是 Beacon这个接入点的FUZZ,那么它会产生无规则信息。
这就是个简单的举例,大家读懂了协议,Fuzzer都可以自己来。
二、基于802.11 Driver 的Fuzzing
关于802.11协议标准的深入解析
(1)802.11扩展有点复杂的...
几种帧类型(管理,数据,控制)大量的信令
速率,信道,网络名称,密码
所有这些东西都必须由固件/驱动程序解析
单独的针对驱动进行闭源驱动、逆向,开源驱动,黑白审计什么的,会很难....也很费劲,所以,Fuzz是一种很不错的选择
(2)Madwifi:是个Linux下的无线驱动,例如Atheros芯片驱动(没搞过无线的应该不知道不同芯片之间有啥区别,google一下就行了)
(3)802.11芯片提供了几种模式的操作用处:
监听802.11层
作为AP接入点
作为一个Ad-Hoc网络
作为一个Station
(4)802.11一共有两个扫描技术(主动与被动)
主动扫描:发送探测请求,并监听探测响应
被动扫描:监听Beacon和信道跳跃
(驱动可以监听Beacon和探测的响应数据。)
(5)802.11的扫描技术(主动与被动)
主动扫描:发送探测请求,并监听探测响应
被动扫描:监听Beacon和信道跳跃
驱动可以监听Beacon和探测的响应数据
1、Fuzzing原理及Fuzzer
关于information elements
信息元素是management frames.中的必要字段,信息元素是由类型、长度和值组成的。
信息元素由一个8位的类型字段,一个8位的长度字段,和多达255个字节的数据。 这种类型的结构是非常类似于在许多不同的协议中使用的普通类型-长度-值(TLV)形式。 信标和探测响应分组必须包含一个SSID 信息元素,对于大多数无线客户端处理数据包。一个支持信息元素值和信道信息元素。
拿这个老外的例子来说吧:
类型的元素为(1byte)
长度是Payload总长度的值(1byte)
Payload的信息元素值为(0-255byte)
有一些信息值是有固定长度的,如果不正确可能缓冲区溢出,如果在802.11内长度高于buffer的大小,则可能出现溢出。
例如。SSID属性,0为它的最小值,最大为32byte
用个循环来表示:
1
2
|
For SSID, test fuzz ssid {0, 1, MIN-1, MIN, MIN+1, MAX-1, MAX, MAX+1, 254, 255} length |
长度值可能是有用的,以触发缓冲区溢出,如果不仔细检查的执行过程中的分析过程中的 802.11帧。这些信息大部分元素最小、固定或极大值可以不同于字节边界(0-255byte)。
发送帧只有Beacon Frames的信息不一定是802.11中制定的元素,这个是为了测试Driver是否能在Beacon中解析有用无用的信息。
SSID的information elements Random
frame = Dot11( proto=0,FCfield=0,ID=0,addr1=DST,addr2=BSSID,
addr3=BSSID,SC=0,addr4=None)
/Dot11Beacon(beacon_interval=100,cap="ESS")
/Dot11Elt(ID=0)
sendp(fuzz(frame), loop=1)
老外的这一个框架,什么都明白了就。
必须要知道解析器通常检查哪些信息元素,了解底层协议那是肯定的.例如WPA的information elements
WPA IE (1 byte)
WPA OUI (3 bytes)
WPA TYPE (1 byte) + WPA VERSION (2 bytes)
WPA multicast cipher (4 bytes)
Number of unicast ciphers (2 bytes: m value)
WPA list of unicast ciphers (4*m bytes)
Number of authentication suites (2 bytes: n value)
WPA list of authentication suites (4 * n bytes)
当Fuzzer开始执行的时候,你可以用不同的“m”和“n”值来检查溢出•截断这些帧并且填充一些不相关的值来测试。
其实呢,我还是觉得,有了方法和思路,根据自己的Idea去Fuzzing比什么都要好,有个叫wifuzzit的框架:
https://github.com/bullo95/WiFi--/tree/master/wifuzzit
挺好的,也发现了一些溢出的CVE等:
CVE-2008-1144年 :Marvell的驱动EAPOL-密钥长度溢出(无线AP)
CVE-2007-5474 :Atheros的供应商特定信息元素溢出(无线AP)
CVE-2007-0933 :缓冲区溢出在无线驱动程序6.0.0.18的的D-Link DWL-G650 +(无线STA)
CVE-2007-5651 :可扩展身份验证协议漏洞(Cisco的无线AP与有线交换机)
CVE-2007-5475 :Marvell的驱动多个信息元素溢出(无线AP)
三、Windows上的Driver Vulnerabilities
其实关于Kernel的漏洞,只要你对Madwifi,无线协议比较清楚的话,再熟悉一些MIPS ,ARM指令就能看懂...注意是读懂,读懂不代表你也能挖出来。
差点把Google炸了才翻出一篇比较老的文章,专门写kernel的,我把主要地方给翻译下贴过来吧,前面讲协议的我看得懂可以分析下,这个后面涉及到内核的我也分析不了,做二进制的有这方面的需求的,可以看下:
最开始他也是提了802.11 Driver 的State,也是说根据State1Fuzzing来的思路,前面噼里啪啦说的跟我前面一样,我直接就贴他后面的漏洞分析。
一个DWL-G132 USB A5AGU.SYS在WINxp下的测试:结果是造成内核崩溃
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1) An attempt was made to access a pageable (or completely invalid) address at an interrupt request level (IRQL) that is too high. This is usually caused by drivers using improper addresses. If kernel debugger is available get stack backtrace. Arguments: Arg1: 56149a1b, memory referenced Arg2: 00000002, IRQL Arg3: 00000000, value 0 = read operation, 1 = write operation Arg4: 56149a1b, address which referenced memory ErrCode = 00000000 eax=00000000 ebx=82103ce0 ecx=00000002 edx=82864dd0 esi=f24105dc edi=8263b7a6 eip=56149a1b esp=80550658 ebp=82015000 iopl=0 nv up ei ng nz ac pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010296 56149a1b ?? ??? Resetting default scope LAST_CONTROL_TRANSFER: from 56149a1b to 804e2158 FAILED_INSTRUCTION_ADDRESS: +56149a1b 56149a1b ?? ??? STACK_TEXT: 805505e4 56149a1b badb0d00 82864dd0 00000000 nt!KiTrap0E+0x233 80550654 82015000 82103ce0 81f15e10 8263b79c 0x56149a1b 80550664 f2408d54 81f15e10 82103c00 82015000 0x82015000 80550694 f24019cc 82015000 82103ce0 82015000 A5AGU+0x28d54 805506b8 f2413540 824ff008 0000000b 82015000 A5AGU+0x219cc 805506d8 f2414fae 824ff008 0000000b 0000000c A5AGU+0x33540 805506f4 f24146ae f241d328 8263b760 81f75000 A5AGU+0x34fae 80550704 f2417197 824ff008 00000001 8263b760 A5AGU+0x346ae 80550728 804e42cc 00000000 821f0008 00000000 A5AGU+0x37197 80550758 f74acee5 821f0008 822650a8 829fb028 nt!IopfCompleteRequest+0xa2 805507c0 f74adb57 8295a258 00000000 829fb7d8 USBPORT!USBPORT_CompleteTransfer+0x373 805507f0 f74ae754 026e6f44 829fb0e0 829fb0e0 USBPORT!USBPORT_DoneTransfer+0x137 80550828 f74aff6a 829fb028 804e3579 829fb230 USBPORT!USBPORT_FlushDoneTransferList+0x16c 80550854 f74bdfb0 829fb028 804e3579 829fb028 USBPORT!USBPORT_DpcWorker+0x224 80550890 f74be128 829fb028 00000001 80559580 USBPORT!USBPORT_IsrDpcWorker+0x37e 805508ac 804dc179 829fb64c 6b755044 00000000 USBPORT!USBPORT_IsrDpc+0x166 805508d0 804dc0ed 00000000 0000000e 00000000 nt!KiRetireDpcList+0x46 805508d4 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x26 |
Fuzz的五秒钟已产生一个缺陷,已经可能对指针进行控制。 为了执行任意代码,然而,一个恶意框架必须定位。在这种情况下,在EDI寄存器所指向成一样的方式,它在Broadcom漏洞做了帧的源地址字段。 随机生成信息元素之一-假EIP值到源地址。
1
2
3
4
5
6
|
kd> dd 0x8263b7a6 (edi) 8263b7a6 f3793ee8 3ee8a34e a34ef379 6eb215f0 8263b7b6 fde19019 006431d8 9b001740 63594364 kd> s 0x8263b7a6 Lffff 0x1b 0x9a 0x14 0x56 8263bd2b 1b 9a 14 56 2a 85 56 63-00 55 0c 0f 63 6e 17 51 ...V*.Vc.U..cn.Q |
下一步是确定哪些信息元素是Crash的原因。 解码后的内存Frame进行了一系列的修直到导致崩溃的特定信息元素被发现。 通过这种方法,确定了溢出的存在利用这个漏洞涉及发现内存中的返回地址指向一个JMP EDI,EDI ,或推电子数据交换; ret指令序列。这是通过运行msfpescan应用程序中包含的ntoskrnl Metasploit框架。 所得的地址必须被调整以考虑内核的基址。ntoskrnl.exe中的地址是0x804f16eb(0x800d7000 + 0x0041a6eb)
1
2
3
4
5
6
|
$ msfpescan ntoskrnl.exe -j edi [ntoskrnl.exe] 0x0040365d push edi; retn 0x0001 0x00405aab call edi 0x00409d56 push edi; ret 0x0041a6eb jmp edi |
实在找不出比这更新的研究内容了,关于国外针对802.11 Fuzz的研究也停滞在了11年。阅读了大约30多份洋码子PDF与PPT以及学术论文,综合写下,有点辛苦.....不管研究不研究,只想让大家明白存在这么一种技术,它的原理是这样,也希望在中文引擎的搜索上,出现关于这一技术的研究内容,如果你也恰好研究过,发现了那里不妥或者出现了错误或者是有更好的方法,欢迎交流指正。上来就喷的,你也放心,我一定会给你喷回去的。