From b31fc4e10de07a24d2ccb6b33ba3d7a0922e083b Mon Sep 17 00:00:00 2001
From: VladLub <vladlubkovskiy1@gmail.com>
Date: Wed, 11 Dec 2024 13:58:11 +0100
Subject: [PATCH] implemented trivial database and fixed trivial errors

---
 code/src/database_connection.py | 87 +++++++++++++++++++++++++++++++++
 code/src/packet_capturing.py    | 29 ++++++++---
 2 files changed, 109 insertions(+), 7 deletions(-)
 create mode 100644 code/src/database_connection.py

diff --git a/code/src/database_connection.py b/code/src/database_connection.py
new file mode 100644
index 0000000..d527a31
--- /dev/null
+++ b/code/src/database_connection.py
@@ -0,0 +1,87 @@
+from scapy.layers.inet import IP, TCP
+from scapy.layers.l2 import Ether, ARP
+import duckdb as duckdb
+
+UNDEFINED = 'Undefined'
+def initiate_database(connection):
+    connection.sql("CREATE TABLE IF NOT EXISTS packets ("
+                   "source_ip VARCHAR, "
+                   "destination_ip VARCHAR, "
+                   "source_mac VARCHAR, "
+                   "destination_mac VARCHAR, "
+                   "source_port VARCHAR, "
+                   "destination_port VARCHAR, "
+                   "is_dangerous BOOLEAN, "
+                   "type_of_threat VARCHAR)")
+def add_address(connection, packet):
+    source_ip = packet[IP].src if IP in packet else UNDEFINED
+    destination_ip = packet[IP].dst if IP in packet else UNDEFINED
+    source_mac = packet[Ether].src if Ether in packet else UNDEFINED
+    destination_mac = packet[Ether].dst if Ether in packet else UNDEFINED
+    source_port = packet[TCP].sport if TCP in packet else UNDEFINED
+    destination_port = packet[TCP].dport if TCP in packet else UNDEFINED
+    is_dangerous = False
+    type_of_threat = 'None'
+
+    if not contains_address(connection, packet):
+        connection.sql(f"INSERT INTO packets VALUES ("
+                           f"'{source_ip}', "
+                           f"'{destination_ip}', "
+                           f"'{source_mac}', "
+                           f"'{destination_mac}', "
+                           f"'{source_port}', "
+                           f"'{destination_port}', "
+                           f"{is_dangerous}, "
+                           f"'{type_of_threat}')")
+
+def update_address(connection, packet, is_dangerous, type_of_threat):
+    source_ip = packet[IP].src if IP in packet else UNDEFINED
+    destination_ip = packet[IP].dst if IP in packet else UNDEFINED
+    source_mac = packet[Ether].src if Ether in packet else UNDEFINED
+    destination_mac = packet[Ether].dst if Ether in packet else UNDEFINED
+    source_port = packet[TCP].sport if TCP in packet else UNDEFINED
+    destination_port = packet[TCP].dport if TCP in packet else UNDEFINED
+
+    connection.sql(f"UPDATE packets SET "
+                       f"is_dangerous = {is_dangerous}, "
+                       f"type_of_threat = '{type_of_threat}' "
+                       f"WHERE source_ip = '{source_ip}' AND "
+                       f"destination_ip = '{destination_ip}' AND "
+                       f"source_mac = '{source_mac}' AND "
+                       f"destination_mac = '{destination_mac}' AND "
+                       f"source_port = '{source_port}' AND "
+                       f"destination_port = '{destination_port}'")
+
+def contains_address(connection, packet):
+    source_ip = packet[IP].src if IP in packet else UNDEFINED
+    destination_ip = packet[IP].dst if IP in packet else UNDEFINED
+    source_mac = packet[Ether].src if Ether in packet else UNDEFINED
+    destination_mac = packet[Ether].dst if Ether in packet else UNDEFINED
+    source_port = packet[TCP].sport if TCP in packet else UNDEFINED
+    destination_port = packet[TCP].dport if TCP in packet else UNDEFINED
+
+    contains = connection.sql(f"SELECT EXISTS ( FROM packets WHERE "
+                              f"source_ip = '{source_ip}' AND "
+                              f"destination_ip = '{destination_ip}' AND "
+                              f"source_mac = '{source_mac}' AND "
+                              f"destination_mac = '{destination_mac}' AND "
+                              f"source_port = '{source_port}' AND "
+                              f"destination_port = '{destination_port}')").fetchone()[0]
+
+    return contains
+
+def get_address(connection, packet):
+    source_ip = packet[IP].src if IP in packet else UNDEFINED
+    destination_ip = packet[IP].dst if IP in packet else UNDEFINED
+    source_mac = packet[Ether].src if Ether in packet else UNDEFINED
+    destination_mac = packet[Ether].dst if Ether in packet else UNDEFINED
+    source_port = packet[TCP].sport if TCP in packet else UNDEFINED
+    destination_port = packet[TCP].dport if TCP in packet else UNDEFINED
+
+    return connection.sql(f"SELECT * FROM packets WHERE "
+                              f"source_ip = '{source_ip}' AND "
+                              f"destination_ip = '{destination_ip}' AND "
+                              f"source_mac = '{source_mac}' AND "
+                              f"destination_mac = '{destination_mac}' AND "
+                              f"source_port = '{source_port}' AND "
+                              f"destination_port = '{destination_port}'").fetchone()
\ No newline at end of file
diff --git a/code/src/packet_capturing.py b/code/src/packet_capturing.py
index 599185c..3fbe562 100644
--- a/code/src/packet_capturing.py
+++ b/code/src/packet_capturing.py
@@ -2,8 +2,12 @@ from scapy.layers.inet import IP, TCP
 from scapy.layers.l2 import Ether, ARP
 from scapy.all import sniff
 from collections import defaultdict
