def test_random_tamper_options(logger): """ Tests tampering a given option with a random value (corrupt) """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None, field="options-mss", tamper_type="corrupt") lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][0] == "MSS" if lpacket["TCP"].options[0][1] == 3453: lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][1] != 3453
def test_mutate(logger, use_canary): """ Tests the tamper 'replace' primitive. """ logger.setLevel("ERROR") canary_id = None # Create an evaluator if use_canary: cmd = [ "--test-type", "echo", "--censor", "censor2", "--log", actions.utils.CONSOLE_LOG_LEVEL, "--no-skip-empty", "--bad-word", "facebook", "--output-directory", actions.utils.RUN_DIRECTORY ] tester = evaluator.Evaluator(cmd, logger) canary_id = evolve.run_collection_phase(logger, tester) for _ in range(0, 25): tamper = actions.tamper.TamperAction(None, field="flags", tamper_type="replace", tamper_value="R", tamper_proto="TCP") # Test mutation 200 times to ensure it remains stable for _ in range(0, 200): tamper._mutate(canary_id) tamper2 = actions.tamper.TamperAction(None) # Confirm tamper value was properly ._fix()-ed val = tamper.tamper_value for _ in range(0, 5): assert tamper.tamper_value == val, "Tamper value is not stable." # Create a test packet to ensure the field/proto choice was safe if random.random() < 0.5: test_packet = layers.packet.Packet(IP() / TCP()) else: test_packet = layers.packet.Packet(IP() / UDP()) # Check that tamper can run safely after mutation try: tamper.run(test_packet, logger) except: print(str(tamper)) raise tamper._mutate_tamper_type() # Test that parsing tamper works - note we have to remove the tamper{} to make a call directly using tamper's parse. tamper2.parse(str(tamper)[7:-1], logger) assert str(tamper2) == str(tamper)
def test_tamper_udp(logger): """ Tests tampering with UDP """ packet = layers.packet.Packet( IP(src='127.0.0.1', dst='127.0.0.1') / UDP(sport=2222, dport=53)) original = copy.deepcopy(packet) tamper = actions.tamper.TamperAction(None, field="chksum", tamper_type="replace", tamper_value=4444, tamper_proto="UDP") lpacket, rpacket = tamper.run(packet, logger) assert not rpacket, "Tamper must not return right child" assert lpacket, "Tamper must give a left child" assert id(lpacket) == id(packet), "Tamper must edit in place" # Confirm tamper replaced the field it was supposed to assert packet[UDP].chksum == 4444, "Tamper did not replace flags." # Confirm tamper didn't corrupt anything in the TCP header assert confirm_unchanged(packet, original, UDP, ["chksum"]) # Confirm tamper didn't corrupt anything else in the IP header assert confirm_unchanged(packet, original, IP, [])
def test_tamper_ip(logger): """ Tests tampering with IP """ packet = layers.packet.Packet( IP(src='127.0.0.1', dst='127.0.0.1') / TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")) original = copy.deepcopy(packet) tamper = actions.tamper.TamperAction(None, field="src", tamper_type="replace", tamper_value="192.168.1.1", tamper_proto="IP") lpacket, rpacket = tamper.run(packet, logger) assert not rpacket, "Tamper must not return right child" assert lpacket, "Tamper must give a left child" assert id(lpacket) == id(packet), "Tamper must edit in place" # Confirm tamper replaced the field it was supposed to assert packet[IP].src == "192.168.1.1", "Tamper did not replace flags." # Confirm tamper didn't corrupt anything in the TCP header assert confirm_unchanged(packet, original, TCP, []) # Confirm tamper didn't corrupt anything else in the IP header assert confirm_unchanged(packet, original, IP, ["src"])
def test_tamper(logger): """ Tests tampering with replace """ packet = layers.packet.Packet( IP(src="127.0.0.1", dst="127.0.0.1") / TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")) original = copy.deepcopy(packet) tamper = actions.tamper.TamperAction(None, field="flags", tamper_type="replace", tamper_value="R") lpacket, rpacket = tamper.run(packet, logger) assert not rpacket, "Tamper must not return right child" assert lpacket, "Tamper must give a left child" assert id(lpacket) == id(packet), "Tamper must edit in place" # Confirm tamper replaced the field it was supposed to assert packet[TCP].flags == "R", "Tamper did not replace flags." new_value = packet[TCP].flags # Must run this check repeatedly - if a scapy fuzz-ed value is not properly # ._fix()-ed, it will return different values each time it's requested for _ in range(0, 5): assert packet[TCP].flags == new_value, "Replaced value is not stable" # Confirm tamper didn't corrupt anything else in the TCP header assert confirm_unchanged(packet, original, TCP, ["flags"]) # Confirm tamper didn't corrupt anything in the IP header assert confirm_unchanged(packet, original, IP, [])
def test_tamper_ip_ident(): """ Tests tampering with IP and that the checksum is correctly changed """ packet = actions.packet.Packet( IP(src='127.0.0.1', dst='127.0.0.1') / TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")) original = copy.deepcopy(packet) tamper = actions.tamper.TamperAction(None, field='id', tamper_type='replace', tamper_value=3333, tamper_proto="IP") lpacket, rpacket = tamper.run(packet, logger) assert not rpacket, "Tamper must not return right child" assert lpacket, "Tamper must give a left child" assert id(lpacket) == id(packet), "Tamper must edit in place" # Confirm tamper replaced the field it was supposed to assert packet[IP].id == 3333, "Tamper did not replace flags." # Confirm tamper didn't corrupt anything in the TCP header assert confirm_unchanged(packet, original, TCP, []) # Confirm tamper didn't corrupt anything else in the IP header assert confirm_unchanged(packet, original, IP, ["id"])
def test_md5options(logger): """ Tests appending a given option - the md5header """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None, field="options-md5header", tamper_value=b'\xee\xee\xee\xee\xee\xee\xee\xee', tamper_type="replace") lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options == [(19, b'\xee\xee\xee\xee\xee\xee\xee\xee')]
def test_tamper_options(logger): """ Tests tampering a given option with a given value """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None, field="options-timestamp", tamper_type="replace", tamper_value=3433) lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][0] == "Timestamp" assert lpacket["TCP"].options[0][1] == (3433, 0)
def test_append_random_options(logger): """ Tests appending a given option with a random value """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None, field="options-mss", tamper_type="corrupt") lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][0] == 'MSS' assert len(lpacket["TCP"].options[0]) == 2
def test_append_options(logger): """ Tests appending a given option """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(tamper_proto="TCP", field="options-wscale", tamper_value=50, tamper_type="replace") lpacket, rpacket = tamper.run(packet, logger) lpacket.show() assert lpacket["TCP"].options == [("WScale", 50)]
def test_options(logger, value, test_type): """ Tests tampering options """ if test_type == "direct": tamper = actions.tamper.TamperAction(None, field="options-%s" % value.lower(), tamper_type="corrupt", tamper_value=bytes([12])) else: tamper = actions.tamper.TamperAction(None) assert tamper.parse("TCP:options-%s:corrupt" % value.lower(), logger) packet = layers.packet.Packet( IP(src="127.0.0.1", dst="127.0.0.1") / TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")) tamper.run(packet, logger) opts_dict_lookup = value.lower().replace(" ", "_") for optname, optval in packet["TCP"].options: if optname == value: break elif optname == layers.ip_layer.TCPLayer.options_names[ opts_dict_lookup]: break else: pytest.fail("Failed to find %s in options" % value) assert len(packet["TCP"].options) == 1 raw_p = bytes(packet) assert raw_p, "options broke scapy bytes" p2 = layers.packet.Packet(IP(bytes(raw_p))) assert p2.haslayer("IP") assert p2.haslayer("TCP") # EOLs might be added for padding, so just check >= 1 assert len(p2["TCP"].options) >= 1 for optname, optval in p2["TCP"].options: if optname == value: break elif optname == layers.ip_layer.TCPLayer.options_names[ opts_dict_lookup]: break else: pytest.fail("Failed to find %s in options" % value)
def test_parse_num(logger): """ Tests parsing integers """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None, tamper_type="options") assert tamper.parse("TCP:options-mss:replace:1440", logger) lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][1] == 1440
def test_parse_run(logger): """ Tests the ability to parse """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None) assert tamper.parse("TCP:options-mss:corrupt", logger) lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][1] != 0
def test_correct_assignment(logger): """ Tests that all options can be assigned """ for option in layers.tcp_layer.TCPLayer.scapy_options.values(): print(option) packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None, field="options-" + str(option.lower()), tamper_type="corrupt") lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][0] == option
def test_option_1(logger): """ Tests option 1 """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None, tamper_type="options") assert tamper.parse("TCP:options-nop:corrupt", logger) lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][1] == ()
def test_option_8(logger): """ Tests options 7 """ packet = layers.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(sport=2222, dport=3333, seq=100, ack=100, flags="S")/("data")) tamper = actions.tamper.TamperAction(None) assert tamper.parse("TCP:options-timestamp:replace:40000", logger) lpacket, rpacket = tamper.run(packet, logger) assert lpacket["TCP"].options[0][1] == (40000, 0)