diff options
Diffstat (limited to 'crafted-pkt')
-rwxr-xr-x | crafted-pkt/badsegments.py | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/crafted-pkt/badsegments.py b/crafted-pkt/badsegments.py new file mode 100755 index 0000000..73f26f3 --- /dev/null +++ b/crafted-pkt/badsegments.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# Create a crafted TCP stream with overlapping and retransmitted segments +# Usage: badsegments.py [output.pcap] + +import sys +from scapy.all import * + + +def make_tcp(server=None, flags=None, data=b'', datalen=0, **kwargs): + assert type(server) == bool + assert len(data) == datalen + if not flags: + flags = 'A' + kwargs['seq' if server else 'ack'] += 0x44332211 + kwargs['ack' if server else 'seq'] += 0x88776655 + if 'A' not in flags: + kwargs['ack'] = 0 + if server: + tcp = TCP(flags=flags, sport=80, dport=32323, **kwargs) + tcpip = IP(dst='10.0.0.1', src='10.0.0.2') / tcp + else: + tcp = TCP(flags=flags, sport=32323, dport=80, **kwargs) + tcpip = IP(dst='10.0.0.2', src='10.0.0.1') / tcp + return tcpip / data + +s = lambda **kwargs: make_tcp(server=True, **kwargs) +c = lambda **kwargs: make_tcp(server=False, **kwargs) + +pkts = [] +# Cases: +# 1. two sequential segments +# 2. out-of-order (swapped two sequential segments) +# 3. Bad overlap (second overlap with different data should be ignored) +# 4. Ignore bad retransmitted data, but extend with remaining data. +# 5. Check handling of overlapping data while fragments are incomplete +# (out-of-order - cannot add fragments to stream) +# 6. lost but acked segments +# 7. lost 3/5 fragments, but acked +# TODO lost and not acked (currently truncated, is that OK?) + +bad = len(sys.argv) <= 2 or sys.argv[2] != 'ok' + +pkts += [ +c(seq=0, ack=0, flags='S'), +s(seq=0, ack=1, flags='SA'), +c(seq=1, ack=1, flags='A'), + +# 1. two sequential segments +c(seq=1, ack=1, data=b'GET / HTTP/1.1\r\n', datalen=16), +c(seq=17, ack=1, data=b'Host:localhost\r\n', datalen=16), +] + +pkts += [ +# 2. out-of-order (swapped two sequential segments) +c(seq=33, ack=1, data=b'X-Swapped: 1st\r\n', datalen=16), +c(seq=49, ack=1, data=b'X-Swapped: 2nd\r\n', datalen=16), +][::-1 if bad else 1] +pkts += [ +s(seq=1, ack=65), +] + +pkts += [ +# 3. Bad overlap (second overlap with different data should be ignored) +c(seq=65, ack=1, data=b'X-Overlap-Packet', datalen=16), +c(seq=65, ack=1, data=b'X-Overlap-IGNORE', datalen=16), +][:2 if bad else 1] + +pkts += [ +# 4. Ignore bad retransmitted data, but extend with remaining data. +c(seq=65, ack=1, data=b'X-BADOVERLAPHEAD: extra data--\r\n', datalen=32), +s(seq=1, ack=97), +] + +# 5. Check handling of overlapping data while fragments are incomplete +# (out-of-order - cannot add fragments to stream) +pkts += [ +c(seq=113, ack=1, data=b'his is delayed\r\n', datalen=16), +c(seq=161, ack=1, data=b'X-OoO-Overlap3:e', datalen=16), +c(seq=161, ack=1, data=b'X-OoO-Overlap3:extend fragment\r\n', datalen=32), +c(seq=97, ack=1, data=b'X-OoO-Overlap: t', datalen=16), +c(seq=129, ack=1, data=b'X-OoO-Overlap2: second delayed\r\n', datalen=32), +] + +pkts += [ +# 6. lost but acked segments +c(seq=193, ack=1, data=b'Cookie: value=1234567890abcdef\r\n', datalen=32), +c(seq=225, ack=1, data=b'X-Missing-But-Acked-Previous:1\r\n', datalen=32), +s(seq=1, ack=257), +][1 if bad else 0:] + +pkts += [ +# 7. lost 3/5 fragments, but acked +c(seq=257, ack=1, data=b'X-IGNORED-ANYWAY: wjedgfjrsfdg\r\n', datalen=32), +c(seq=287, ack=1, data=b'\r', datalen=1), +c(seq=273, ack=1, data=b':', datalen=1), +c(seq=289, ack=1, data=b'X-Missing-3-Out-Of-5-But-ACK:Y\r\n', datalen=32), +s(seq=1, ack=321), +][1 if bad else 0:] + +pkts += [ +c(seq=321, ack=1, data=b'\r\n', datalen=2), +s(seq=1, ack=323), +] + +# Show packets and write to file +for i, pkt in enumerate(pkts): + pkt.time = i * 0.000001 + print(pkt.summary()) +if len(sys.argv) > 1: + wrpcap(sys.argv[1], pkts) |