+import duckdb as duckdb
+import database_connection as dbConn
 import time
 
+connection = duckdb.connect('packets_data.duckdb')
+
 reserved_ips = ["192.168.1.4", "192.168.1.1", "192.168.1.7", "172.16.0.3"]
 
 syn_counts = defaultdict(int)
@@ -11,19 +15,22 @@ syn_counts_last_checked = time.time()
 
 arp_table = defaultdict()
 
-def ip_spoofing(src_mac, src_ip):
+def ip_spoofing(src_mac, src_ip, packet):
 	if src_ip not in reserved_ips:
 		if src_ip.startswith("10.") or src_ip.startswith("192.168.") or src_ip.startswith("169.254."):
+			dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="IP Spoofing")
 			print("Possible IP spoofing using private networks detected.")
 		elif src_ip.startswith("172."):
 			octet = int(src_ip.split(".")[1])
 			if 16 <= octet <= 31:
+				dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="IP Spoofing")
 				print("Possible IP spoofing using private networks detected.")
 
 def syn_fin(packet):
 	if TCP in packet:
 		tcp_flags = packet[TCP].flags
 		if 'S' in tcp_flags and 'F' in tcp_flags:
+			dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="SYN-FIN")
 			print("Malicious packet detected: SYN-FIN combination.")
 			print(f"MAC Address of malicious agent: {packet[Ether].src}")
 
@@ -31,6 +38,7 @@ def null_packet(packet):
 	if TCP in packet:
 		tcp_flags = packet[TCP].flags
 		if tcp_flags == 0:
+			dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="Null Packet")
 			print("Malicious null packet found.")
 			print(f"MAC Address of malicious agent: {packet[Ether].src}")
 
@@ -39,6 +47,7 @@ def port_check(packet):
 		src_port = packet[TCP].sport
 		dst_port = packet[TCP].dport
 		if src_port == 0 or dst_port == 0:
+			dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="TCP Port 0")
 			print("Illegal packet with source or destination port 0.")
 			print(f"MAC Address of malicious agent: {packet[Ether].src}")
 
@@ -46,6 +55,7 @@ def destination_check(packet):
 	if IP in packet:
 		dest_ip = packet[IP].dst
 		if dest_ip.endswith(".0") or dest_ip.endswith(".255"):
+			dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="Broadcast Address")
 			print("Packets with broadcast destination address detected.")
 			print(f"MAC Address of malicious agent: {packet[Ether].src}")
 
@@ -55,6 +65,7 @@ def malformed_check(packet):
 		# Attempt to parse packet
 		packet.show()
 	except Exception as e:
+		dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="Malformed Packet")
 		print(f"Malformed packet detected: {e}")
 		print(f"Source: {packet[IP].src if IP in packet else 'Unknown'}")
 
@@ -68,6 +79,7 @@ def syn_flood_detection(packet):
 	if time.time() - syn_counts_last_checked > 10:
 		for ip, count in syn_counts.items():
 			if count > 100:
+				dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="SYN Flood")
 				print(f"Possible SYN flood from {ip}. Number of SYN Packets in last {time.time() - syn_counts_last_checked} seconds: {count}")
 		syn_counts.clear()
 		syn_counts_last_checked = time.time()
@@ -81,39 +93,42 @@ def arp_spoofing(packet):
 		src_mac = packet[ARP].hwsrc
 		if src_ip in arp_table:
 			if arp_table[src_ip] != src_mac:
+				dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="ARP Spoofing")
 				print(f"Possible ARP spoofing detected from IP {src_ip}. Conflicting MACs: {arp_table[src_ip]} and {src_mac}")
 		else:
 			arp_table[src_ip] = src_mac
 
 def tcp_reset_attack(packet):
 	if packet[TCP].flags == 'R':
+		dbConn.update_address(connection=connection, packet=packet, is_dangerous=True, type_of_attack="TCP Reset")
 		print(f"Possible TCP reset attack from {packet[IP].src}")
 
 def packet_handler(packet):
+	dbConn.add_address(connection=connection, packet=packet)
 	if IP in packet:
 		src_ip = packet[IP].src
 		dst_ip = packet[IP].dst
 		src_mac = packet[Ether].src if Ether in packet else None
 		print(f"Packet captured: {src_ip} -> {dst_ip}")
-		ip_spoofing(src_mac, src_ip)
+		ip_spoofing(src_mac, src_ip, packet)
+		destination_check(packet)
+		malformed_check(packet)
+		syn_flood_detection(packet)
+		arp_spoofing(packet)
 	if TCP in packet:
 		syn_fin(packet)
 		null_packet(packet)
 		port_check(packet)
 		tcp_reset_attack(packet)
-	destination_check(packet)
-	malformed_check(packet)
-	syn_flood_detection(packet)
-	arp_spoofing(packet)
 
 # Allows unit testing of the dict
 def get_dict():
 	return syn_counts
-
 def dict_clear():
 	syn_counts.clear()
 
 def main():
+	dbConn.initiate_database(connection)
 	print("Starting packet capture...")
 	sniff(prn=packet_handler, store=False)
 
-- 
GitLab