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