Add overlapping segmentation

This commit is contained in:
George Hughey 2019-12-15 17:21:17 -08:00
parent fdac0dfb25
commit 61acc0970d
2 changed files with 103 additions and 10 deletions

View File

@ -107,7 +107,7 @@ class FragmentAction(Action):
# Craft new packets
# Make sure we don't go out of bounds by choosing the min
overlapBytes = min(payload[fragsize:], overlap)
overlapBytes = min(len(payload[fragsize:]), self.overlap)
# Attach these bytes to the first packet
pkt1 = IP(packet["IP"])/payload[:fragsize + overlapBytes]
pkt2 = IP(packet["IP"])/payload[fragsize:]
@ -155,10 +155,15 @@ class FragmentAction(Action):
Returns a string representation with the fragsize
"""
s = Action.__str__(self)
if self.segment:
s += "{" + "tcp" + ":" + str(self.fragsize) + ":" + str(self.correct_order) + "}"
if self.overlap == 0:
ending = "}"
else:
s += "{" + "ip" + ":"+ str(self.fragsize) + ":" + str(self.correct_order) + "}"
ending = ":" + str(self.overlap) + "}"
if self.segment:
s += "{" + "tcp" + ":" + str(self.fragsize) + ":" + str(self.correct_order) + ending
else:
s += "{" + "ip" + ":"+ str(self.fragsize) + ":" + str(self.correct_order) + ending
return s
def parse(self, string, logger):
@ -177,22 +182,36 @@ class FragmentAction(Action):
num_parameters = string.count(":")
# If num_parameters is greater than 2, it's not a valid fragment action
if num_parameters != 2:
msg = "Cannot parse fragment action %s" % string
logger.error(msg)
raise Exception(msg)
else:
if num_parameters == 2:
params = string.split(":")
seg, fragsize, correct_order = params
overlap = 0
if "tcp" in seg:
self.segment = True
else:
self.segment = False
elif num_parameters == 3:
params = string.split(":")
seg, fragsize, correct_order, overlap = params
if overlap.endswith("}"):
overlap = overlap[:-1] # Chop off trailing }
if "tcp" in seg:
self.segment = True
else:
self.segment = False
else:
msg = "Cannot parse fragment action %s" % string
logger.error(msg)
raise Exception(msg)
try:
# Try to convert to int
self.fragsize = int(fragsize)
except ValueError:
self.overlap = int(overlap)
except ValueError as e:
print(e)
msg = "Cannot parse fragment action %s" % string
logger.error(msg)
raise Exception(msg)

View File

@ -217,4 +217,78 @@ def test_ip_only_fragment():
assert packet1["Raw"].load == b'datadata', "Left packet incorrectly fragmented"
assert packet2["Raw"].load == b"11datadata", "Right packet incorrectly fragmented"
def test_overlapping_segment():
"""
Basic test for overlapping segments.
"""
fragment = actions.fragment.FragmentAction(correct_order=True)
fragment.parse("fragment{tcp:-1:True:4}", logger)
packet = actions.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(seq=100)/("datadata11datadata"))
packet1, packet2 = fragment.run(packet, logger)
assert id(packet1) != id(packet2), "Duplicate aliased packet objects"
assert packet1["Raw"].load != packet2["Raw"].load, "Packets were not different"
assert packet1["Raw"].load == b'datadata11dat', "Left packet incorrectly segmented"
assert packet2["Raw"].load == b"1datadata", "Right packet incorrectly fragmented"
assert packet1["TCP"].seq == 100, "First packet sequence number incorrect"
assert packet2["TCP"].seq == 109, "Second packet sequence number incorrect"
def test_overlapping_segment_no_overlap():
"""
Basic test for overlapping segments with no overlap. (shouldn't ever actually happen)
"""
fragment = actions.fragment.FragmentAction(correct_order=True)
fragment.parse("fragment{tcp:-1:True:0}", logger)
packet = actions.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(seq=100)/("datadata11datadata"))
packet1, packet2 = fragment.run(packet, logger)
assert id(packet1) != id(packet2), "Duplicate aliased packet objects"
assert packet1["Raw"].load != packet2["Raw"].load, "Packets were not different"
assert packet1["Raw"].load == b'datadata1', "Left packet incorrectly segmented"
assert packet2["Raw"].load == b"1datadata", "Right packet incorrectly fragmented"
assert packet1["TCP"].seq == 100, "First packet sequence number incorrect"
assert packet2["TCP"].seq == 109, "Second packet sequence number incorrect"
def test_overlapping_segment_entire_packet():
"""
Basic test for overlapping segments overlapping entire packet.
"""
fragment = actions.fragment.FragmentAction(correct_order=True)
fragment.parse("fragment{tcp:-1:True:9}", logger)
packet = actions.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(seq=100)/("datadata11datadata"))
packet1, packet2 = fragment.run(packet, logger)
assert id(packet1) != id(packet2), "Duplicate aliased packet objects"
assert packet1["Raw"].load != packet2["Raw"].load, "Packets were not different"
assert packet1["Raw"].load == b'datadata11datadata', "Left packet incorrectly segmented"
assert packet2["Raw"].load == b"1datadata", "Right packet incorrectly fragmented"
assert packet1["TCP"].seq == 100, "First packet sequence number incorrect"
assert packet2["TCP"].seq == 109, "Second packet sequence number incorrect"
def test_overlapping_segment_out_of_bounds():
"""
Basic test for overlapping segments overlapping beyond the edge of the packet.
"""
fragment = actions.fragment.FragmentAction(correct_order=True)
fragment.parse("fragment{tcp:-1:True:20}", logger)
packet = actions.packet.Packet(IP(src="127.0.0.1", dst="127.0.0.1")/TCP(seq=100)/("datadata11datadata"))
packet1, packet2 = fragment.run(packet, logger)
assert id(packet1) != id(packet2), "Duplicate aliased packet objects"
assert packet1["Raw"].load != packet2["Raw"].load, "Packets were not different"
assert packet1["Raw"].load == b'datadata11datadata', "Left packet incorrectly segmented"
assert packet2["Raw"].load == b"1datadata", "Right packet incorrectly fragmented"
assert packet1["TCP"].seq == 100, "First packet sequence number incorrect"
assert packet2["TCP"].seq == 109, "Second packet sequence number incorrect"