Search this site





ARP Security - ARP-related security issues


During a bit of boredom, I found that I could knock my friend's Mac laptop offline by assuming it's IP address. After some quick research, I found that I could convince another machine that "I" was using it's IP address, and it would happily panic and try and attempt to get a new address with dhcp. I thought to myself, "It can't be this easy to DoS someone on a local network."

In any case, much of this article is probably common knowledge in the security community. However, it was new to me as I was discovering and researching it; so here it is. All of the research here was through trial and error, and I broke the network a few times ;)

ARP, IPs, and You

My first hunch for why this works was to blame the network hardware (switches, etc). Turns out I was wrong. Let's start from the beginning!

So, I start off by assuming someone else's ip address:
ifconfig rl0 inet
What happens when I do that? Watching tcpdump in another window:
17:25:40.216489 00:50:ba:15:19:0d > Broadcast, ethertype ARP (0x0806), length 60: arp who-has tell
Can't decipher tcpdump output? That's ok. When I set my IP to '' my operating system sends out an arp "who-has" packet seeing if anyone else has this IP. So why is this important?

When any computer on the network receives this kind of packet, it puts an entry in a table called the ARP table. The ARP table maps IP addresses to MAC addresses. This kind of packet is a broadcast arp packet that has the same "who-has" IP address as "tell" IP address. The problem with very dynamic networks is that the likelihood of anything on the network having any static (permanent) arp entries is very low. Translation: You can poison hosts and network devices with little effort.

How can we make the process of poisoning easier? We can use nemesis, a packet injection tool, to help us out. Instead of using OS tools to set our IP, we can use nemesis to poison networked devices.

Nemesis for Arp Poisoning

Remember that packet that we sent out when we changed our IP? Well we can spoof it with nemesis.
nemesis arp -S -D \ 
            -H 00:de:ad:be:ef:00 -h 01:de:ad:be:ef:00
This will broadcast an arp "who-has" packet on the network and pretty much every machine will happily update their arp tables with your new entry for the ip and the mac address of 00:de:ad:be:ef:00.

