feat: rewrite sql + alert sent to sql db from idps

This commit is contained in:
Oxbian 2024-11-18 21:49:08 -05:00
parent 2d25387fde
commit 48e9554d38
Signed by: Oxbian
GPG Key ID: 0E8F319FD43747E5
10 changed files with 110 additions and 87 deletions

View File

@ -24,7 +24,7 @@ La base de données SQL est structurée de la façon suivante:
## Interface de tests d'alertes
Un script python `tests/cef-generator.py` permet de générer des alertes CEF dans la base de données SQL.
Un script python `sql/cef-generator.py` permet de générer des alertes CEF dans la base de données SQL.
Ce script peut être utile pour le développement d'interface d'affichage des alertes. Pour l'utiliser il faut une base de donnée sql, et mettre les identifiants dans le script.
De plus, ce script à besoin de la librairie `sql` pour pouvoir ajouter / faire des requêtes à la base de données MySQL.
@ -39,7 +39,7 @@ pip install -r requirements.txt
Puis executer le script `tests/cef-generator.py` avec le python3 du l'environnement virtuel.
```bash
.venv/bin/python3 tests/cef-generator.py
.venv/bin/python3 sql/cef-generator.py
```
## Demo

View File

@ -6,6 +6,10 @@
"db_user": "sidps",
"db_password": "SUPERPASSWORD",
"db_port": "3306",
"cef_version": 1,
"device_product": "SIDPS",
"device_vendor": "ArKa",
"device_version": "vAlpha",
"synscan_time": 180,
"synscan_count": 5,
"tcpconnectscan_time": 180,

View File

@ -9,44 +9,61 @@ class Database:
self.conn = mysql.connector.connect(host=config["db_host"], database=config["db_database"], user=config["db_user"], password=config["db_password"], port=config["db_port"])
self.config = config
def send_alert(self, alert):
def send_alert(self, date_alert = None, agent_severity = None, device_event_class_id = None,
name = None, src = None, dst = None, dpt = None, spt = None, msg = None,
proto = None, bytesin = None, bytesout = None, reason = None, act = None):
"""Ajoute une alerte dans la base de données
@param alert: Alerte à rajouter dans la BDD"""
@param date_alert: Timestamp de l'alerte
@param agent_severity: Criticité de l'alerte (0 - 10)
@param device_event_class_id: Identifiant de signature, pour le moteur de corrélation
@param name: Nom descriptif de l'alerte
@param src: Adresse IP source
@param dst: Adresse IP destination
@param dpt: Port de destination
@param spt: Port source
@param msg: Champ de texte pour des notes ou commentaires additionnels
@param proto: Protocol couche 4 (réseau) utilisé
@param bytesin: Quantité de bytes (8 bits ici) entrants
@param bytesout: Quantité de bytes (8 bits ici) sortants
@param reason: Description de la raison de l'alerte
@param act: Action prise en réponse de l'alerte
"""
try:
cursor = self.conn.cursor()
sql_query = """
INSERT INTO alertes (
cef_version, date_alerte, event_gravite, device_product,
device_vendor, device_version, alerte_name, sourceAddress,
destinationAddress, destinationPort, sourcePort, protocol,
applicationProtocol, reason, action, commentaire
cef_version, date_alerte, agent_severity, device_event_class_id,
device_product, device_vendor, device_version, name, dst, src,
dpt, spt, msg, proto, bytesin, bytesout, reason, act
) VALUES (
%(cef_version)s, %(date_alerte)s, %(event_gravite)s, %(device_product)s,
%(device_vendor)s, %(device_version)s, %(alerte_name)s, %(src)s,
%(dst)s, %(destinationPort)s, %(sourcePort)s, %(protocol)s,
%(applicationProtocol)s, %(reason)s, %(action)s, %(commentaire)s
%(cef_version)s, %(date_alerte)s, %(agent_severity)s, %(device_event_class_id)s,
%(device_product)s, %(device_vendor)s, %(device_version)s, %(name)s, %(dst)s,
%(src)s, %(dpt)s, %(spt)s, %(msg)s, %(proto)s, %(bytesin)s, %(bytesout)s,
%(reason)s, %(act)s
);
"""
# Paramètres pour la requête SQL
params = {
"cef_version": alert["CEF"],
"date_alerte": alert["datetime"],
"event_gravite": alert["agent_severity"],
"device_product": alert["Device Product"],
"device_vendor": alert["Device Vendor"],
"device_version": alert["Device Version"],
"alerte_name": alert["name"],
"src": alert["src"],
"dst": alert["dst"],
"destinationPort": alert["dstPort"],
"sourcePort": alert["srcPort"],
"protocol": alert["protocol"],
"applicationProtocol": alert["applicationProtocol"],
"reason": alert["reason"],
"action": alert["action"],
"commentaire": alert["commentaire"]
"cef_version": self.get_key("cef_version", 1),
"date_alerte": date_alert,
"agent_severity": agent_severity,
"device_event_class_id": device_event_class_id,
"device_product": self.get_key("device_product", "SIDPS"),
"device_vendor": self.get_key("device_vendor", "ArKa"),
"device_version": self.get_key("device_version", "vAlpha"),
"name": name,
"src": src,
"dst": dst,
"dpt": dpt,
"spt": spt,
"msg": msg,
"proto": proto,
"bytesin": bytesin,
"bytesout": bytesout,
"reason": reason,
"act": act
}
# Exécution de la requête d'insertion
@ -61,4 +78,4 @@ class Database:
@param key: clé du paramètre souhaité
@param default_val: valeur par défaut si la clé n'existe pas"""
return self.config.get(key, None)
return self.config.get(key, default_val)

