v4.5 Demo initial commit
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
from scapy.all import rdpcap, Raw, DNS, DNSQR
|
||||
try:
|
||||
from scapy.layers.tls.all import TLS
|
||||
except ImportError:
|
||||
# Fallback or mock if TLS not available, though we use a try-except block in usage
|
||||
TLS = None
|
||||
import re
|
||||
import os
|
||||
from IoTAnalyzer.models import UrlRaw, HashRaw
|
||||
|
||||
|
||||
def analyze_pcap_file(pcap_file, raw_dataset_id):
|
||||
|
||||
"""
|
||||
Analyzes a PCAP file and stores found hashes and URLs in the database.
|
||||
"""
|
||||
print("Start analyzing...")
|
||||
|
||||
# Adjust the path to the file
|
||||
# Check multiple locations for the file
|
||||
possible_paths = [
|
||||
os.path.join('/app/files/uploads', pcap_file), # Mounted frontend uploads
|
||||
os.path.join('/app/files', pcap_file), # Shared files
|
||||
os.path.join('Frontend', 'iot-pre-tester-frontend', 'public', 'filesAttachment', pcap_file), # Local dev fallback
|
||||
]
|
||||
|
||||
filepath = None
|
||||
for path in possible_paths:
|
||||
if os.path.exists(path):
|
||||
filepath = path
|
||||
break
|
||||
|
||||
if not filepath:
|
||||
print(f"Fehler: Datei {pcap_file} nicht gefunden in: {possible_paths}")
|
||||
return
|
||||
|
||||
# Regular expressions for hashes and URLs
|
||||
hash_pattern = re.compile(r"\b[a-fA-F0-9]{32,64}\b") # MD5, SHA1, SHA256
|
||||
|
||||
# Stricter URL pattern:
|
||||
# 1. Requires http://, https://, or www. (Standard)
|
||||
# 2. OR Naked domain with AT LEAST 2 dots (e.g. sub.domain.com) to catch cloud URLs but avoid "J.mINT"
|
||||
url_pattern = re.compile(
|
||||
r"\b(?:"
|
||||
r"(?:https?://|www\.)(?:[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})" # Protocol/www required
|
||||
r"|"
|
||||
r"(?:[a-zA-Z0-9-]+\.){2,}[a-zA-Z]{2,6}" # Naked domain with >= 2 dots
|
||||
r"|"
|
||||
r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" # IPv4
|
||||
r")"
|
||||
r"(?:/[a-zA-Z0-9._%/-]*)?\b"
|
||||
)
|
||||
|
||||
# Load PCAP file
|
||||
try:
|
||||
packets = rdpcap(filepath)
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Öffnen der PCAP-Datei: {e}")
|
||||
return
|
||||
|
||||
found_hashes = set()
|
||||
found_urls = set()
|
||||
|
||||
# Analyze packets
|
||||
for pkt in packets:
|
||||
# 1. DNS Queries (Reliable source for domains)
|
||||
if pkt.haslayer(DNS) and pkt[DNS].qd:
|
||||
try:
|
||||
qname = pkt[DNS].qd.qname.decode('utf-8', errors='ignore')
|
||||
if qname.endswith('.'):
|
||||
qname = qname[:-1]
|
||||
if qname:
|
||||
found_urls.add(qname)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 2. TLS Server Name Indication (SNI)
|
||||
# Attempt to extract SNI if TLS layer is present
|
||||
if TLS and pkt.haslayer(TLS):
|
||||
try:
|
||||
# Iterate through TLS messages to find ClientHello and extensions
|
||||
if hasattr(pkt[TLS], 'msg'):
|
||||
for msg in pkt[TLS].msg:
|
||||
if hasattr(msg, 'ext'):
|
||||
for ext in msg.ext:
|
||||
if hasattr(ext, 'servernames'):
|
||||
for servername in ext.servernames:
|
||||
if hasattr(servername, 'servername'):
|
||||
sni = servername.servername.decode('utf-8', errors='ignore')
|
||||
if sni:
|
||||
found_urls.add(sni)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 3. Raw Payload (Fallback with strict regex)
|
||||
if pkt.haslayer(Raw): # Check whether the packet has a payload
|
||||
payload = pkt[Raw].load.decode(errors='ignore')
|
||||
|
||||
# Search for hashes
|
||||
found_hashes.update(hash_pattern.findall(payload))
|
||||
|
||||
# Search for URLs
|
||||
found_urls.update(url_pattern.findall(payload))
|
||||
|
||||
# Store results in the database
|
||||
save_urls_to_database(found_urls, raw_dataset_id)
|
||||
save_hashes_to_database(found_hashes, raw_dataset_id)
|
||||
|
||||
print("Done analyzing.")
|
||||
|
||||
|
||||
def save_urls_to_database(urls, raw_dataset_id):
|
||||
"""
|
||||
Stores extracted URLs in the database.
|
||||
"""
|
||||
for url in urls:
|
||||
UrlRaw.objects.create(
|
||||
raw_dataset_id=raw_dataset_id,
|
||||
url=url
|
||||
)
|
||||
|
||||
|
||||
def save_hashes_to_database(hashes, raw_dataset_id):
|
||||
"""
|
||||
Stores extracted hashes in the database.
|
||||
"""
|
||||
for hash_value in hashes:
|
||||
HashRaw.objects.create(
|
||||
raw_dataset_id=raw_dataset_id,
|
||||
hash_value=hash_value
|
||||
)
|
||||
Reference in New Issue
Block a user