From c3b6071b12b945dbf222bc94cebe1715eceae793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20De=20Keersmaeker?= <francois.dekeersmaeker@uclouvain.be> Date: Wed, 7 Jun 2023 16:09:40 +0200 Subject: [PATCH] Added old and new packet SHA256 hash values to log --- src/packet/BOOTP.py | 4 +++- src/packet/CoAP.py | 4 +++- src/packet/DNS.py | 4 +++- src/packet/IGMPv3mr.py | 4 +++- src/packet/Packet.py | 21 ++++++++++++++++++--- src/packet/Transport.py | 4 +++- src/pcap_tweaker.py | 13 ++++++++++++- 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/packet/BOOTP.py b/src/packet/BOOTP.py index 075697b..c796c1b 100644 --- a/src/packet/BOOTP.py +++ b/src/packet/BOOTP.py @@ -69,6 +69,8 @@ class BOOTP(Packet): :return: Dictionary containing tweak information. """ + # Store old hash value + old_hash = self.get_hash() # Get field which will be modified field = random.choice(self.fields) @@ -94,4 +96,4 @@ class BOOTP(Packet): self.update_fields() # Return value: dictionary containing tweak information - return self.get_dict_log(field, old_value, new_value) + return self.get_dict_log(field, old_value, new_value, old_hash) diff --git a/src/packet/CoAP.py b/src/packet/CoAP.py index 1d1d9e0..1855d93 100644 --- a/src/packet/CoAP.py +++ b/src/packet/CoAP.py @@ -77,6 +77,8 @@ class CoAP(Packet): :return: Dictionary containing tweak information. """ + # Store old hash value + old_hash = self.get_hash() # Get field which will be modified field = random.choice(self.fields) @@ -104,4 +106,4 @@ class CoAP(Packet): self.update_fields() # Return value: dictionary containing tweak information - return self.get_dict_log(field, old_value, new_value) + return self.get_dict_log(field, old_value, new_value, old_hash) diff --git a/src/packet/DNS.py b/src/packet/DNS.py index e147b99..cfb79b9 100644 --- a/src/packet/DNS.py +++ b/src/packet/DNS.py @@ -71,6 +71,8 @@ class DNS(Packet): :return: Dictionary containing tweak information. """ + # Store old hash value + old_hash = self.get_hash() # Get field which will be modified field = self.get_field() @@ -123,4 +125,4 @@ class DNS(Packet): self.update_fields() # Return value: dictionary containing tweak information - return self.get_dict_log(field, old_value, new_value) + return self.get_dict_log(field, old_value, new_value, old_hash) diff --git a/src/packet/IGMPv3mr.py b/src/packet/IGMPv3mr.py index 2f1cfc0..40d3b81 100644 --- a/src/packet/IGMPv3mr.py +++ b/src/packet/IGMPv3mr.py @@ -19,6 +19,8 @@ class IGMPv3mr(Packet): :return: Dictionary containing tweak information. """ + # Store old hash value + old_hash = self.get_hash() # Set random IP address for all group records old_value = "" new_value = "" @@ -38,4 +40,4 @@ class IGMPv3mr(Packet): self.update_fields() # Return value: dictionary containing tweak information - return self.get_dict_log("maddr", old_value, new_value) + return self.get_dict_log("maddr", old_value, new_value, old_hash) diff --git a/src/packet/Packet.py b/src/packet/Packet.py index 2f37f82..e107794 100644 --- a/src/packet/Packet.py +++ b/src/packet/Packet.py @@ -6,6 +6,7 @@ import re import random from ipaddress import IPv4Address, IPv6Address import scapy.all as scapy +import hashlib class Packet: """ @@ -190,6 +191,15 @@ class Packet: return self.layer_index + def get_hash(self) -> str: + """ + Get packet hash. + + :return: Packet hash. + """ + return hashlib.sha256(bytes(self.packet)).hexdigest() + + def rebuild(self) -> None: """ Rebuild packet, but keep old timestamp. @@ -225,7 +235,7 @@ class Packet: self.rebuild() - def get_dict_log(self, field: str, old_value: str, new_value: str) -> dict: + def get_dict_log(self, field: str, old_value: str, new_value: str, old_hash: str) -> dict: """ Log packet field modification, and return a dictionary containing tweak information. @@ -233,6 +243,7 @@ class Packet: :param field: Field name. :param old_value: Old field value. :param new_value: New field value. + :param old_hash: Old packet hash (before tweak). :return: Dictionary containing tweak information. """ timestamp = self.packet.time @@ -243,7 +254,9 @@ class Packet: "protocol": self.name, "field": field, "old_value": old_value, - "new_value": new_value + "new_value": new_value, + "old_hash": old_hash, + "new_hash": self.get_hash() } return d @@ -255,6 +268,8 @@ class Packet: :return: Dictionary containing tweak information, or None if no tweak was performed. """ + # Store old hash value + old_hash = self.get_hash() # Get field which will be modified field, value_type = random.choice(list(self.fields.items())) # Store old value of field @@ -323,4 +338,4 @@ class Packet: self.update_fields() # Return value: dictionary containing tweak information - return self.get_dict_log(field, old_value, new_value) + return self.get_dict_log(field, old_value, new_value, old_hash) diff --git a/src/packet/Transport.py b/src/packet/Transport.py index 433d82c..da73a5e 100644 --- a/src/packet/Transport.py +++ b/src/packet/Transport.py @@ -27,6 +27,8 @@ class Transport(Packet): :return: Dictionary containing tweak information, or None if no tweak was performed. """ + # Store old hash value + old_hash = self.get_hash() # Check if destination port is a well-known port if self.layer.getfieldval("dport") in self.ports: field = "dport" @@ -53,4 +55,4 @@ class Transport(Packet): self.update_fields() # Return value: dictionary containing tweak information - return self.get_dict_log(field, old_value, new_value) + return self.get_dict_log(field, old_value, new_value, old_hash) diff --git a/src/pcap_tweaker.py b/src/pcap_tweaker.py index d42f28e..aaacadf 100644 --- a/src/pcap_tweaker.py +++ b/src/pcap_tweaker.py @@ -10,6 +10,7 @@ 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 @@ -59,6 +60,16 @@ def rebuild_packet(packet: scapy.Packet) -> scapy.Packet: 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: @@ -91,7 +102,7 @@ def tweak_pcaps(pcaps: list, output: str, random_range: int = 1, packet_numbers: csv_log = os.path.basename(input_pcap).replace(".pcap", ".edit.csv") csv_log = os.path.join(csv_dir, csv_log) with open(csv_log, "w") as csv_file: - field_names = ["id", "timestamp", "protocol", "field", "old_value", "new_value"] + field_names = ["id", "timestamp", "protocol", "field", "old_value", "new_value", "old_hash", "new_hash"] writer = csv.DictWriter(csv_file, fieldnames=field_names) writer.writeheader() -- GitLab