View File

@ -1,3 +1,5 @@
from datetime import datetime
def rule(packet, tcp_packets, db):
"""Règle SYNScan:
Un SYNScan va envoyer des requêtes TCP avec le flag SYN
@ -9,4 +11,5 @@ def rule(packet, tcp_packets, db):
seuil = db.get_key("synscan_count", 5)
if (tcp_packets.count_packet_of_type("RA", time_window) + tcp_packets.count_packet_of_type("SA", time_window)) + tcp_packets.count_packet_of_type("R", time_window) >= seuil:
db.send_alert(datetime.now(), 5, None, "Syn scan", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de Syn->SynACK->Reset ACK et Syn->Reset ACK", act="Alerte")
print(f"Alerte, seuil dépassés, risque de SynScan")

View File

@ -1,3 +1,5 @@
from datetime import datetime
def rule(packet, tcp_packets, db):
"""Règle TCPConnect Scan:
Un scan TCP connect va effectuer une connexion TCP en entier sur chaque port scanné.
@ -8,4 +10,5 @@ def rule(packet, tcp_packets, db):
seuil = db.get_key("tcpconnectscan_count", 5)
if (tcp_packets.count_packet_of_type("A", time_window) + tcp_packets.count_packet_of_type("RA", time_window)) >= seuil:
print(f"Alerte, seuils dépassés, risque de TCPConnectScan")
db.send_alert(datetime.now(), 5, None, "TCPConnect Scan", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de Syn->SynACK->ACK->Reset->ACK et Syn->Reset ACK", act="Alerte")
print(f"Alerte, seuils dépassés, risque de TCPConnectScan")

View File

@ -12,6 +12,8 @@ class TCP:
def add_packet(self, ip_src, port_src, ip_dst, port_dst, flags, timestamp):
"""Ajoute le suivi d'un paquet dans le dictionnaire"""
timestamp = int(timestamp)
# Initialisation de la liste de paquets pour l'IP source
if ip_src not in self.packets:
self.packets[ip_src] = []
@ -82,7 +84,7 @@ class TCP:
return None
for i, [p_s, ip_d, p_d, f, stamp] in enumerate(self.packets[ip_src]):
if p_s == port_src and ip_d == ip_dst and p_d == port_dst and f in flags:
if p_s == port_src and ip_d == ip_dst and p_d == port_dst and flags in f:
return i
return None

View File

@ -1,5 +0,0 @@
CREATE DATABASE sidps DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'sidps'@'localhost' IDENTIFIED BY 'SUPERPASSWORD';
GRANT ALL PRIVILEGES ON sidps.* TO 'sidps'@'localhost';
FLUSH PRIVILEGES;
use sidps;

View File

@ -9,7 +9,6 @@ import time
import random
from datetime import datetime
def generate_alert(alert_type):
# Dictionnaire pour différents types d'alertes réseau et fichiers
alert_templates = {
@ -71,7 +70,7 @@ def generate_filename():
def generate_alerts(conn, cursor, main_headers):
# Récupérer ces données depuis une fonction
alertes = ["Syn Flood", "Port Scanning", "Suspicious File Creation", "Critical File Deletion Attempt"]
alertes = ["Syn Flood", "Port Scanning"] #, "Suspicious File Creation", "Critical File Deletion Attempt"]
while True:
data = generate_alert(random.choice(alertes))
@ -81,15 +80,14 @@ def generate_alerts(conn, cursor, main_headers):
# Préparer la requête SQL d'insertion
sql_query = """
INSERT INTO alertes (
cef_version, date_alerte, event_gravite, device_product,
device_vendor, device_version, alerte_name, sourceAddress,
destinationAddress, destinationPort, sourcePort, protocol,
applicationProtocol, reason, action, commentaire
cef_version, date_alerte, agent_severity, device_event_class_id,
device_product, device_vendor, device_version, name, dst, src,
dpt, spt, msg, proto, bytesin, bytesout, reason, act
) VALUES (
%(cef_version)s, %(date_alerte)s, %(event_gravite)s, %(device_product)s,
%(device_vendor)s, %(device_version)s, %(alerte_name)s, %(src)s,
%(dst)s, %(destinationPort)s, %(sourcePort)s, %(protocol)s,
%(applicationProtocol)s, %(reason)s, %(action)s, %(commentaire)s
%(cef_version)s, %(date_alerte)s, %(agent_severity)s, %(device_event_class_id)s,
%(device_product)s, %(device_vendor)s, %(device_version)s, %(name)s, %(dst)s,
%(src)s, %(dpt)s, %(spt)s, %(msg)s, %(proto)s, %(bytesin)s, %(bytesout)s,
%(reason)s, %(act)s
);
"""
@ -97,20 +95,22 @@ def generate_alerts(conn, cursor, main_headers):
params = {
"cef_version": merged["CEF"],
"date_alerte": datetime.now(),
"event_gravite": int(merged["agent_severity"]),
"agent_severity": int(merged["agent_severity"]),
"device_event_class_id": None,
"device_product": merged["Device Product"],
"device_vendor": merged["Device Vendor"],
"device_version": merged["Device Version"],
"alerte_name": merged["name"],
"name": merged["name"],
"src": merged["src"],
"dst": merged["dst"],
"destinationPort": None, # A définir si disponible
"sourcePort": None, # A définir si disponible
"protocol": "TCP", # Par défaut, à adapter si besoin
"applicationProtocol": "N/A", # À ajuster en fonction des besoins
"reason": "Suspicious activity detected", # Exemple, à adapter
"action": "Alerted", # Exemple d'action
"commentaire": "" # Optionnel
"dpt": None,
"spt": None,
"msg": "Message",
"proto": "TCP",
"bytesin": None,
"bytesout": None,
"reason": "Activité suspecte",
"act": "Alert"
}
# Exécution de la requête d'insertion
@ -132,17 +132,11 @@ def main():
cursor = conn.cursor()
# En-têtes généraux
CEF_version = 1
Device_vendor = "ArKa"
Device_product = "SIDPS"
Device_version = "vAlpha"
main_headers = {
"CEF": CEF_version,
"Device Vendor": Device_vendor,
"Device Product": Device_product,
"Device Version": Device_version
"CEF": 1,
"Device Vendor": "ArKa",
"Device Product": "SIDPS",
"Device Version": "vAlpha"
}
# Lancer la génération d'alertes

View File

@ -12,18 +12,21 @@ CREATE TABLE alertes (
id SERIAL PRIMARY KEY, -- Identifiant unique pour chaque alerte
cef_version VARCHAR(10) DEFAULT 'CEF:1', -- Version du format CEF utilisé
date_alerte TIMESTAMP(3) NOT NULL, -- Date et heure de l'alerte avec une précision de millisecondes
event_gravite INT CHECK (event_gravite >= 0 AND event_gravite <= 10), -- Niveau de gravité de l'alerte sur une échelle de 0 à 10
agent_severity INT CHECK (agent_severity >= 0 AND agent_severity <= 10), -- Niveau de gravité de l'alerte sur une échelle de 0 à 10
device_event_class_id VARCHAR(1023), -- Identifiant de la signature permettant d'aider les moteurs de corrélations
device_product VARCHAR(63), -- Nom du produit à l'origine de l'alerte
device_vendor VARCHAR(63), -- Nom du fournisseur ou fabricant du produit
device_version VARCHAR(31), -- Version du produit ou dispositif ayant généré l'alerte
alerte_name VARCHAR(512), -- Nom descriptif de l'alerte
destinationAddress VARCHAR(45), -- Adresse IP de destination impliquée dans l'alerte
sourceAddress VARCHAR(45), -- Adresse IP source impliquée dans l'alerte
destinationPort INT, -- Port de destination utilisé pour l'événement ou l'alerte
sourcePort INT, -- Port source de l'événement ou de l'alerte
protocol VARCHAR(10), -- Protocole réseau impliqué (ex : TCP, UDP)
applicationProtocol VARCHAR(20), -- Protocole applicatif impliqué (ex : HTTP, FTP)
reason TEXT, -- Description de la raison de l'alerte expliquant pourquoi elle a été générée
action VARCHAR(50), -- Action entreprise en réponse à l'alerte (ex : bloqué, alerté uniquement, ...)
commentaire TEXT -- Champ texte pour des notes ou commentaires additionnels concernant l'alerte
name VARCHAR(512), -- Nom descriptif de l'alerte
-- Champ d'extension du CEF
dst VARCHAR(45), -- Adresse IP de destination impliquée dans l'alerte
src VARCHAR(45), -- Adresse IP source impliquée dans l'alerte
dpt INT, -- Port de destination utilisé pour l'événement ou l'alerte
spt INT, -- Port source de l'événement ou de l'alerte
msg VARCHAR(1023), -- Champ texte pour des notes ou commentaires additionnels concernant l'alerte
proto VARCHAR(10), -- Protocole réseau impliqué (ex : TCP, UDP)
bytesin INT, -- Quantité de bytes (8 bits ici) entrant (cas de flood ou DOS)
bytesout INT, -- Quantité des bytes (8 bits ici) sortants
reason VARCHAR(1023), -- Description de la raison de l'alerte expliquant pourquoi elle a été générée
act VARCHAR(50) -- Action entreprise en réponse à l'alerte (ex : bloqué, alerté uniquement, ...)
);

View File

@ -18,18 +18,20 @@ CREATE TABLE alertes (
id SERIAL PRIMARY KEY, -- Identifiant unique pour chaque alerte
cef_version VARCHAR(10) DEFAULT 'CEF:1', -- Version du format CEF utilisé
date_alerte TIMESTAMP(3) NOT NULL, -- Date et heure de l'alerte avec une précision de millisecondes
event_gravite INT CHECK (event_gravite >= 0 AND event_gravite <= 10), -- Niveau de gravité de l'alerte sur une échelle de 0 à 10
agent_severity INT CHECK (agent_severity >= 0 AND agent_severity <= 10), -- Niveau de gravité de l'alerte sur une échelle de 0 à 10
device_event_class_id VARCHAR(1023), -- Identifiant de la signature permettant d'aider les moteurs de corrélations
device_product VARCHAR(63), -- Nom du produit à l'origine de l'alerte
device_vendor VARCHAR(63), -- Nom du fournisseur ou fabricant du produit
device_version VARCHAR(31), -- Version du produit ou dispositif ayant généré l'alerte
alerte_name VARCHAR(512), -- Nom descriptif de l'alerte
destinationAddress VARCHAR(45), -- Adresse IP de destination impliquée dans l'alerte
sourceAddress VARCHAR(45), -- Adresse IP source impliquée dans l'alerte
destinationPort INT, -- Port de destination utilisé pour l'événement ou l'alerte
sourcePort INT, -- Port source de l'événement ou de l'alerte
protocol VARCHAR(10), -- Protocole réseau impliqué (ex : TCP, UDP)
applicationProtocol VARCHAR(20), -- Protocole applicatif impliqué (ex : HTTP, FTP)
reason TEXT, -- Description de la raison de l'alerte expliquant pourquoi elle a été générée
action VARCHAR(50), -- Action entreprise en réponse à l'alerte (ex : bloqué, alerté uniquement, ...)
commentaire TEXT -- Champ texte pour des notes ou commentaires additionnels concernant l'alerte
name VARCHAR(512), -- Nom descriptif de l'alerte
dst VARCHAR(45), -- Adresse IP de destination impliquée dans l'alerte
src VARCHAR(45), -- Adresse IP source impliquée dans l'alerte
dpt INT, -- Port de destination utilisé pour l'événement ou l'alerte
spt INT, -- Port source de l'événement ou de l'alerte
msg VARCHAR(1023), -- Champ texte pour des notes ou commentaires additionnels concernant l'alerte
proto VARCHAR(10), -- Protocole réseau impliqué (ex : TCP, UDP)
bytesin INT, -- Quantité de bits entrant (cas de flood ou DOS)
bytesout INT, -- Quantité des bits sortants
reason VARCHAR(1023), -- Description de la raison de l'alerte expliquant pourquoi elle a été générée
act VARCHAR(50) -- Action entreprise en réponse à l'alerte (ex : bloqué, alerté uniquement, ...)
);