From a2a17dd370d597b35f848fca8198bfeca3bf18c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20De=20Keersmaeker?= <francois.dekeersmaeker@uclouvain.be> Date: Thu, 8 Jun 2023 10:10:02 +0200 Subject: [PATCH] Payload hash: first pad payload to min Ethernet payload length (46 bytes) --- src/packet/Packet.py | 37 ++++++++++++++++++++++++++++++++++--- src/pcap_tweaker.py | 29 ++--------------------------- traces/arp-2.pcap | Bin 0 -> 140 bytes traces/http.pcap | Bin 1426 -> 1402 bytes 4 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 traces/arp-2.pcap diff --git a/src/packet/Packet.py b/src/packet/Packet.py index e107794..43f9064 100644 --- a/src/packet/Packet.py +++ b/src/packet/Packet.py @@ -8,14 +8,19 @@ from ipaddress import IPv4Address, IPv6Address import scapy.all as scapy import hashlib + class Packet: """ Wrapper around the Scapy `Packet` class. """ + ##### CLASS VARIABLES ##### + # List of all alphanumerical characters ALPHANUM_CHARS = list(string.ascii_letters + string.digits) ALPHANUM_BYTES = list(bytes(string.ascii_letters + string.digits, "utf-8")) + # Minimun payload length (in bytes) + MIN_PAYLOAD_LENGTH = 46 # Protocol name correspondences protocols = { @@ -26,6 +31,10 @@ class Packet: fields = {} + + ##### STATIC METHODS ##### + + @staticmethod def string_edit_char(s: str) -> str: """ @@ -97,6 +106,21 @@ class Packet: return i - 1 + @staticmethod + def rebuild_packet(packet: scapy.Packet) -> scapy.Packet: + """ + Rebuild a Scapy packet from its bytes representation, + but keep its old timestamp. + + :param packet: Scapy packet + :return: Rebuilt Scapy packet, with old timestamp + """ + timestamp = packet.time + new_packet = packet.__class__(bytes(packet)) + new_packet.time = timestamp + return new_packet + + @classmethod def init_packet(c, packet: scapy.Packet, id: int = 0, last_layer_index: int = -1) -> Packet: """ @@ -135,6 +159,10 @@ class Packet: continue # No supported protocol found, raise ValueError raise ValueError(f"No supported protocol found for packet: {packet.summary()}") + + + + ##### INSTANCE METHODS ##### def __init__(self, packet: scapy.Packet, id: int = 0, last_layer_index: int = -1) -> None: @@ -193,11 +221,14 @@ class Packet: def get_hash(self) -> str: """ - Get packet hash. + Get packet payload SHA256 hash. + The payload is first padded with null bytes to reach the minimum Ethernet payload length of 46 bytes. - :return: Packet hash. + :return: Packet payload SHA256 hash. """ - return hashlib.sha256(bytes(self.packet)).hexdigest() + pad_bytes_to_add = Packet.MIN_PAYLOAD_LENGTH - len(self.packet.payload) + payload = bytes(self.packet.payload) + bytes(pad_bytes_to_add) if pad_bytes_to_add > 0 else bytes(self.packet.payload) + return hashlib.sha256(payload).hexdigest() def rebuild(self) -> None: diff --git a/src/pcap_tweaker.py b/src/pcap_tweaker.py index aaacadf..faf29f5 100644 --- a/src/pcap_tweaker.py +++ b/src/pcap_tweaker.py @@ -10,7 +10,6 @@ import csv import scapy.all as scapy from scapy.layers import dhcp, dns, http from scapy.contrib import coap, igmp, igmpv3 -import hashlib from packet.Packet import Packet @@ -46,30 +45,6 @@ def must_edit_packet(i: int, packet_numbers: list, random_range: int) -> bool: return is_specified or is_random -def rebuild_packet(packet: scapy.Packet) -> scapy.Packet: - """ - Rebuild a Scapy packet from its bytes representation, - but keep its old timestamp. - - :param packet: Scapy packet - :return: Rebuilt Scapy packet, with old timestamp - """ - timestamp = packet.time - new_packet = packet.__class__(bytes(packet)) - new_packet.time = timestamp - return new_packet - - -def get_packet_hash(packet: scapy.Packet) -> str: - """ - Get the SHA256 hash of a Scapy packet. - - :param packet: Scapy packet - :return: SHA256 hash of Scapy packet - """ - return hashlib.sha256(bytes(packet)).hexdigest() - - def tweak_pcaps(pcaps: list, output: str, random_range: int = 1, packet_numbers: list = None, dry_run: bool = False) -> None: """ Main functionality of the program: @@ -117,7 +92,7 @@ def tweak_pcaps(pcaps: list, output: str, random_range: int = 1, packet_numbers: my_packet = Packet.init_packet(packet, i, last_layer_index) except ValueError: # No supported protocol found in packet, skip it - new_packets.append(rebuild_packet(packet)) + new_packets.append(Packet.rebuild_packet(packet)) break else: d = my_packet.tweak() @@ -131,7 +106,7 @@ def tweak_pcaps(pcaps: list, output: str, random_range: int = 1, packet_numbers: break else: # Packet won't be edited - new_packets.append(rebuild_packet(packet)) + new_packets.append(Packet.rebuild_packet(packet)) i += 1 diff --git a/traces/arp-2.pcap b/traces/arp-2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..2cff7b392b97a8c2cba3fe253aa60630a28e5019 GIT binary patch literal 140 zcmca|c+)~A1{MYcU}0bca<u2!Bz0V5X3zq%L3qQ_5a*EQl(fy?GJ-hR7#KMi*nkQl i`~xc(L0W(S$SMZueE$fc6QTy9AFh)L!Uw5Gm;nF}?j_0q literal 0 HcmV?d00001 diff --git a/traces/http.pcap b/traces/http.pcap index 7146df96245a394a9078f3b8bc4f3ae1b068c5d0..4a22e03a1b1c49019b49d2ec2b4aa2106349a88b 100644 GIT binary patch delta 247 zcmbQl{fldYgjln?OOoshMg}hi1~5)Z+x#sfXri7AScYXXD_o|cTWgcTtBD;D8M&FP z3}!$*APm*>$N;Qo6;S3DP!xnAGL!WfuYjcl{rS+PB$%#<wE*3)c_$OxJcvz`nV1d0 pQtOW}F>GRF0Aq;MW<TaNj9|I9#}V3~mI<&zv=v;ykcwe700282Nbvvw delta 272 zcmeyxHHmwIgxI0&f+-eqybN9p3}Ad9Oug8Rd!n9;*kPc|<#tANnGT4|=Uzqz8=xK# zhU$4_AOqw80Z3<aA0xvpARB}s@{=_fuYe8JcH=^q5@Lc#aem=NGj;MGCS+qJ{_`?y nVq^egh_RcUnAb3Z%?)JYL)Xm0imdrM7lr~aRs%MWlNlHQa3Dho -- GitLab