Introduction

This tutorial servies two purposes.

  • We are to understand IPv4 ARP via hands-on packet crafting experiments
  • We need this to realize part of TCP protocol via packet crafting

There are two methods to add (or to spoof) a host.

  • Add a static entry to a host’s ARP table
  • Reply to ARP request

Adding Static ARP Entry

We can add a static ARP entry via the arp command (Linux now considers it deprecated) or via the ip neighbor command . Below is an example of using arp

sudo arp -s 10.1.1.3 08:00:27:08:0d:a1

Replying to ARP Request

The following program reply to ARP request, as such, it acts as an neighbor.

#
# arpphantom.py 
#
import signal
import sys

from scapy.sendrecv import sendp
from scapy.sendrecv import sniff
from scapy.layers.l2 import ARP

def gracefully_exit(sig, frame):
    print("Ctrl-C pressed. Exiting ...")
    sys.exit(0)

def usage(prog):
    # python arpphantom.py 10.1.1.3 08:00:27:08:0d:a1 enp0s9
    print("Usage: prog PHANTOM_HOST_IP PHANTOM_HW_ADDR NIC")

def main(argv):
    signal.signal(signal.SIGINT, gracefully_exit)
    if len(argv) < 4: 
        usage(argv[0])
        sys.exit(1)
    # host = '10.1.1.3'
    # nic = 'enp0s9'
    # hwaddr = '08:00:27:08:0d:a1'
    host = argv[1]
    hwaddr = argv[2]
    nic = argv[3]
    filter = 'arp dst host ' + host
    while True: 
        packets = sniff(filter=filter, count=1)
        arppkt = packets[0]
        arppkt.dst = arppkt.src
        arppkt.src = hwaddr
        arppkt.op = 2
        arppkt.hwdst = hwaddr
        arppkt.psrc = packets[0].pdst
        arppkt.hwsrc = packets[0].hwdst
        arppkt.hwdst = packets[0].hwsrc
        arppkt.pdst = packets[0].psrc
        sendp(arppkt, iface=nic, verbose=0)
        print(arppkt.summary())

if __name__ == "__main__":
    main(sys.argv)