Created
January 11, 2018 10:42
-
-
Save SupraJames/779475fefb6dfe7af315a68f03fe63dd to your computer and use it in GitHub Desktop.
ARP responder using Python / scapy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Horrible bodge for when ESP82xx devices are not responding to ARP requests any more. | |
# This script can run anywhere on the subnet. It listens for ARP requests and responds | |
# with the MAC address in macDict based on the IP address. | |
# | |
# Note that it will ONLY respond if the IP address is found in macDict below. | |
# | |
# Please be careful with this tool. If wrongly configured, network breakage could occur. | |
# | |
# Requires scapy (pip install scapy) and tcpdump. Running tcpdump usually requires root | |
# so this script will need to be run as root. | |
# | |
# TODO: It would be great if the script could be improved to only send a response if we do | |
# not see a response on the wire within a second or so. At the moment we are blindy assuming | |
# that the ARP response is not coming. This will involve a lot more logic to keep track of what | |
# ARP requests have come in, and if they have been answered or not. | |
from __future__ import print_function | |
from scapy.all import * | |
import time | |
# Your network broadcast address | |
broadcastNet = "192.168.100.255" | |
macDict = { "192.168.100.152" : "60:01:94:98:97:c6", | |
"192.168.100.149" : "68:c6:3a:a7:d3:40"} | |
# Use MAC address of this machine as source. If not eth0, change this: | |
myMAC = get_if_hwaddr('eth0') | |
def handle_packet(packet): | |
if packet[ARP].op == ARP.who_has: | |
#print("Someone is asking about " + packet.pdst) | |
#print(packet.summary()) | |
if packet.pdst in macDict: | |
print("Sending ARP response for " + packet.pdst) | |
reply = ARP(op=ARP.is_at, hwsrc=macDict[packet.pdst], psrc=packet.pdst, hwdst="ff:ff:ff:ff:ff:ff", pdst=broadcastNet) | |
go = Ether(dst="ff:ff:ff:ff:ff:ff", src=myMAC) / reply | |
sendp(go) | |
return | |
# Sniff for ARP packets. Run handle_packet() on each one | |
sniff(filter="arp",prn=handle_packet) |
Hi, thanks for the script. I do get this error though:
Traceback (most recent call last):
File "macfix.py", line 42, in <module>
sniff(filter="arp",prn=handle_packet)
File "/home/ps/.local/lib/python2.7/site-packages/scapy/sendrecv.py", line 1036, in sniff
sniffer._run(*args, **kwargs)
File "/home/ps/.local/lib/python2.7/site-packages/scapy/sendrecv.py", line 989, in _run
session.on_packet_received(p)
File "/home/ps/.local/lib/python2.7/site-packages/scapy/sessions.py", line 82, in on_packet_received
result = self.prn(pkt)
File "macfix.py", line 30, in handle_packet
if packet[ARP].op == ARP.who_has:
File "/home/ps/.local/lib/python2.7/site-packages/scapy/base_classes.py", line 254, in __getattr__
raise AttributeError(attr)
AttributeError: who_has
Maybe who_has
is not correct in recent tcp-dump?
Quick update, it seems to work with this fix: 'who-has'
instead if ARP.who_has
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have tried this and am getting the following error:
root@hass:/usr/local/bin# python2 arp_responder.py Traceback (most recent call last): File "arp_responder.py", line 43, in <module> sniff(filter="arp",prn=handle_packet,store=0) File "/usr/local/lib/python2.7/dist-packages/scapy/sendrecv.py", line 620, in sniff r = prn(p) File "arp_responder.py", line 31, in handle_packet if packet[ARP].op == ARP.who_has: File "/usr/local/lib/python2.7/dist-packages/scapy/packet.py", line 817, in __getitem__ raise IndexError("Layer [%s] not found" % lname) IndexError: Layer [ARP] not found
Do you have any ideas what might be causing this error?
Fixed the problem (posted here for others)
$ sudo apt-get install tcpdump tcpreplay wireshark