Skip to content
Snippets Groups Projects
Commit 03f8754c authored by Popal, Massi's avatar Popal, Massi
Browse files

Upload New File

parent e5d806d6
Branches main
No related tags found
No related merge requests found
#!/usr/bin/python3
from flask import Flask, request, jsonify
import ssl
import sqlite3
from typing import List, Dict
import logging
import requests
import json
import networkx as nx
import os
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app = Flask(__name__)
conn = sqlite3.connect("iocs.db", check_same_thread=False)
conn.execute("CREATE TABLE IF NOT EXISTS iocs (id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT)")
def gac_connect(time_window: float = 300.0) -> List[Dict]:
"""Identify multi-step attacks by constructing a directed graph of IoCs based on time and entity overlap."""
cursor = conn.execute("SELECT data FROM iocs")
iocs = [json.loads(row[0]) for row in cursor.fetchall()]
if not iocs:
return []
G = nx.DiGraph()
for ioc in iocs:
G.add_node(ioc["timestamp"], data=ioc)
for i, ioc1 in enumerate(iocs):
for ioc2 in iocs[i+1:]:
time_diff = float(ioc2["timestamp"]) - float(ioc1["timestamp"])
if time_diff <= time_window and (set(ioc1["attackers"]) & set(ioc2["attackers"]) or set(ioc1["victims"]) & set(ioc2["victims"])):
G.add_edge(ioc1["timestamp"], ioc2["timestamp"])
multi_step_attacks = []
for component in nx.weakly_connected_components(G):
nodes = sorted([G.nodes[n]["data"] for n in component], key=lambda x: float(x["timestamp"]))
if len(nodes) <= 1:
continue
attackers, victims, details = set(), set(), []
attack_type = nodes[0]["pattern"]
for i, node in enumerate(nodes):
attackers.update(node["attackers"])
victims.update(node["victims"])
details.append(node)
if i > 0:
prev_type, curr_type = nodes[i-1]["pattern"], node["pattern"]
if "Portscan" in prev_type and "Exploitation" in curr_type:
attack_type = "Portscan followed by Exploitation"
elif "Exploitation" in prev_type and "DDoS" in curr_type:
attack_type = "Exploitation followed by DDoS"
elif "Portscan" in prev_type and "DDoS" in curr_type:
attack_type = "Portscan followed by DDoS"
elif "Exploitation" in prev_type and "Worm Propagation" in curr_type:
attack_type = "Exploitation followed by Worm Propagation"
else:
attack_type = f"{attack_type} and {curr_type}"
multi_step_attacks.append({
"type": attack_type,
"attackers": list(attackers),
"victims": list(victims),
"details": details,
"network_id": nodes[0]["network_id"]
})
for attack in multi_step_attacks:
logging.info(f"Multi-Step Attack in {attack['network_id']} detected: {attack['type']}")
return multi_step_attacks
@app.route('/submit_ioc', methods=['POST'])
def submit_ioc():
"""Process incoming IoCs, store them, and trigger alert generation."""
ioc_data = request.json
for ioc in ioc_data:
conn.execute("INSERT INTO iocs (data) VALUES (?)", (json.dumps(ioc),))
conn.commit()
logging.info(f"Received IoCs: {len(ioc_data)} from Network {ioc_data[0]['network_id']}")
network_ids = set(ioc["network_id"] for ioc in ioc_data)
multi_step_attacks = gac_connect()
messages = []
if multi_step_attacks:
messages = send_alerts(multi_step_attacks, multi_step=True, network_ids=network_ids)
else:
cursor = conn.execute("SELECT data FROM iocs")
iocs = [json.loads(row[0]) for row in cursor.fetchall()]
if iocs:
messages = send_alerts(iocs, multi_step=False, network_ids=network_ids)
# Print messages at the end
if messages:
print("\n=== Nachrichten an Netzwerke ===")
for msg in messages:
print(msg)
print("====================\n")
return jsonify({"status": "success"}), 200
def send_alerts(attacks_or_iocs, multi_step: bool, network_ids: set) -> List[str]:
"""Transmit alerts to client networks via HTTPS and return tailored messages."""
messages = []
for item in attacks_or_iocs:
source_network = item["network_id"]
alert_type = item["type"] if multi_step else item["pattern"]
attackers, victims = item["attackers"], item["victims"]
if "Portscan" in alert_type:
recommendation = "Blockiere die Quell-IPs und überprüfe die Zielsysteme auf Scan-Aktivitäten."
elif "Exploitation" in alert_type:
recommendation = "Isoliere die betroffenen Systeme und überprüfe sie auf Kompromittierung."
elif "DDoS" in alert_type:
recommendation = "Erhöhe die Netzwerksicherheit und blockiere die Angreifer-IPs."
elif "Worm Propagation" in alert_type:
recommendation = "Quarantäne infizierte Systeme und führe eine Netzwerkbereinigung durch."
else:
recommendation = "Blockiere Angreifer-IPs und überprüfe Zielsysteme auf Kompromittierung."
for network_id in network_ids:
if network_id == source_network:
message = f"In deinem Netzwerk wurde ein {alert_type} erkannt."
else:
message = f"Im angebundenen Netzwerk {source_network} wurde ein {alert_type} erkannt."
alert_plus = {
"type": alert_type,
"attackers": attackers,
"victims": victims,
"source_network": source_network,
"current_network": network_id,
"recommendation": recommendation,
"message": message # Include the tailored message in the alert
}
network_url = f"https://{network_id.lower()}.local:8080/alert"
try:
response = requests.post(network_url, json=alert_plus, verify=False)
if response.status_code == 200:
logging.info(f"Alert Plus sent to {network_id}: {message}")
messages.append(f"An {network_id}: {message} Empfehlung: {recommendation}")
else:
logging.error(f"Error sending to {network_id}: {response.status_code}")
except Exception as e:
logging.error(f"Connection error sending to {network_id}: {e}")
return messages
if __name__ == "__main__":
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
cert_path = "cert.pem"
key_path = "key.pem"
if not (os.path.exists(cert_path) and os.path.exists(key_path)):
raise FileNotFoundError("SSL certificates (cert.pem, key.pem) not found. Generate them with OpenSSL.")
context.load_cert_chain(cert_path, key_path)
app.run(host='0.0.0.0', port=443, ssl_context=context, threaded=False)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment