diff --git a/Demo/Dockerfiles/Dockerfile.attaquant b/Demo/Dockerfiles/Dockerfile.attaquant index bbdaa4a..8c52ada 100644 --- a/Demo/Dockerfiles/Dockerfile.attaquant +++ b/Demo/Dockerfiles/Dockerfile.attaquant @@ -2,8 +2,9 @@ FROM python:alpine3.20 # Installation des paquets nécessaires pour scapy RUN apk -U upgrade && \ - apk add --no-cache libpcap libpcap-dev gcc musl-dev libffi-dev nmap iproute2 -RUN pip install scapy + apk add --no-cache nmap iproute2 +RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories +RUN apk -U add --no-cache hping3 COPY Demo/Dockerfiles/attaquant-entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh diff --git a/Demo/Dockerfiles/Dockerfile.cible b/Demo/Dockerfiles/Dockerfile.cible index 6793bc3..e951461 100644 --- a/Demo/Dockerfiles/Dockerfile.cible +++ b/Demo/Dockerfiles/Dockerfile.cible @@ -1,15 +1,9 @@ -FROM python:alpine3.20 +FROM httpd:alpine -# Installation des paquets nécessaires pour scapy -RUN apk -U upgrade && \ - apk add --no-cache libpcap libpcap-dev gcc musl-dev libffi-dev iproute2 -RUN pip install scapy +# Installation des paquets nécessaire pour le routage +RUN apk -U upgrade && apk add --no-cache iproute2 COPY Demo/Dockerfiles/cible-entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] -# Copier le script de détection d'attaques -#COPY cible.py /cible.py - -# Lancer le script de détection -#CMD ["python", "/cible.py"] +CMD ["httpd-foreground"] diff --git a/Demo/Dockerfiles/Dockerfile.idps b/Demo/Dockerfiles/Dockerfile.idps index adc6592..89f925e 100644 --- a/Demo/Dockerfiles/Dockerfile.idps +++ b/Demo/Dockerfiles/Dockerfile.idps @@ -16,7 +16,7 @@ WORKDIR /app COPY idps /app/idps # Copie du fichier de configuration -COPY config.json /app/config.json +COPY Demo/config/config-idps.json /app/config.json # Utiliser le script comme point d'entrée ENTRYPOINT ["/entrypoint.sh"] diff --git a/Demo/Dockerfiles/Dockerfile.ids b/Demo/Dockerfiles/Dockerfile.ids index 2a91158..cded915 100644 --- a/Demo/Dockerfiles/Dockerfile.ids +++ b/Demo/Dockerfiles/Dockerfile.ids @@ -12,7 +12,7 @@ WORKDIR /app COPY idps /app/ids # Copie du fichier de configuration -COPY config.json /app/config.json +COPY Demo/config/config-ids.json /app/config.json # Lancer le script de la sonde IDS -CMD ["python3", "/app/ids/ids.py"] +CMD ["python3", "/app/ids/main.py"] diff --git a/Demo/config/config-idps.json b/Demo/config/config-idps.json new file mode 100644 index 0000000..02f0cb8 --- /dev/null +++ b/Demo/config/config-idps.json @@ -0,0 +1,31 @@ +{ + "rules_dirpath": "/app/idps/rules", + "ifaces": ["eth1"], + "db_host": "172.20.3.10", + "db_database": "sidps", + "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, + "tcpconnectscan_count": 5, + "ackscan_time": 180, + "ackscan_count": 5, + "finscan_time": 180, + "finscan_count": 5, + "nullscan_time": 180, + "nullscan_count": 5, + "xmasscan_time": 180, + "xmasscan_count": 5, + "synflood_time": 60, + "synflood_count": 100, + "tcpconnectflood_time": 60, + "tcpconnectflood_count": 100, + "syndos_time": 60, + "syndos_count": 100 +} diff --git a/Demo/config/config-ids.json b/Demo/config/config-ids.json new file mode 100644 index 0000000..7b203bb --- /dev/null +++ b/Demo/config/config-ids.json @@ -0,0 +1,31 @@ +{ + "rules_dirpath": "/app/ids/rules", + "ifaces": ["br-c56b595383ad"], + "db_host": "172.20.3.10", + "db_database": "sidps", + "db_user": "sidps", + "db_password": "SUPERPASSWORD", + "db_port": "3306", + "cef_version": 1, + "device_product": "Sonde IDS", + "device_vendor": "ArKa", + "device_version": "vAlpha", + "synscan_time": 180, + "synscan_count": 5, + "tcpconnectscan_time": 180, + "tcpconnectscan_count": 5, + "ackscan_time": 180, + "ackscan_count": 5, + "finscan_time": 180, + "finscan_count": 5, + "nullscan_time": 180, + "nullscan_count": 5, + "xmasscan_time": 180, + "xmasscan_count": 5, + "synflood_time": 60, + "synflood_count": 100, + "tcpconnectflood_time": 60, + "tcpconnectflood_count": 100, + "syndos_time": 60, + "syndos_count": 100 +} diff --git a/Demo/docker-compose.yml b/Demo/docker-compose.yml index 9180621..0811914 100644 --- a/Demo/docker-compose.yml +++ b/Demo/docker-compose.yml @@ -20,7 +20,6 @@ services: context: .. dockerfile: Demo/Dockerfiles/Dockerfile.idps container_name: idps - command: sleep infinity cap_add: - NET_ADMIN - NET_RAW @@ -39,7 +38,6 @@ services: context: .. dockerfile: Demo/Dockerfiles/Dockerfile.cible container_name: cible - command: sleep infinity cap_add: - NET_ADMIN networks: @@ -67,7 +65,6 @@ services: context: .. dockerfile: Demo/Dockerfiles/Dockerfile.ids container_name: ids - command: sleep infinity cap_add: - NET_ADMIN - NET_RAW diff --git a/README.md b/README.md index d8bd344..28207bb 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,20 @@ Pour lancer cette démonstration, il faudra avoir `docker` & `docker compose` d' ```bash cd Demo/ -docker compose up -d +./deploy.sh ``` -## TODO +La cible (172.20.2.3) héberge un serveur web apache avec la page par défaut sur son port 80. +Les conteneurs attaquants disposent tous les deux de nmap et de hping3 pour réaliser des scan et des floods / DOS. + +Rappel des commandes pour flood avec et sans charge utile avec hping3: + +```bash +hping3 -S --flood IP +hping3 -S --flood -d TAILLE IP +``` + +## TODO: -- Noyau d'analyse de l'IDS -- Interface web pour visualiser les alertes / rechercher dedans - Moteur de corrélation des alertes (récupération + renvoi dans MySQL). +- Moteur de détection par comportement diff --git a/config.json b/config.json index e028151..02f0cb8 100644 --- a/config.json +++ b/config.json @@ -21,5 +21,11 @@ "nullscan_time": 180, "nullscan_count": 5, "xmasscan_time": 180, - "xmasscan_count": 5 + "xmasscan_count": 5, + "synflood_time": 60, + "synflood_count": 100, + "tcpconnectflood_time": 60, + "tcpconnectflood_count": 100, + "syndos_time": 60, + "syndos_count": 100 } diff --git a/idps/main.py b/idps/main.py index 664bb47..08934a1 100644 --- a/idps/main.py +++ b/idps/main.py @@ -94,7 +94,7 @@ def packet_callback(packet, rules_functions, tcp_packets, db): #print(packet) if IP in packet and TCP in packet: tcp_packets.add_packet(packet[IP].src, packet[TCP].sport, packet[IP].dst, packet[TCP].dport, packet[TCP].flags, time.time()) - print(tcp_packets[packet[IP].src]) + #print(tcp_packets[packet[IP].src]) check_frame_w_rules(packet, rules_functions['TCP'], tcp_packets, db) tcp_packets.clean_old_packets() diff --git a/idps/rules/TCP/DOS/syndos.py b/idps/rules/TCP/DOS/syndos.py new file mode 100644 index 0000000..54480e9 --- /dev/null +++ b/idps/rules/TCP/DOS/syndos.py @@ -0,0 +1,36 @@ +from datetime import datetime +import time + + +def rule(packet, tcp_packets, db): + """ + Règle SYN Dos: + Un SYN DOS va envoyer des requêtes TCP avec le flag SYN en très grand nombre afin de surcharger le serveur ou la cible avec des grosses quantités de données + - Si le port est ouvert, le serveur répond avec: SYN-ACK, puis le client RESET la connexion. + - Si le port est fermé, le serveur répond avec: RST-ACK. + """ + + # Ne pas réagir si dans la période de cooldown + if (rule.cooldown + rule.time_window > time.time()): + return + + # Initialisation des paramètres à partir de la configuration si nécessaire + if (rule.seuil == 0 and rule.time_window == 0): + rule.time_window = db.get_key("synsdos_time", 60) + rule.seuil = db.get_key("syndos_count", 100) + + # Comptage des paquets TCP correspondant aux motifs spécifiques + syndeny_count = tcp_packets.count_packet_of_type(["S", "RA"], rule.time_window, True) + synaccept_count = tcp_packets.count_packet_of_type(["S", "SA", "R"], rule.time_window, True) + + # Détection si le seuil est dépassé et que la charge utile des paquets est non nulle + if (syndeny_count + synaccept_count >= rule.seuil and len(packet['TCP'].payload) > 0): + db.send_alert(datetime.now(), 5, None, "Syn DOS", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de Syn->SynACK->Reset et Syn->Reset ACK", act="Alerte") + print("Alerte, seuil dépassé, risque de Syn DOS détecté.") + rule.cooldown = time.time() + + +# Variables statiques +rule.cooldown = 0 +rule.time_window = 0 +rule.seuil = 0 diff --git a/idps/rules/TCP/DOS/synflood.py b/idps/rules/TCP/DOS/synflood.py new file mode 100644 index 0000000..520f9f5 --- /dev/null +++ b/idps/rules/TCP/DOS/synflood.py @@ -0,0 +1,36 @@ +from datetime import datetime +import time + + +def rule(packet, tcp_packets, db): + """ + Règle SYN Flood: + Un SYN Flood va envoyer des requêtes TCP avec le flag SYN en très grand nombre afin de surcharger le serveur ou la cible + - Si le port est ouvert, le serveur répond avec: SYN-ACK, puis le client RESET la connexion. + - Si le port est fermé, le serveur répond avec: RST-ACK. + """ + + # Ne pas réagir si dans la période de cooldown + if (rule.cooldown + rule.time_window > time.time()): + return + + # Initialisation des paramètres à partir de la configuration si nécessaire + if (rule.seuil == 0 and rule.time_window == 0): + rule.time_window = db.get_key("synsflood_time", 60) + rule.seuil = db.get_key("synflood_count", 100) + + # Comptage des paquets TCP correspondant aux motifs spécifiques + syndeny_count = tcp_packets.count_packet_of_type(["S", "RA"], rule.time_window, True) + synaccept_count = tcp_packets.count_packet_of_type(["S", "SA", "R"], rule.time_window, True) + + # Détection si le seuil est dépassé + if (syndeny_count + synaccept_count >= rule.seuil): + db.send_alert(datetime.now(), 5, None, "Syn flood", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de Syn->SynACK->Reset et Syn->Reset ACK", act="Alerte") + print("Alerte, seuil dépassé, risque de Syn Flood détecté.") + rule.cooldown = time.time() + + +# Variables statiques +rule.cooldown = 0 +rule.time_window = 0 +rule.seuil = 0 diff --git a/idps/rules/TCP/DOS/tcpconnectflood.py b/idps/rules/TCP/DOS/tcpconnectflood.py new file mode 100644 index 0000000..ddb34e2 --- /dev/null +++ b/idps/rules/TCP/DOS/tcpconnectflood.py @@ -0,0 +1,34 @@ +from datetime import datetime +import time + + +def rule(packet, tcp_packets, db): + """Règle TCPConnect Flood: + Un flood TCP connect va effectuer une connexion TCP en très grand nombre + Si le port est ouvert le serveur acceptera la connexion SYN -> SYN ACK -> ACK -> Reset ACK + Sinon le port est fermé et le serveur refusera la connexion SYN -> Reset ACK + """ + + if (rule.cooldown + rule.time_window > time.time()): + return + + # Vérification si nécessaire de récupérer les variables depuis la config + if (rule.seuil == 0 and rule.time_window == 0): + rule.time_window = db.get_key("tcpconnectflood_time", 60) + rule.seuil = db.get_key("tcpconnectflood_count", 100) + + # Comptage du nombre de scan tcp connect acceptés et refusés + tcpconnectdeny_count = tcp_packets.count_packet_of_type(["S", "RA"], rule.time_window, True) + tcpconnectaccept_count = tcp_packets.count_packet_of_type(["S", "SA", "A", "RA"], rule.time_window, True) + + if (tcpconnectaccept_count + tcpconnectdeny_count >= rule.seuil): + db.send_alert(datetime.now(), 5, None, "TCPConnect Flood", 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 TCPconnect Flood") + rule.cooldown = time.time() + + +# Variables statiques +rule.cooldown = 0 +rule.time_window = 0 +rule.seuil = 0 + diff --git a/idps/rules/TCP/Scan/ackscan.py b/idps/rules/TCP/Scan/ackscan.py index c210738..3b321f5 100644 --- a/idps/rules/TCP/Scan/ackscan.py +++ b/idps/rules/TCP/Scan/ackscan.py @@ -16,7 +16,11 @@ def rule(packet, tcp_packets, db): rule.time_window = db.get_key("ackscan_time", 180) rule.seuil = db.get_key("ackscan_count", 5) - if tcp_packets.count_packet_of_type(["A", "R"], rule.time_window, True) + tcp_packets.count_packet_of_type(["A"], rule.time_window, True) >= rule.seuil: + # Comptage nombre de scan ack acceptés et refusés + ackdeny_count = tcp_packets.count_packet_of_type(["A", "R"], rule.time_window, True) + ackaccept_count = tcp_packets.count_packet_of_type(["A"], rule.time_window, True) + + if (ackaccept_count + ackdeny_count >= rule.seuil): db.send_alert(datetime.now(), 5, None, "ACK scan", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de Ack->Reset et Ack pas de réponse", act="Alerte") print(f"Alerte, seuil dépassés, risque d'Ack scan") rule.cooldown = time.time() diff --git a/idps/rules/TCP/Scan/finscan.py b/idps/rules/TCP/Scan/finscan.py index 3ecf5f5..d6c4ae9 100644 --- a/idps/rules/TCP/Scan/finscan.py +++ b/idps/rules/TCP/Scan/finscan.py @@ -16,7 +16,11 @@ def rule(packet, tcp_packets, db): rule.time_window = db.get_key("finscan_time", 180) rule.seuil = db.get_key("finscan_count", 5) - if tcp_packets.count_packet_of_type(["F", "RA"], rule.time_window, True) + tcp_packets.count_packet_of_type(["F"], rule.time_window, True) >= rule.seuil: + # Comptage du nombre de scan fin acceptés et refusés + findeny_count = tcp_packets.count_packet_of_type(["F", "RA"], rule.time_window, True) + finaccept_count = tcp_packets.count_packet_of_type(["F"], rule.time_window, True) + + if (findeny_count + finaccept_count >= rule.seuil): db.send_alert(datetime.now(), 5, None, "Fin scan", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de Fin->Reset Ack et Fin->rien", act="Alerte") print(f"Alerte, seuil dépassés, risque de Fin Scan") rule.cooldown = time.time() diff --git a/idps/rules/TCP/Scan/nullscan.py b/idps/rules/TCP/Scan/nullscan.py index 7b373e2..6c686cb 100644 --- a/idps/rules/TCP/Scan/nullscan.py +++ b/idps/rules/TCP/Scan/nullscan.py @@ -16,7 +16,11 @@ def rule(packet, tcp_packets, db): rule.time_window = db.get_key("nullscan_time", 180) rule.seuil = db.get_key("nullscan_count", 5) - if tcp_packets.count_packet_of_type([""], rule.time_window, True) + tcp_packets.count_packet_of_type(["", "RA"], rule.time_window, True) >= rule.seuil: + # Comptage du nombre de scan null acceptés et refusés + nulldeny_count = tcp_packets.count_packet_of_type(["", "RA"], rule.time_window, True) + nullaccept_count = tcp_packets.count_packet_of_type([""], rule.time_window, True) + + if (nulldeny_count + nulldeny_count >= rule.seuil): db.send_alert(datetime.now(), 5, None, "Null scan", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de None->Reset Ack et None -> rien", act="Alerte") print(f"Alerte, seuil dépassés, risque de Null Scan") rule.cooldown = time.time() diff --git a/idps/rules/TCP/Scan/synscan.py b/idps/rules/TCP/Scan/synscan.py index 3a6e3c4..9a5e5dc 100644 --- a/idps/rules/TCP/Scan/synscan.py +++ b/idps/rules/TCP/Scan/synscan.py @@ -3,7 +3,7 @@ import time def rule(packet, tcp_packets, db): - """Règle SYNScan: + """Règle SYN Scan: Un SYNScan va envoyer des requêtes TCP avec le flag SYN Si le port est ouvert alors le serveur répondra: Syn ACK, puis le client Reset la connexion Sinon le port est fermé et le serveur répondra: Reset ACK @@ -16,7 +16,11 @@ def rule(packet, tcp_packets, db): rule.time_window = db.get_key("synscan_time", 180) rule.seuil = db.get_key("synscan_count", 5) - if tcp_packets.count_packet_of_type(["S", "RA"], rule.time_window, True) + tcp_packets.count_packet_of_type(["S", "SA", "R"], rule.time_window, True) >= rule.seuil: + # Comptage du nombre de scan syn acceptés et refusés + syndeny_count = tcp_packets.count_packet_of_type(["S", "RA"], rule.time_window, True) + synaccept_count = tcp_packets.count_packet_of_type(["S", "SA", "R"], rule.time_window, True) + + if (synaccept_count + syndeny_count >= rule.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 et Syn->Reset ACK", act="Alerte") print(f"Alerte, seuil dépassés, risque de SynScan") rule.cooldown = time.time() diff --git a/idps/rules/TCP/Scan/tcpconnectscan.py b/idps/rules/TCP/Scan/tcpconnectscan.py index 3451fb0..69253bd 100644 --- a/idps/rules/TCP/Scan/tcpconnectscan.py +++ b/idps/rules/TCP/Scan/tcpconnectscan.py @@ -17,7 +17,11 @@ def rule(packet, tcp_packets, db): rule.time_window = db.get_key("tcpconnectscan_time", 180) rule.seuil = db.get_key("tcpconnectscan_count", 5) - if tcp_packets.count_packet_of_type(["S", "SA", "A", "RA"], rule.time_window, True) + tcp_packets.count_packet_of_type(["S", "RA"], rule.time_window, True) >= rule.seuil: + # Comptage du nombre de scan tcp connect acceptés et refusés + tcpconnectdeny_count = tcp_packets.count_packet_of_type(["S", "RA"], rule.time_window, True) + tcpconnectaccept_count = tcp_packets.count_packet_of_type(["S", "SA", "A", "RA"], rule.time_window, True) + + if (tcpconnectaccept_count + tcpconnectdeny_count >= rule.seuil): 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") rule.cooldown = time.time() @@ -25,5 +29,5 @@ def rule(packet, tcp_packets, db): # Variables statiques rule.cooldown = 0 -rule.time_window = 180 -rule.seuil = 5 +rule.time_window = 0 +rule.seuil = 0 diff --git a/idps/rules/TCP/Scan/xmasscan.py b/idps/rules/TCP/Scan/xmasscan.py index 4f811c5..17cd359 100644 --- a/idps/rules/TCP/Scan/xmasscan.py +++ b/idps/rules/TCP/Scan/xmasscan.py @@ -16,7 +16,11 @@ def rule(packet, tcp_packets, db): rule.time_window = db.get_key("xmasscan_time", 180) rule.seuil = db.get_key("xmasscan_count", 5) - if tcp_packets.count_packet_of_type(["FPU", "RA"], rule.time_window, True) + tcp_packets.count_packet_of_type(["FPU"], rule.time_window, True) >= rule.seuil: + # Comptage du nombre de scan XMAS acceptés et refusés + xmasdeny_count = tcp_packets.count_packet_of_type(["FPU", "RA"], rule.time_window, True) + xmasaccept_count = tcp_packets.count_packet_of_type(["FPU"], rule.time_window, True) + + if (xmasaccept_count + xmasdeny_count >= rule.seuil): db.send_alert(datetime.now(), 5, None, "XMAS scan", packet['IP'].src, packet['IP'].dst, proto="TCP", reason="Détection de nombreux patterns de Fin Push Urg -> rien et Fin Push Urg->Reset ACK", act="Alerte") print(f"Alerte, seuil dépassés, risque de XMAS Scan") rule.cooldown = time.time() diff --git a/idps/tcp.py b/idps/tcp.py index 0ee21f3..edbdf03 100644 --- a/idps/tcp.py +++ b/idps/tcp.py @@ -34,7 +34,6 @@ class TCP: i, ip = self.find_packet_to_replace(ip_src, port_src, ip_dst, port_dst, "S") if i is not None: - print(f"i: {i}, {ip_src}:{port_src}->{ip_dst}:{port_dst}, paquets: \n{self.packets}") self.packets[ip][i][3].append("SA") self.packets[ip][i][4] = timestamp return @@ -48,7 +47,6 @@ class TCP: i, ip = self.find_packet_to_replace(ip_src, port_src, ip_dst, port_dst, "R") if i is not None: - print(f"i: {i}, {ip_src}:{port_src}->{ip_dst}:{port_dst}, paquets: \n{self.packets}") self.packets[ip][i][3].append("A") self.packets[ip][i][4] = timestamp return @@ -63,7 +61,6 @@ class TCP: i, ip = self.find_packet_to_replace(ip_src, port_src, ip_dst, port_dst, "S") if i is not None: - print(f"i: {i}, {ip_src}:{port_src}->{ip_dst}:{port_dst}, paquets: \n{self.packets}") self.packets[ip][i][3].append("RA") self.packets[ip][i][4] = timestamp return @@ -78,7 +75,6 @@ class TCP: i, ip = self.find_packet_to_replace(ip_src, port_src, ip_dst, port_dst, "S") if i is not None: - print(f"i: {i}, {ip_src}:{port_src}->{ip_dst}:{port_dst}, paquets: \n{self.packets}") self.packets[ip][i][3].append("R") self.packets[ip][i][4] = timestamp return @@ -90,7 +86,6 @@ class TCP: i, ip = self.find_packet_to_replace(ip_src, port_src, ip_dst, port_dst, "A") if i is not None: - print(f"i: {i}, {ip_src}:{port_src}->{ip_dst}:{port_dst}, paquets: \n{self.packets}") self.packets[ip][i][3].append("F") self.packets[ip][i][4] = timestamp return @@ -98,8 +93,6 @@ class TCP: self.packets[ip_src].append([port_src, ip_dst, port_dst, ["F"], timestamp]) return - # TODO: ajout flag fin, none, fin urg push - def find_packet_to_replace(self, ip_src, port_src, ip_dst, port_dst, flags): """Cherche l'indice et le port de source du paquet dont le flag doit être remplacé"""