When an IP datagram is sent from one host to the other on a local network, the destination IP address must be known in order to perform the transmissio nat the data link layer. When the IP address of the host is known and the MAC address is needed, a broadcast packet, known as an ARP request is sent out on the network. The destination machine with the IP in the ARP request then responds with an ARP reply.
ARP is a stateless protocol such that all hosts on a network will automatically cache any ARP replies they have received regardless of whether network hosts have requested them. Sometimes, even ARP entries that have not expired are overwritten when a new ARP reply packet is received.
Given two machines A
and B
, with IP a.a.a.a
and MAC aa:aa:aa:aa:aa:aa
, respectively IP b.b.b.b
and MAC bb:bb:bb:bb:bb:bb
, in case machine A
needs to find out the MAC address of machine B
, then machine A
sends an ARP Request packet to the broadcast address. Since B
is part of the same network as A
, the broadcast packet is delivered to B
such that B
responds with its MAC address directly to machine A
.
IP: a.a.a.a IP: b.b.b.b MAC: aa:aa:aa:aa:aa:aa MAC: bb:bb:bb:bb:bb +---+ +-----------+ +---+ | A | | Broadcast | | B | +-+-+ +-----+-----+ +-+-+ | | | | ARP Request | +-------------->+-------------->| | who-has b.b.b.b tell a.a.a.a | | | | | | | | ARP Reply | |<------------------------------+ | b.b.b.b is at bb:bb:bb:bb:bb | | | | | | |
A typical ARP request and reply using tcpdump
:
tcpdump -vvv -i eth0 arp
might look like:
12:54:01.390421 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has b.b.b.b tell a.a.a.a, length 28 12:54:01.391665 ARP, Ethernet (len 6), IPv4 (len 4), Reply b.b.b.b is-at bb:bb:bb:bb:bb:bb (oui Unknown), length 46
Whenever a machine on the local network A
knows the IP address of machine B
and wants to retrieve the MAC address of machine B
, machine A
will first search its own ARP cache on machine A
. On Linux, the ARP cache can be inspected by issuing the command:
arp -a
For instance, following the example and issuing arp -a
on machine A
, the following would be the expected output:
(b.b.b.b) at bb:bb:bb:bb:bb:bb [ether] on eth0
where:
b.b.b.b
is the IP address of machine B
,bb:bb:bb:bb:bb:bb
is the MAC address of the machine B
In this case, the MAC address of machine B
has already been cached on machine A
but suppose that the interface just came up and the ARP cache table is empty. In other words, assume that issuing the command arp -a
on machine A
yields no output. In that case, machine A
must discover the MAC of machine B
such that an ARP request is sent.
An ARP request (and reply) packet has the following illustrative format:
6 bytes 6 2 28 10 +---------------------+----------------+------+---------------------+---------+-----+ | Destination address | Source Address | Type | ARP reply / request | Padding | CRC | +---------------------+----------------+------+---------------------+---------+-----+ | | +-----------------------------------------------------------+-----------------------+ | Hardware type (2 bytes) | Protocol type (2) | +-----------------------------+-----------------------------+-----------------------+ | Hardware address length (1) | Protocol address length (1) | Operation code (2) | +-----------------------------+-----------------------------+-----------------------+ | Source hardware address | +-----------------------------------------------------------------------------------+ | Source protocol address | +-----------------------------------------------------------------------------------+ | Target hardware address | +-----------------------------------------------------------------------------------+ | Target protocol address | +-----------------------------------------------------------------------------------+
where:
1
,2048
or 0x0800
for IPv4 networks,6
bytes,4
bytes,1
) or an ARP reply (2
),ff:ff:ff:ff:ff:ff
for ARP replies) and this field is ignored for ARP requests,
Given the above ARP packet format, in order for machine A
to discover the MAC address of machine B
, A
will have to create an ARP reply packet with the following parameters:
1
indicating an ARP request,A
(aa:aa:aa:aa:aa:aa
),A
(a.a.a.a
),B
(b.b.b.b
)B
is not yet known to machine A
.
All machines on the LAN whose IP address does not match the "Target protocol address" of the packet will drop the packet. When machine B
notices that its IP address matches the "Target protocol address", machine B
will generate an ARP reply packet with the following parameters:
2
indicating an ARP reply,B
(bb:bb:bb:bb:bb:bb
),B
(b.b.b.b
),and will additionally cache the "Source protocol address" and "Source hardware address" in the ARP cache in order to be able to send the ARP reply.
Machine B
will now generate an unicast package to machine A
and deliver the ARP reply and when machine A
receives the ARP reply, A
will update its own ARP cache.
Given that ARP is stateless, any machine that receives an ARP reply packet would update its own internal ARP cache, possibly overwriting any existing entries. All that is required for an ARP poisoning attack, is for a machine to send ARP reply packets to a victim machine, over and over again in order to convince the victim machine that some IP address has a certain MAC address.
Imagine a simple machine B
connected to the network (IP b.b.b.b
and MAC bb:bb:bb:bb:bb:bb
) with the ability to reach the LAN and the Internet though a gateway provided by the DHCP server on the network that the machine joins. Initially, the ARP cache will be empty as illustrated by the arp -a
command:
arp -a
Let there be an attacker A
(IP a.a.a.a
and MAC aa:aa:aa:aa:aa:aa
) that wants to poison the victim machine B
ARP cache and convince victim B
that machine C
(IP c.c.c.c
and MAC cc:cc:cc:cc:cc
) is in fact located at the address of the attacker machine A
.
IP: a.a.a.a IP: b.b.b.b IP: c.c.c.c MAC: aa:aa:aa:aa:aa:aa MAC: bb:bb:bb:bb:bb:bb MAC: cc:cc:cc:cc:cc:cc +---+ +---+ +---+ | A | | B | | C | +-+-+ +-+-+ +-+-+ | | | | | traffic to c.c.c.c | | +--------------------------->| | | | | ARP reply packets | | +------------------------------>| | +------------------------------>| | +------------------------------>| | | c.c.c.c is at aa:aa:aa:aa:aa | | | | | | traffic to c.c.c.c | | |<------------------------------+ | | | |
In order to do so, the attacker machine A
will spam the victim machine B
with ARP reply packets, even if machine B
has not made any ARP requests to the network, telling machine B
that machine C
with IP address c.c.c.c
has the MAC address a:aa:aa:aa:aa:aa
instead of cc:cc:cc:cc:cc:cc
.
For instance, by using nping
, an ARP reply packet can be crafted on machine A
and then delivered to machine B
by executing the command:
nping --arp b.b.b.b --arp-type ARP-reply --arp-sender-mac aa:aa:aa:aa:aa:aa --arp-sender-ip c.c.c.c
Now, if one were to execute arp -a
on machine B
in order to see the ARP cache, the following output would be observed:
? (c.c.c.c) at aa:aa:aa:aa:aa:aa [ether] on eth0
where:
eth0
is the local LAN interface shared by all machines
Now, starting tcpdump
on machine A
in order to check for ICMP traffic to and from machine B
:
tcpdump -vvv -i eth0 'icmp and (src b.b.b.b or dst b.b.b.b)'
and then issuing a simple ping
command on machine B
to machine C
while observing tcmpdump
on machine A
reveals:
08:41:40.965396 IP (tos 0x0, ttl 64, id 13679, offset 0, flags [DF], proto ICMP (1), length 84) b.b.b.b > c.c.c.c: ICMP echo request, id 35568, seq 55, length 64 08:41:41.989911 IP (tos 0x0, ttl 64, id 13841, offset 0, flags [DF], proto ICMP (1), length 84) b.b.b.b > c.c.c.c: ICMP echo request, id 35568, seq 56, length 64
This shows that machine B
is now convinced that machine C
lies at the address of machine A
and then delivers via the ping
command the ICMP echo request packets to machine A
. When machine A
receives the packets from B
, it observes that the ICMP packet contains the source IP address of machine B
(b.b.b.b
which is plausible) and the destination IP of machine C
(c.c.c.c
) such that machine A
does not reply.
Nevertheless and irrespective of the source and destination addresses set in the packets by machine B
, while the ARP poisoning takes effect, machine B
will deliver all traffic intended for machine C
to the attacker machine A
.
Even though ARP posisoning can be performed for various reasons, the most common would be to perform a Man-in-The-Middle (MiTM) attack in order to be able to control the traffic of a machine on the local network.
Consider the previous ARP poisoning setup with three machines A
, B
and C
with their corresponding IP and MAC addresses. Furthermore, let machine C
be the legitimate gateway of the local area network consisting of the machines A
, B
and C
.
IP: a.a.a.a IP: b.b.b.b IP: c.c.c.c MAC: aa:aa:aa:aa:aa:aa MAC: bb:bb:bb:bb:bb:bb MAC: cc:cc:cc:cc:cc:cc +---+ +---+ +---+ | A | | B | | C | +-+-+ +-+-+ +-+-+ | | | | | traffic from B to Internet | | +----------------------------+----------------------> | | | | ARP reply packets | | +------------------------------>| | +------------------------------>| | +------------------------------>| | | c.c.c.c is at aa:aa:aa:aa:aa | | | | | | traffic from B to Internet | | <-----------+-------------------------------+ | | | |
Checking the routing table on machine B
with route -n
reveals a very basic network topology:
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 c.c.c.c 0.0.0.0 UG 0 0 0 eth0 c.c.c.c 0.0.0.0 255.255.255.255.0 U 0 0 0 eth0
where:
c.c.c.c
is the IP address of machine C
and is an acting gateway for machine B
on the local network
In order to redirect the traffic such that the attacker machine A
becomes the gateway for machine B
, the attacker machine A
performs an ARP posisoning attack against machine B
in order to convince machine B
that the IP address c.c.c.c
has the MAC address of machine A
(aa:aa:aa:aa:aa:aa
).
The same nping
command can be used to achieve that effect:
nping --arp b.b.b.b --arp-type ARP-reply --arp-sender-mac aa:aa:aa:aa:aa:aa --arp-sender-ip c.c.c.c -c 5555555 --delay 100ms
where:
-c 5555555
makes nping
send a large amount of packets,–delay 100ms
is used to reduce the delay between packets and increase the chances that the ARP cache will be poisoned on machine B
Once the traffic from machine B
needs to be sent through the gateway c.c.c.c
, the IP address c.c.c.c
will resolve to the MAC address of machine A
(aa:aa:aa:aa:aa:aa
). Now, all that the attacker machine A
has to do in order to observe the traffic is to perform some network address translation (NAT) for machine B
and enable IP forwarding.
Unfortunately, most Ethernet networks are susceptible to ARP posisoning attacks such that there are just a few options available. On the other hand, the same ARP spoofing mechanism is in fact leveraged by some frameworks, in particular, load balancing networks in order to allow a machine on the local network to take over some incoming traffic. That being said, since ARP spoofing is both a feature and a vulnerability, the mitigations available are limited hinging on a matter of compromise.
It goes without saying that traffic between two endpoints, for instance, between a machine on the LAN and a remote website across the Internet should always be encrypted point-to-point such as by using SSL and secure protocol counterparts such as HTTPs, FTPs, etc. By using point-to-point encryption, even if an ARP poisoning attack is used in order for an attacker machine to become a gateway, the attacker will not be able to observe the plain text traffic between the poisoned victim machine and the remote site.
In regards to the ARP spoofing attack directly, features such as "Static/Dynamic ARP Inspection" (DAI) help prevent ARP poisoning attacks accross a LAN by intercepting ARP packets and checking the MAC and IP address against a trusted and locally stored database of MAC to IP mappings.
A different approach would be for all machines to have static ARP entries for important machines on the network in order to not allow the connection to those machines to be hijacked by an ARP poisoning attack. Typically, adding a static entry into the ARP tables can be done via the following command:
arp -s c.c.c.c cc:cc:cc:cc:cc:cc
where:
c.c.c.c
is the IP address and,cc:cc:cc:cc:cc:cc
is the MAC addressUnfortunately, the maintenance costs in order to configure each and every machine on the LAN using static ARP tables is very high because all machines have to be updated. Similarly, in case a network change is to be made, changing the static ARP tables could be bothersome.
Another avenue of prevention would be the implementation of 802.11X on the local LAN (may it be wired or wireless) that would make the clients benefit from a combination of protections, such as point-to-point encryption with the gateway based on pre-installed certificates or port control where the switches and linking equipment only allow connections from one single MAC address per hardware port.