/** * ArpSpoofDetection @ 01/26/2004 - 12:51:55 * <romain.guy@jext.org> * Monitors ARP replies to detect ARP spoofing actions (also called ARP poisoning). */import java.util.HashMap;import jpcap.*;/** * The monitor is based on the jpcap library from netresearch. Implementing the simple * JpcapHandler interface */public class ArpSpoofDetection implements JpcapHandler{ ////////////////////////////////////////////////////////////////////////////////////////////////// // ATTRIBUTES ////////////////////////////////////////////////////////////////////////////////////////////////// // this is our internal ARP table, independant from the system one private HashMap arpTable = new HashMap(); ////////////////////////////////////////////////////////////////////////////////////////////////// // METHODS & CONSTRUCTORS ////////////////////////////////////////////////////////////////////////////////////////////////// /** * Empty, dummy constructor. * Waiting for better use. */ public ArpSpoofDetection() { } /** * Event driven monitoring. Each time a packet is sniffed from the wires, it is sent to the * handlePacket() method of the JpcapHandler interface. * Our goal is to check if it is an ARP packet of type REPLY. By looking up our internal ARP * table we will be able to issue ARP poisoning warnings. * We've performed additional checks to guarantee the packet is an Ethernet frame encapsulating * an IP packet. */ public void handlePacket(Packet packet) { if (packet instanceof ARPPacket) { ARPPacket arp = (ARPPacket) packet; if (arp.operation == ARPPacket.ARP_REPLY && arp.hardtype == ARPPacket.HARDTYPE_ETHER && arp.prototype == ARPPacket.PROTOTYPE_IP) { // tricky stuff which lets us get a string representation of the MAC address EthernetPacket ethernet = new EthernetPacket(); ethernet.src_mac = arp.sender_hardaddr; // another tricky stuff to get the IP address as a string IPAddress ip = new IPAddress(arp.sender_protoaddr); String sourceMACAddress = ethernet.getSourceAddress(); String sourceIPAddress = ip.toString(); // lookup for an existing entry in the ARP table // getting a new ARP reply is considered suspect if (arpTable.containsKey(sourceIPAddress)) { // when the received ARP reply contains a MAC/IP couple different // from the one stored in our ARP table, we issue a warning if (!arpTable.get(sourceIPAddress).equals(sourceMACAddress)) { System.out.println("[WARNING] " + sourceIPAddress + " was " + arpTable.get(sourceIPAddress) + " and is now " + sourceMACAddress); } // when the host is unknown we assume it is a legacy one // therefore, we register it in our arpTable } else { arpTable.put(sourceIPAddress, sourceMACAddress); } } } } /** * Starts the actual monitoring process. * This method uses the first network device of the system by default. * XXX : hack to let user choose his preferred device. */ public void antiSpoof() { System.out.println("Using network interface " + Jpcap.getDeviceList()[0]); try { Jpcap dump = Jpcap.openDevice(Jpcap.getDeviceList()[0], 1024, true, 20); dump.loopPacket(-1, this); } catch (java.io.IOException ioe) { System.err.println("Unable to activate dump."); } } ////////////////////////////////////////////////////////////////////////////////////////////////// // MAIN ENTRY POINT ////////////////////////////////////////////////////////////////////////////////////////////////// public static void main(String[] args) { // starts the arp spoofing monitoring process ArpSpoofDetection arp = new ArpSpoofDetection(); arp.antiSpoof(); }}