feat: Semaine 9
This commit is contained in:
@@ -0,0 +1 @@
|
||||
3.12
|
||||
@@ -0,0 +1,3 @@
|
||||
```
|
||||
uv add pyftpdlib
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
from scapy.all import rdpcap, TCP, UDP, ICMP, ARP
|
||||
|
||||
packets = rdpcap("ultimate.pcapng")
|
||||
protocols = {"TCP": TCP, "UDP": UDP, "ICMP": ICMP, "ARP": ARP}
|
||||
|
||||
stats = {name: 0 for name in [*protocols, "Others"]}
|
||||
|
||||
for packet in packets:
|
||||
for name, layer in protocols.items():
|
||||
if packet.haslayer(layer):
|
||||
stats[name] += 1
|
||||
break
|
||||
stats["Others"] += 1
|
||||
|
||||
print("Répartition par protocole")
|
||||
for proto, count in stats.items():
|
||||
if count > 0:
|
||||
print(f"{proto:6} : {count} paquets.")
|
||||
@@ -0,0 +1,7 @@
|
||||
from ftplib import FTP
|
||||
|
||||
ftp = FTP()
|
||||
ftp.connect("127.0.0.1", 2121)
|
||||
ftp.login("John", "P4ssword!")
|
||||
print("Connecté au serveur.")
|
||||
ftp.quit()
|
||||
@@ -0,0 +1,42 @@
|
||||
import cv2
|
||||
import os
|
||||
|
||||
DOSSIER_IMAGES = "./images_extraites"
|
||||
DOSSIER_VISAGES = "./visages_detectes"
|
||||
|
||||
def detecter_visages(dossier_src=DOSSIER_IMAGES, dossier_dst=DOSSIER_VISAGES):
|
||||
os.makedirs(dossier_dst, exist_ok=True)
|
||||
modele = cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
|
||||
detecteur = cv2.CascadeClassifier(modele)
|
||||
compteur = 0
|
||||
|
||||
for nom_fichier in os.listdir(dossier_src):
|
||||
if not nom_fichier.lower().endswith((".jpg", ".jpeg", ".png")):
|
||||
continue
|
||||
|
||||
chemin = os.path.join(dossier_src, nom_fichier)
|
||||
image = cv2.imread(chemin)
|
||||
if image is None:
|
||||
continue
|
||||
|
||||
gris = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
visages = detecteur.detectMultiScale(gris, scaleFactor=1.05, minNeighbors=4, minSize=(20, 20))
|
||||
|
||||
if len(visages) == 0:
|
||||
print(f" {nom_fichier} : aucun visage")
|
||||
continue
|
||||
|
||||
print(f" {nom_fichier} : {len(visages)} visage(s) détecté(s)")
|
||||
|
||||
for (x, y, largeur, hauteur) in visages:
|
||||
cv2.rectangle(image, (x, y), (x + largeur, y + hauteur), (0, 255, 0), 2)
|
||||
|
||||
chemin_sortie = os.path.join(dossier_dst, nom_fichier)
|
||||
cv2.imwrite(chemin_sortie, image)
|
||||
compteur += 1
|
||||
|
||||
print(f"\n{compteur} images avec visages sauvegardées dans {dossier_dst}/")
|
||||
|
||||
if __name__ == "__main__":
|
||||
detecter_visages()
|
||||
@@ -0,0 +1,3 @@
|
||||
from collections import namedtuple
|
||||
|
||||
Response = namedtuple("Response", ["header"])
|
||||
@@ -0,0 +1,16 @@
|
||||
import re # RegEx
|
||||
|
||||
def extract_header(payload):
|
||||
try:
|
||||
header_brut = payload[:payload.index(b"\r\n\r\n") + 2]
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
header = dict(re.findall(
|
||||
r"(?P<cle>.*?): (?P<valeur>.*?)\r\n",
|
||||
header_brut.decode(errors="ignore")
|
||||
))
|
||||
|
||||
if "Content-Type" not in header:
|
||||
return None
|
||||
return header
|
||||
@@ -0,0 +1,36 @@
|
||||
from scapy.all import TCP
|
||||
|
||||
class Extracteur:
|
||||
def __init__(self, fichier_pcap):
|
||||
pcap = rdpcap(fichier_pcap)
|
||||
self.sessions = pcap.sessions()
|
||||
self.responses = []
|
||||
|
||||
def trouver_reponses(self):
|
||||
for session in self.sessions:
|
||||
payload = b""
|
||||
for paquet in self.sessions[session]:
|
||||
try:
|
||||
if paquet[TCP].dport == 80 or paquet[TCP].sport == 80:
|
||||
payload += bytes(paquet[TCP].payload)
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
if payload:
|
||||
header = extract_header(payload)
|
||||
if header is None:
|
||||
continue
|
||||
self.responses.append(Response(header=header, payload=payload))
|
||||
|
||||
def ecrire_images(self):
|
||||
os.makedirs(DOSSIER_SORTIE, exist_ok=True)
|
||||
compteur = 0
|
||||
for response in self.responses:
|
||||
contenu, content_type = extract_content(response)
|
||||
if contenu and content_type:
|
||||
nom = os.path.join(DOSSIER_SORTIE, f"image_{compteur}.{content_type}")
|
||||
with open(nom, "wb") as f:
|
||||
f.write(contenu)
|
||||
print(f" {nom}")
|
||||
compteur += 1
|
||||
print(f"\n{compteur} images extraites")
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
[project]
|
||||
name = "scappy-test"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"pyftpdlib>=2.2.0",
|
||||
"scapy>=2.7.0",
|
||||
]
|
||||
@@ -0,0 +1,14 @@
|
||||
from pyftpdlib.handlers import FTPHandler
|
||||
|
||||
from pyftpdlib.authorizers import DummyAuthorizer
|
||||
from pyftpdlib.servers import FTPServer
|
||||
|
||||
authorizer = DummyAuthorizer()
|
||||
authorizer.add_user("John", "P4ssword!", ".", perm="r")
|
||||
|
||||
handler = FTPHandler
|
||||
handler.authorizer = authorizer
|
||||
|
||||
server = FTPServer(("127.0.0.1", 2121), handler)
|
||||
print("Serveur FTP démarré")
|
||||
server.serve_forever()
|
||||
@@ -0,0 +1 @@
|
||||
from scapy.all import sniff, conf, DNSQR, DNS,
|
||||
@@ -0,0 +1,28 @@
|
||||
import platform
|
||||
from scapy.all import sniff, TCP, IP, conf, get_if_list
|
||||
from scapy.packet import Packet
|
||||
|
||||
conf.sniff_promisc = False
|
||||
system = platform.system()
|
||||
|
||||
# Interface de déboguage (si le nom de l'adaptateur n'est pas celui renseigné plus bas)
|
||||
# print("Interfaces disponibles:")
|
||||
# for iface in get_if_list():
|
||||
# print(f" - {iface}")
|
||||
|
||||
match system:
|
||||
case "Darwin": # MacOS
|
||||
lo = "lo0"
|
||||
case "Windows":
|
||||
lo = "\\Device\\NPF_Loopback"
|
||||
case _: # Certainement du Linux
|
||||
lo = "lo"
|
||||
|
||||
def detecter_credentials(paquet: Packet):
|
||||
if paquet.haslayer(TCP) and paquet[TCP].payload:
|
||||
payload = bytes(paquet[TCP].payload).decode(errors="ignore")
|
||||
if payload.startswith("USER ") or payload.startswith("PASS "):
|
||||
print(f"{paquet[IP].src} => {paquet[IP].dst}")
|
||||
print(payload.strip())
|
||||
|
||||
sniff(filter= "tcp port 2121", iface= lo, prn= detecter_credentials, store= 0)
|
||||
@@ -0,0 +1,35 @@
|
||||
from scapy.all import IP, ICMP, sr1, conf, TCP, ARP, Ether, srp, UDP, DNS, DNSQR, Packet
|
||||
|
||||
conf.sniff_promisc = False
|
||||
|
||||
cible = "79.137.78.240" # datafrance.fr, le site de Rachid
|
||||
ports = [22, 80, 443, 8080, 3306]
|
||||
|
||||
# __truediv__
|
||||
for port in ports:
|
||||
paquet = IP(dst= cible) / TCP(dport= port, flags= 'S')
|
||||
reponse = sr1(paquet, timeout= 1, verbose= 0)
|
||||
|
||||
if reponse and reponse[TCP].flags == 'SA': # SYN-ACK, le serveur répond "oui" aux connexions
|
||||
print(f"Port {port}: ouvert")
|
||||
else:
|
||||
print(f"Port {port}: fermé ou filtré")
|
||||
|
||||
|
||||
paquet = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst="192.168.1.0/24") # Ether : adresse Broadcast (tous les appareils) / ARP : "qui a cette adresse ?"
|
||||
reponses, _ = srp(paquet, timeout= 2, verbose= 0)
|
||||
print(f"{len(reponses)} hôtes détectés: ")
|
||||
|
||||
for envoi, reception in reponses:
|
||||
print(f"{reception.psrc} -> {reception.hwsrc}")
|
||||
|
||||
|
||||
requete = IP(dst= '1.1.1.1') / UDP(dport= 53) / DNS(
|
||||
rd= 1, # Recursive Desired (demande une réponse)
|
||||
qd= DNSQR(qname= "datafrance.fr") # Résolution de datafrance.fr
|
||||
)
|
||||
|
||||
reponse = sr1(requete, timeout= 2, verbose= 0)
|
||||
if reponse and reponse.haslayer(DNS):
|
||||
for i in range(reponse[DNS].ancount):
|
||||
print(reponse[DNS].an[i].rdata) # rdata : Response Data
|
||||
Binary file not shown.
Generated
+58
@@ -0,0 +1,58 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "pyasynchat"
|
||||
version = "1.0.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyasyncore" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ec/d2/b41df9021c12ca314146abcde7bdd3d9d37d44cc01559d7f13df459ee586/pyasynchat-1.0.5.tar.gz", hash = "sha256:36665473ae730dac51e6d7dad70f8295962120c830ab692f0a31efba32687e24", size = 9959, upload-time = "2026-01-05T20:05:27.712Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/48/e8/e5ad498cb6a834c16af910e259926fd545dd7873a2da451f3a2bb228d7ee/pyasynchat-1.0.5-py3-none-any.whl", hash = "sha256:35b7859515693e479e8d95ebe9f32cbf4d6312ab7599ced39fc24699e51de46f", size = 7869, upload-time = "2026-01-05T20:05:26.613Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyasyncore"
|
||||
version = "1.0.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4e/43/035dfe0cb01687c1940fdc008f46a43c41067e226e862df49327469764a0/pyasyncore-1.0.5.tar.gz", hash = "sha256:dd483d5103a6d59b66b86e0ca2334ad43dca732ff23a0ac5d63c88c52510542e", size = 15854, upload-time = "2026-01-05T19:59:31.893Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/ab/b10cee56269ae150763f3f83b3e9305a11f42f50b3dcd58eeb8f7988f0bb/pyasyncore-1.0.5-py3-none-any.whl", hash = "sha256:269bbc5252671827387636822841a1fb721ec6e858b23a3e12cf92eb1f97da2a", size = 10237, upload-time = "2026-01-05T19:59:30.824Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyftpdlib"
|
||||
version = "2.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyasynchat" },
|
||||
{ name = "pyasyncore" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f9/42/8751c5f58ae59b09e070da4fa322ae9693a340d2cc456b5a380b2c1ee47a/pyftpdlib-2.2.0.tar.gz", hash = "sha256:4ba0642078792df63dd3b2e9c8f838f2a3ecf428c7518d5921c0530d53512acf", size = 189150, upload-time = "2026-02-07T23:09:26.519Z" }
|
||||
|
||||
[[package]]
|
||||
name = "scappy-test"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "pyftpdlib" },
|
||||
{ name = "scapy" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "pyftpdlib", specifier = ">=2.2.0" },
|
||||
{ name = "scapy", specifier = ">=2.7.0" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scapy"
|
||||
version = "2.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/82/97/7caec64f05eae3d305d83e7cce1ef2f337710513b89efb334f7278202e79/scapy-2.7.0.tar.gz", hash = "sha256:bfc1ef1b93280aea1ddee53be7f74232aa28ac3d891244d41ee85200d24aa446", size = 2412897, upload-time = "2025-12-26T22:10:53.359Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/6f/bd32e5e8adc391063858da17271bb444e4b009842cffa593bca8b2b78af7/scapy-2.7.0-py3-none-any.whl", hash = "sha256:eb22786da92be6fd8e5c694ae5595e4f5b9ac1f4364c9c45986844f3e3063561", size = 2590982, upload-time = "2025-12-26T22:07:48.941Z" },
|
||||
]
|
||||
Reference in New Issue
Block a user