Detecting ARP Spoofing Attacks

After investigating an ARP spoofing incident recently, I started thinking of how we could easily ferret out this sort of information when responding to a potential incident.

In this particular case, there were two important parts of the attack:

  1. ARP spoofing forced all traffic bound for the default gateway to be funneled through the infected machine, and
  2. HTTP proxying allowed for the injection of malicious code in HTML documents.

ARP spoofing would be easy to detect and/or rule out if you happen to know the MAC address of the default gateway off the top of your head as you could just look at the local ARP cache ("arp -a" at a command prompt) to make sure you had the right one; however, I'd suspect that most people wouldn't have that information easily at hand. 

Another approach that might work is to:

  • Start a network capture.
  • Clear the ARP cache of any entries for the default gateway ("arp -d 192.168.0.1").
  • Initiate a connection to something on the other side of the default gateway ("ping microsoft.com").
  • Stop the capture and look to see if you got more than one ARP response when you ARP'd for the default gateway.

This approach is messy and it makes the assumption that the malware responds to ARP requests rather than just spamming the hosts on the subnet with gratuitous ARPs.   The remaining approach would be to do what we did in this incident -- take a network trace of general network traffic and look for the excessive gratuitous ARPs coming from the infected machine.  (I'd also suspect that most IDS systems would catch this -- if you were feeling lazy, you could probably take the network trace and feed it through Snort in offline mode...)

I had an epiphany about the second part, detection injection of malicious code in HTML docs, while I was having a romantic dinner over the weekend.  Fortunately, my significant other is used to this sort of behavior and she didn't even roll her eyes when I asked if she had a pen and paper so I could write it down...

The epiphany was that the best way to find injected code was to compare a suspicious document with a known-good document.  Of course, the problem is finding a known-good doc to compare to but, with a bit of thought, I came up with an additional insight -- an attacker couldn't inject a payload into a doc downloaded over SSL.  So, I think the following would work nicely:

Unfortunately, the two copies of default.aspx, in this example, will have minor differences but nothing so obvious as an <iframe> pointing somewhere else.

I'm open to other approaches, though, and I'd love to hear from folks who have other ideas.