1e35cfc60SAlan Somers#! /usr/bin/env python3 2e35cfc60SAlan Somers# Used to inject various malformed packets 3e35cfc60SAlan Somers 4e35cfc60SAlan Somersimport errno 5e35cfc60SAlan Somersimport logging 6e35cfc60SAlan Somersimport subprocess 7e35cfc60SAlan Somersimport sys 8e35cfc60SAlan Somers 9e35cfc60SAlan Somerslogging.getLogger("scapy").setLevel(logging.CRITICAL) 10e35cfc60SAlan Somers 11e35cfc60SAlan Somersfrom scapy.all import IP, ICMP, IPOption 12e35cfc60SAlan Somersimport scapy.layers.all 13e35cfc60SAlan Somersfrom scapy.layers.inet import ICMPEcho_am 14e35cfc60SAlan Somersfrom scapy.layers.tuntap import TunTapInterface 15e35cfc60SAlan Somers 16e35cfc60SAlan SomersSRC_ADDR = "192.0.2.14" 17e35cfc60SAlan SomersDST_ADDR = "192.0.2.15" 18e35cfc60SAlan Somers 19e35cfc60SAlan Somersmode = sys.argv[1] 20e35cfc60SAlan Somersip = None 21e35cfc60SAlan Somers 22e35cfc60SAlan Somers# fill opts with nop (0x01) 23e35cfc60SAlan Somersopts = b'' 24e35cfc60SAlan Somersfor x in range(40): 25e35cfc60SAlan Somers opts += b'\x01' 26e35cfc60SAlan Somers 27e35cfc60SAlan Somers 28e35cfc60SAlan Somers# Create and configure a tun interface with an RFC5737 nonrouteable address 29e35cfc60SAlan Somerscreate_proc = subprocess.run( 30e35cfc60SAlan Somers args=["ifconfig", "tun", "create"], 31e35cfc60SAlan Somers capture_output=True, 32e35cfc60SAlan Somers check=True, 33e35cfc60SAlan Somers text=True) 34e35cfc60SAlan Somersiface = create_proc.stdout.strip() 35e35cfc60SAlan Somerstun = TunTapInterface(iface) 36e35cfc60SAlan Somerswith open("tun.txt", "w") as f: 37e35cfc60SAlan Somers f.write(iface) 38e35cfc60SAlan Somerssubprocess.run(["ifconfig", tun.iface, "up"]) 39e35cfc60SAlan Somerssubprocess.run(["ifconfig", tun.iface, SRC_ADDR, DST_ADDR]) 40e35cfc60SAlan Somers 41e35cfc60SAlan Somersping = subprocess.Popen( 42e35cfc60SAlan Somers args=["/sbin/ping", "-v", "-c1", "-t1", DST_ADDR], 43e35cfc60SAlan Somers text=True 44e35cfc60SAlan Somers) 45e35cfc60SAlan Somers# Wait for /sbin/ping to ping us 46e35cfc60SAlan Somersecho_req = tun.recv() 47e35cfc60SAlan Somers 48e35cfc60SAlan Somers# Construct the response packet 49e35cfc60SAlan Somersif mode == "opts": 50e35cfc60SAlan Somers # Sending reply with IP options 51e35cfc60SAlan Somers echo_reply = IP( 52e35cfc60SAlan Somers dst=SRC_ADDR, 53e35cfc60SAlan Somers src=DST_ADDR, 54e35cfc60SAlan Somers options=IPOption(opts) 55e35cfc60SAlan Somers )/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload 56e35cfc60SAlan Somerselif mode == "pip": 57e35cfc60SAlan Somers # packet in packet (inner has options) 58e35cfc60SAlan Somers 59e35cfc60SAlan Somers inner = IP( 60e35cfc60SAlan Somers dst=SRC_ADDR, 61e35cfc60SAlan Somers src=DST_ADDR, 62e35cfc60SAlan Somers options=IPOption(opts) 63e35cfc60SAlan Somers )/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload 64e35cfc60SAlan Somers outer = IP( 65e35cfc60SAlan Somers dst=SRC_ADDR, 66e35cfc60SAlan Somers src=DST_ADDR 67e35cfc60SAlan Somers )/ICMP(type=3, code=1) # host unreach 68e35cfc60SAlan Somers 69e35cfc60SAlan Somers echo_reply = outer/inner 70e35cfc60SAlan Somerselif mode == "reply": 71e35cfc60SAlan Somers # Sending normal echo reply 72e35cfc60SAlan Somers echo_reply = IP( 73e35cfc60SAlan Somers dst=SRC_ADDR, 74e35cfc60SAlan Somers src=DST_ADDR, 75e35cfc60SAlan Somers )/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload 76e35cfc60SAlan Somerselse: 77e35cfc60SAlan Somers print("unknown mode {}".format(mode)) 78e35cfc60SAlan Somers exit(1) 79e35cfc60SAlan Somers 80e35cfc60SAlan Somerstun.send(echo_reply) 81e35cfc60SAlan Somersouts, errs = ping.communicate() 82e35cfc60SAlan Somers 83e35cfc60SAlan Somerssys.exit(ping.returncode) 84