Detect ARP poisoning on LAN

ARP Poisoning : Potential MITM attack

Occasionally during security audits it may be necessary to check your LAN for rogue machines. All the potential rogue machine in your LAN needs to do is poison your ARP cache so that the cache thinks that the attacker is the router or the destination machine. Then all packets to that machine will go through the rogue machine, and it will be, from the network’s standpoint, between the client and the server, even though technically it’s just sitting next to them. This is actually fairly simple to do, and is also fairly easy to detect as a result.

In this sample case, the rogue machine was in a different room but still on the same subnet. Through simple ARP poisoning it convinced the router that it was our server, and convinced the server that it was the router. It then had an enjoyable time functioning as both a password sniffer and a router for unsupported protocols.

By simply pinging all the local machines (nmap -sP will do this quickly) and then checking the ARP table (arp -an) for duplicates, you can detect ARP poisoning quite quickly.

$ arp -an| awk '{print $4}'| sort | uniq -c | grep -v ' 1 '
    5 F8:F0:11:15:34:51

Then I simply looked at the IP addresses used by that ethernet address in ‘arp -an’ output, ignoring those that were blatantly poisoned (such as the router) and looked up the remaining address in DNS to see which machine it was.

Below is a script I wrote to automate this process (perhaps in a cron job) , and send out an alert email if any ARP poisoning is detected.

ARP Poisoning Check Script

This can ideally run as a cronjob (i.e. 30 * * * *)

# Star Dot Hosting
# detect arp poisoning on LAN

currentmonth=`date "+%Y-%m-%d %H:%M:%S"`

rm $logpath/arpwatch.log

echo "ARP Poisoning Audit: " $currentmonth >> $logpath/arpwatch.log
echo -e "-----------------------------------------" >> $logpath/arpwatch.log
echo -e >> $logpath/arpwatch.log

arp -an | awk '{print $4}' | sort | uniq -c | grep -v ' 1 '

if [ "$?" -eq 0 ]
        arp -an | awk '{print $4}' | sort | uniq -c | grep -v ' 1 ' >> $logpath/arpwatch.log 2>&1
        cat $logpath/arpwatch.log | mail -s 'Potential ARP Poisoning ALERT!'
echo -e "No potential ARP poisoning instances found..." >> $logpath/arpwatch.log