首先是创建以太网头部和ARP头部结构: ★ typedef struct _et_header //以太网头部 { unsigned char eh_dst[6]; unsigned char eh_src[6]; unsigned eh_type; }ET_HEADER; typedef struct _arp_header //ARP头部 { unsigned arp_hdr; unsigned arp_pro; unsigned char arp_hln; unsigned char arp_pln; unsigned arp_opt; unsigned char arp_sha[6]; unsigned long arp_spa; unsigned char arp_tha[6]; unsigned long arp_tpa; }ARP_HEADER; ★ 然后是发送ARP请求报文主线程取得所有适配器名字其中“adapter_name”表示个用于存放适配器名字缓冲区而这些适配器名字将以UNICODE编码方式存入此缓冲区中UNICODE编码方式就是用个字空间(两个字节)来存放个这样每个间自然会出现个'\0'而两个适配器名字的间将会有个字为'\0'作为间隔adapter_length:这个缓冲区大小: ★ (PacketGetAdapterNames((char*)adapter_name, &adapter_length)FALSE) { prf("PacketGetAdapterNames error:%d\n",GetLastError); 0; } ★ 打开适配器此处我默认打开第块适配器: ★ lpAdapter=(LPADAPTER)PacketOpenAdapter((LPTSTR)adapter_list[0]); (!lpAdapter||(lpAdapter->hFileINVALID_HANDLE_VALUE)) { prf("Unable to open the driver, Error Code : %lx\n", GetLastError); 0; } ★ 以太网头部和ARP头部结构赋值StrToMac是笔者自定义串转换为Mac地址: ★ StrToMac("00E06E41508F",s_Mac); //"00E06E41508F"是笔者测试所用本地机网卡地址,测试者应将其改为测试机网卡地址 memcpy(et_header.eh_src,s_Mac,6); StrToMac("FFFFFFFFFFFE",d_Mac); //目物理地址设置为FFFFFFFFFFFE memcpy(et_header.eh_dst,d_Mac,6); et_header.eh_type=htons(0x0806); //类型为0x0806表示这是ARP包 arp_header.arp_hdr=htons(0x0001); //硬件地址类型以太网地址 arp_header.arp_pro=htons(0x0800); //协议地址类型为IP协议 arp_header.arp_hln=6; //硬件地址长度为6 arp_header.arp_pln=4; //协议地址长度为4 arp_header.arp_opt=htons(0x0001); //标识为ARP请求 arp_header.arp_spa=inet_addr("172.24.21.10"); //"172.24.21.10"是我测试所用本地机IP,测试者应将其改为测试机IP memcpy(arp_header.arp_sha,et_header.eh_src,6); arp_header.arp_tpa=inet_addr(argv[1]); memcpy(arp_header.arp_tha,et_header.eh_dst,6); ★ 发送数据包: ★ lpPacket=PacketAllocatePacket; //给PACKET结构指针分配内存 PacketInitPacket(lpPacket,buffer,512); //化PACKET结构指针 PacketSetNumWrites(lpAdapter,5); //设置发送次数 PacketSendPacket(lpAdapter,lpPacket,TRUE);//发送ARP请求包 ★ 最后别忘了扫尾工作: ★ PacketFreePacket(lpPacket); //释放PACKET结构指针 PacketCloseAdapter(lpAdapter); //关闭适配器 ★ 最后是监听线程: 设置接收数据包系列参数: ★ PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_DIRECTED); //设置网卡为直接模式 PacketSetBuff(lpAdapter,1024); //设置网卡接收数据包缓冲区大小 PacketSetReadTimeout(lpAdapter,2); //设置接收到个包后“休息”时间 ★ 接收数据包: ★PacketReceivePacket(lpAdapter, lpPacket, TRUE); //接收数据包★ 对数据包进行分析以得出结论: ★ char *buf; bpf_hdr *lpBpfhdr; ET_HEADER *lpEthdr; in_addr addr={0}; buf=(char *)lpPacket->Buffer; lpBpfhdr=(bpf_hdr *)buf; lpEthdr=(ET_HEADER *)(buf+lpBpfhdr->bh_hdrlen); (lpEthdr->eh_typehtons(0x0806)) //判断是否为ARP包 { ARP_HEADER *lpArphdr=(ARP_HEADER*)(buf+lpBpfhdr->bh_hdrlen+(ET_HEADER)); char source_ip[20]={0},dest_ip[20]={0}; addr.S_un.S_addr=lpArphdr->arp_spa; memcpy(source_ip,inet_ntoa(addr),strlen(inet_ntoa(addr))); mem(&addr,0,(in_addr)); addr.S_un.S_addr=lpArphdr->arp_tpa; memcpy(dest_ip,inet_ntoa(addr),strlen(inet_ntoa(addr))); (!strcmp(source_ip,ip) && !strcmp(dest_ip,"172.24.21.10")) //判断接收到包源IP和目IP是否正确(串变量ip是从主线程传递过来被探测机ip) { (lpArphdr->arp_opthtons(0x0002)) //判断是否为ARP应答 { prf("There is a Snfer!\n"); } } }
antiarpsniffer:用ARP伪装广播探测网络中的Sniffer
首先是创建以太网头部和ARP头部结构: ★ typedef struct _et_header //以太网头部 { unsigned char eh_dst[6]; unsigned char eh_src[6]; unsigned eh_type; }ET_HEADER; typedef struct _arp_header //ARP头部 { unsigned arp_hdr; unsigned arp_pro; unsigned char arp_hln; unsigned char arp_pln; unsigned arp_opt; unsigned char arp_sha[6]; unsigned long arp_spa; unsigned char arp_tha[6]; unsigned long arp_tpa; }ARP_HEADER; ★ 然后是发送ARP请求报文主线程取得所有适配器名字其中“adapter_name”表示个用于存放适配器名字缓冲区而这些适配器名字将以UNICODE编码方式存入此缓冲区中UNICODE编码方式就是用个字空间(两个字节)来存放个这样每个间自然会出现个'\0'而两个适配器名字的间将会有个字为'\0'作为间隔adapter_length:这个缓冲区大小: ★ (PacketGetAdapterNames((char*)adapter_name, &adapter_length)FALSE) { prf("PacketGetAdapterNames error:%d\n",GetLastError); 0; } ★ 打开适配器此处我默认打开第块适配器: ★ lpAdapter=(LPADAPTER)PacketOpenAdapter((LPTSTR)adapter_list[0]); (!lpAdapter||(lpAdapter->hFileINVALID_HANDLE_VALUE)) { prf("Unable to open the driver, Error Code : %lx\n", GetLastError); 0; } ★ 以太网头部和ARP头部结构赋值StrToMac是笔者自定义串转换为Mac地址: ★ StrToMac("00E06E41508F",s_Mac); //"00E06E41508F"是笔者测试所用本地机网卡地址,测试者应将其改为测试机网卡地址 memcpy(et_header.eh_src,s_Mac,6); StrToMac("FFFFFFFFFFFE",d_Mac); //目物理地址设置为FFFFFFFFFFFE memcpy(et_header.eh_dst,d_Mac,6); et_header.eh_type=htons(0x0806); //类型为0x0806表示这是ARP包 arp_header.arp_hdr=htons(0x0001); //硬件地址类型以太网地址 arp_header.arp_pro=htons(0x0800); //协议地址类型为IP协议 arp_header.arp_hln=6; //硬件地址长度为6 arp_header.arp_pln=4; //协议地址长度为4 arp_header.arp_opt=htons(0x0001); //标识为ARP请求 arp_header.arp_spa=inet_addr("172.24.21.10"); //"172.24.21.10"是我测试所用本地机IP,测试者应将其改为测试机IP memcpy(arp_header.arp_sha,et_header.eh_src,6); arp_header.arp_tpa=inet_addr(argv[1]); memcpy(arp_header.arp_tha,et_header.eh_dst,6); ★ 发送数据包: ★ lpPacket=PacketAllocatePacket; //给PACKET结构指针分配内存 PacketInitPacket(lpPacket,buffer,512); //化PACKET结构指针 PacketSetNumWrites(lpAdapter,5); //设置发送次数 PacketSendPacket(lpAdapter,lpPacket,TRUE);//发送ARP请求包 ★ 最后别忘了扫尾工作: ★ PacketFreePacket(lpPacket); //释放PACKET结构指针 PacketCloseAdapter(lpAdapter); //关闭适配器 ★ 最后是监听线程: 设置接收数据包系列参数: ★ PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_DIRECTED); //设置网卡为直接模式 PacketSetBuff(lpAdapter,1024); //设置网卡接收数据包缓冲区大小 PacketSetReadTimeout(lpAdapter,2); //设置接收到个包后“休息”时间 ★ 接收数据包: ★PacketReceivePacket(lpAdapter, lpPacket, TRUE); //接收数据包★ 对数据包进行分析以得出结论: ★ char *buf; bpf_hdr *lpBpfhdr; ET_HEADER *lpEthdr; in_addr addr={0}; buf=(char *)lpPacket->Buffer; lpBpfhdr=(bpf_hdr *)buf; lpEthdr=(ET_HEADER *)(buf+lpBpfhdr->bh_hdrlen); (lpEthdr->eh_typehtons(0x0806)) //判断是否为ARP包 { ARP_HEADER *lpArphdr=(ARP_HEADER*)(buf+lpBpfhdr->bh_hdrlen+(ET_HEADER)); char source_ip[20]={0},dest_ip[20]={0}; addr.S_un.S_addr=lpArphdr->arp_spa; memcpy(source_ip,inet_ntoa(addr),strlen(inet_ntoa(addr))); mem(&addr,0,(in_addr)); addr.S_un.S_addr=lpArphdr->arp_tpa; memcpy(dest_ip,inet_ntoa(addr),strlen(inet_ntoa(addr))); (!strcmp(source_ip,ip) && !strcmp(dest_ip,"172.24.21.10")) //判断接收到包源IP和目IP是否正确(串变量ip是从主线程传递过来被探测机ip) { (lpArphdr->arp_opthtons(0x0002)) //判断是否为ARP应答 { prf("There is a Snfer!\n"); } } }
最新评论