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