Get a head start on your coding projects with our Python Code Generator. Perfect for those times when you need a quick solution. Don't wait, try it today!
In the previous tutorial, we built an ARP spoof script using Scapy that once it is established correctly, any traffic meant for the target host will be sent to the attacker's host. Now, you are maybe wondering, how can we detect these kinds of attacks? well, that's what we are going to do in this tutorial.
The basic idea behind the script that we're going to build is to keep sniffing packets (passive monitoring or scanning) in the network. Once an ARP packet is received, we analyze two components:
And then, we compare the two. If they are not the same, then we are definitely under an ARP spoof attack!
Get: Build 24 Ethical Hacking Scripts & Tools with Python Book
First, let's import what we gonna need (you need to install Scapy first, head to this tutorial or the official Scapy documentation for installation):
from scapy.all import Ether, ARP, srp, sniff, conf
Then we need a function that given an IP address, it makes an ARP request and retrieves the real MAC address the that IP address:
def get_mac(ip):
"""
Returns the MAC address of `ip`, if it is unable to find it
for some reason, throws `IndexError`
"""
p = Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip)
result = srp(p, timeout=3, verbose=False)[0]
return result[0][1].hwsrc
Related: Build 24 Ethical Hacking Scripts & Tools with Python Book
After that, the sniff() function that we gonna use, takes a callback (or function) to apply to each packet sniffed, let's define it:
def process(packet):
# if the packet is an ARP packet
if packet.haslayer(ARP):
# if it is an ARP response (ARP reply)
if packet[ARP].op == 2:
try:
# get the real MAC address of the sender
real_mac = get_mac(packet[ARP].psrc)
# get the MAC address from the packet sent to us
response_mac = packet[ARP].hwsrc
# if they're different, definitely there is an attack
if real_mac != response_mac:
print(f"[!] You are under attack, REAL-MAC: {real_mac.upper()}, FAKE-MAC: {response_mac.upper()}")
except IndexError:
# unable to find the real mac
# may be a fake IP or firewall is blocking packets
pass
Note: Scapy encodes the type of ARP packet in a field called "op" which stands for operation, by default the "op" is 1 or "who-has" which is an ARP request, and 2 or "is-at" is an ARP reply.
As you may see, the above function checks for ARP packets. More precisely, ARP replies, and then compares between the real MAC address and the response MAC address (that's sent in the packet itself).
All we need to do now is to call the sniff() function with the callback written above:
sniff(store=False, prn=process)
Note: store=False tells sniff() function to discard sniffed packets instead of storing them in memory, this is useful when the script runs for a very long time.
When you try to run the script, nothing will happen obviously, but when an attacker tries to spoof your ARP cache like in the figure shown below:
The ARP spoof detector (which ran on another machine, obviously) will automatically respond:
Alright, that's it!
To prevent such man-in-the-middle attacks, you need to use Dynamic ARP Inspection, which is a security feature that automatically rejects malicious ARP packets we just detected.
Here are some further readings:
Check the full code.
Finally, we have an Ethical Hacking with Python Ebook, where we build 24 hacking tools and scripts! Make sure to check it out if you're interested.
Happy Crafting ♥
Take the stress out of learning Python. Meet our Python Code Assistant – your new coding buddy. Give it a whirl!
View Full Code Generate Python Code
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!