Created
September 11, 2021 00:33
-
-
Save 003random/7a545253fc2f65e0c3cf0e5d0e5e48e7 to your computer and use it in GitHub Desktop.
Revisions
-
003random created this gist
Sep 11, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,95 @@ package main import ( "fmt" "log" "net" "os" "time" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcap" ) func main() { // Store arguments as variables of the right type iface := os.Args[1] srcMAC, err := net.ParseMAC(os.Args[2]) if err != nil { log.Fatal(err) } srcIP := net.ParseIP(os.Args[3]) // Create mapping to store ARP reply values replies := make(map[string]string) // Open socket handle, err := pcap.OpenLive(iface, 2048, false, 100*time.Nanosecond) if err != nil { log.Fatal(err) } // Only capture ARP replies if err := handle.SetBPFFilter("arp[6:2] = 2"); err != nil { log.Fatal(err) } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) // Loop over the incoming packets channel for packet := range packetSource.Packets() { arpLayer := packet.Layer(layers.LayerTypeARP) arp, ok := arpLayer.(*layers.ARP) if !ok { continue } err = sendARPRequest(handle, srcMAC, srcIP, arp.SourceProtAddress) if err != nil { log.Fatal(err) } if previousMAC, ok := replies[net.IP(arp.SourceProtAddress).String()]; ok { if previousMAC != net.HardwareAddr(arp.SourceHwAddress).String() { fmt.Println("ARP Spoofing Detected for IP Address", net.IP(arp.SourceProtAddress).String()) } } replies[net.IP(arp.SourceProtAddress).String()] = net.HardwareAddr(arp.SourceHwAddress).String() time.AfterFunc(time.Second*50, func() { delete(replies, net.IP(arp.SourceProtAddress).String()) }) } } func sendARPRequest(handle *pcap.Handle, srcMAC net.HardwareAddr, srcIP, dstIP net.IP) error { // Construct layers for the ARP request eth := layers.Ethernet{ SrcMAC: srcMAC, DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, EthernetType: layers.EthernetTypeARP, } arp := layers.ARP{ AddrType: layers.LinkTypeEthernet, Protocol: layers.EthernetTypeIPv4, HwAddressSize: 6, ProtAddressSize: 4, Operation: layers.ARPRequest, SourceHwAddress: []byte(srcMAC), SourceProtAddress: srcIP.To4(), DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, DstProtAddress: dstIP.To4(), } buf := gopacket.NewSerializeBuffer() // Send a single ARP request packet (we never retry a send, since this err := gopacket.SerializeLayers(buf, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, ð, &arp) if err != nil { return err } return handle.WritePacketData(buf.Bytes()) }