Pwn The Network - Discover devices in the network using ARP scan
Once connected to a network, a hacker/penetration tester starts by discovering devices connected to the same network. This is the first part of the information gathering phase in every network pentesting assessment.
There several ways to scan a network, for example, a technique like ping sweep is used to send ICMP echo request packets to every device and get responses from connected devices. Sometimes, this method is not reliable enough, as some devices running a firewall may not respond depending on the firewall rules. On the other hand, performing an ARP scan is more reliable as all devices must respond to ARP packets even the ones that are running firewalls, otherwise they cannot communicate with any other machine. In this article, we explain what is the ARP and how can we use it to discover devices in a network. As always, we will be implementing the whole thing in python.
What is ARP ?
ARP stands for address resolution protocol. This protocol is used to find the MAC address of the device corresponding to its IP address. This protocol aims to create communication between two devices on a local area network (Ethernet) by providing the other device’s MAC address. To establish communication between two devices, the source device needs to generate the ARP request message.
ARP protocol
When a new computer joins a local area network (LAN), it will receive a unique IP address to use for identification and communication.
Packets of data arrive at a gateway, destined for a particular host machine. The gateway, or the piece of hardware on a network that allows data to flow from one network to another, asks the ARP program to find a MAC address that matches the IP address. The ARP cache keeps a list of each IP address and its matching MAC address. The ARP cache is dynamic, but users on a network can also configure a static ARP table containing IP addresses and MAC addresses.
In our case, we will use ARP to broadcast a request to the entire network. Devices that are connected to the same network must respond with ARP response.
What is a Scapy?
To perform an ARP scan, we need to forge our own packets from scratch, so we can send ARP request to the whole network. To do so, there is no better than the powerful scapy framework. Scapy is able to forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more. Scapy mainly does two things: sending packets and receiving answers. You define a set of packets, it sends them, receives answers, matches requests with answers and returns a list of packet couples (request, answer) and a list of unmatched packets.
Let’s code
The python script we are going to code is pretty simple to write yet it is a good introduction to scapy as we will use it often in the series Pwn The Network articles.
We use our script as follows: python3 arp-scanner.py --network <net_addr>/<subnet_prefix>
ARP protocol
We will only need the scapy
and argparse
libraries to parse the network address we want to scan.
To install scapy, use pip install scapy
import scapy.all as scapy
import argparse
The scan
function is defined to take in the IP address of the network as an argument and return a list of answered ARP (Address Resolution Protocol) requests. An ARP request is a packet that is broadcasted to all devices on a network to find their MAC (Media Access Control) addresses. The function creates an ARP request packet and a broadcast packet, combines them, and sends them to the specified network using the scapy.srp
function. The function then returns the list of answered requests.
#define the function to scan the network
def scan(ip):
arp_request = scapy.ARP(pdst=ip) #create an ARP request packet
broadcast = scapy.Ether(dst='ff:ff:ff:ff:ff:ff') #create a broadcast packet
arp_request_broadcast = broadcast/arp_request #combine the ARP request and broadcast packet
answered_list= scapy.srp(arp_request_broadcast,timeout=1,verbose=False)[0] #send the packet and store the response in a list
return answered_list #return the response
The get_mac_vendor
function is defined to take in the MAC address of a device and return its vendor. The function first formats the MAC address by converting it to upper case and removing the colons. It then opens the mac-vendor.txt
file and searches for the MAC address in each line of the file. If the MAC address is found, the function returns the vendor name from the line. If the MAC address is not found, the function returns ‘Unknown’.
#define the function to get the vendor of the given mac address
def get_mac_vendor(mac):
mac = mac.upper().replace(':','')[0:6] #convert the mac address to upper case, remove the colons and get the first 6 characters
with open("mac-vendor.txt","r") as f: #open the 'mac-vendor.txt' file in read mode
for line in f : #iterate through the lines in the file
if mac in line: #if the mac address is in the line
return line[7:] #return the vendor name from the line
return 'Unknown' #if the mac address is not found in the file, return 'Unknown'
The main
function is defined as the entry point of the script. It creates a new ArgumentParser
object and adds a required command line argument network
of type string. The function then parses the command line arguments, scans the network using the scan
function, and iterates through the list of hosts returned by the scan
function. For each host, the function gets the vendor using the get_mac_vendor
function and prints the IP address, MAC address and vendor of the host.
#define the main function
def main():
parser = argparse.ArgumentParser() #create a new ArgumentParser object
parser.add_argument('-n','--network', type=str, required=True) #add a new argument 'network' which is required and is a string
args = parser.parse_args() #parse the command line arguments
hosts = scan(args.network) #scan the network and get the response
for host in hosts: #iterate through the hosts in the response
mac_vendor = get_mac_vendor(host[1].src).strip() #get the vendor of the host
print(host[0].pdst + 2*'\t' + host[1].src + 2*'\t' + mac_vendor) #print the ip address, mac address and vendor of the host
Conclusion
A good understanding of ARP is necessary of every hacker/penetration tester interested in network hacking. It is used to conduct MITM attacks to intercept network traffic and perform even more sophisticated attacks.
Full code is available on github.
HAPPY HACKING.