So let's put this to use on an existing host on our network:
kenya% arp 
? ( at 00:0c:f1:2e:2b:95 on tl0 [ethernet]
... meanwhile, I'm being evil ...
whack% sudo nemesis arp -S -D \ 
            -H 00:de:ad:be:ef:00 -h 00:de:ad:be:ef:00
... and back on the other machine ...
kenya% arp
? ( at 00:de:ad:be:ef:00 on tl0 [ethernet] 
Note how the mac addresses are different after I poison the network. This technique is wonderfully simple. Most (all?) machines and network devices on the network should now be convinced that 00:de:ad:be:ef:00 is the proper mac address for the ip

Now that we've poisoned the network, we can sniff traffic and see that packets that were intended on the "real" are now coming to us because the switches know that 00:de:ad:be:ef:00 is us. The added benefit, is that our real mac address is not 00:de:ad:be:ef:00. Audits logs will not track us easily, especially on large-user networks with several unmanaged switches.

Attack: Local DoS

If your network uses dhcp with dynamic dns, you can very easily track someone and keep them from gaining network access if you are on the same network segment (wireless networks, anyone?). This simple scriptlet will keep a particular host offline as long as it's running:
while true; do 
  nemesis arp -S poorsap -D poorsap \ 
    -H 00:de:ad:be:ef:00 -h 00:de:ad:be:ef:00
  sleep 1
Once a second, I'll claim I am poorsap. Every time this person does dhcp and it updates dns, nemesis will look up the hostname and send out the packet on the network claiming that another machine is actually poorsap. No one will send packets to the real poorsap because they think it's mac address is elsewhere. Furthermore, if the OS panics and does a dhcp release/renew sequence, the dns entry will update and it'll kick it off a new IP address, if any. This has other benefits I'll mention in the next section

Attack: Man in the Middle

There are two flavors of this kind of attack: Local and Remote. I don't want to get in a religious war with security pedants about semantics, but for this situation, local means the local network segment (layer 2), and remote means outside the local network.

There are two styles of each attack: The first being where you broadcast arp changes to the local net to convince everyone on the local segment that there is a new mac address for a given IP. The second is where you convince only an individual host that a mac address has changed for a given IP.

The first attack, local, is where you convince a network or a host that you are someone else on the local segment. Traffic intended for the target host will go to you.

The second attack, remote, is where you convince a network or a host that you are the gateway. Traffic intended for outbound delivery will try to go through you. Feel free to sniff their outbound traffic such as authentication, aim conversations, etc. More on this later

You get the idea, arp poisoning is too easy to do on normal host machines. And on dynamic networks, it's very likely that local-segment routers will have to listen to arp updates.

Simple MITM Script

I'm lazy. I'll be the first to admit it. So in lazy efforts, I wrote a script to automate the task of poisoning hosts and routers. You can grab arpmitm here. You can repair your changes once you've played around with it enough by using the '-r' option along with the original -v and -g options.

I can simply do this:
./arpmitm -v poorsap -g gateway_ip
And viola! All of poorsap's traffic is going through me, both inbound and outbound. Makes you feel safe about your network eh? Hell, Windows doesn't even log arp table changes as far as I know. I tried this against a friend's Windows XP machine, and there was nothing about it in the event viewer logs. Therefore, any normal user will be completely oblivious to the fact that their computer just agreed to route traffic through you. Fantastic design, eh?

The clear benefit here is that I can now sniff your traffic without being in promiscuous mode. Promiscuous mode is detectable in certain environments depending on the promiscuous node's OS, drivers, etc. Furthermore, I've found that wireless cards stop being able to function normally while in promiscuous mode. Kill both of those birds with one stone by doing this method.

Getting more complex

Add a firewall rule or two for nat and port redirection (FreeBSD PF):
nat on ndis0 from !ndis0 to any ->
rdr pass on ndis0 inet proto tcp from any to any port 80 -> port 80
Turn on pf, load those rules, and run arpmitm on someone. All their web traffic will point them to '' regardless of the destination host. The poor user tries to go to, and comes up. Brilliantly simple.


The danger from this kind of attack is clear. It seems the only way to protect against this is to use static (permanent) arp entries in both the router and client hosts. However, it needs to be mentioned that using static arp entries will never scale even in small environments (less than 5 servers) becuase you'll have to update all servers whenever an entry needs changing. PITA, more work that it's worth.

Static arp entries can be set in most operating systems with the following command:
arp -s [ip_address] [mac_address]
If you do this, then your arp table will now have a permanent entry in it. It might be a good idea if you had a dhcp-client hook script that set a static arp entry for the gateway after every successful dhcp request. That assumes, however, that you are getting a dhcp address from a trustworthy dhcp server. If someone's put up an evil dhcp server, that's a whole other ball game I won't be covering in this article.

Forgetting dhcp-client hosts for the moment, let's focus on servers. If your environment is such that server ip addresses never change, then you may benefit from static arp entries. However, if IPs or network interfaces change more than never, static entries are a waste of effort and will just serve as a point of breakage. Unfortunately in a larger environment, servers may change more often than never, so setting static entries, again, is way more effort than it is worth.

Anyway, most switches can have static arp entries for servers mapping the server's mac address to the switch port where the server is connected. Furthermore, all servers can also have static arp entries of other servers as well as static entries for any gateway hosts.

Another way to fix this is to rethink your network layout. Have your important servers on a secure subnet with limited access. This includes limiting both physical and remote access. If I can't get on the local segment, I can't poison your machines.


The ease of this style of attack worries me. For those of you who already know about it and have worked with it before: How else can you prevent this?

As always, if you feel like contributing ideas or comments, please email me or bug me on AIM. I'm always interested in feedback. (My contact information can be found in the 'about' section)