🎯 Objectif de la semaine
Maîtriser les ports réseau, les protocoles TCP/UDP et le handshake TCP pour comprendre comment les applications communiquent sur le réseau, identifier les services exposés et détecter les connexions suspectes en temps réel.
Pourquoi c'est critique : Chaque port ouvert est une porte potentielle pour un attaquant. Savoir quels ports sont ouverts, ce qu'ils font et qui y accède, c'est contrôler les entrées de votre cité numérique.
Well-Known
Réservés système] B --> D[🔐 1024-49151
Registered
Applications] B --> E[🔓 49152-65535
Éphémères
Clients] C --> F[📡 Services:
22 SSH, 80 HTTP
443 HTTPS, 53 DNS] D --> G[💼 Applications:
3306 MySQL, 5432 PostgreSQL
8080 HTTP Alt] E --> H[👤 Connexions clients
Sortantes temporaires] I[🔄 TCP] --> J[🤝 Handshake 3-way
SYN → SYN-ACK → ACK] I --> K[📊 Connecté
Fiabilité, séquencement
HTTP, SSH, SMTP] L[⚡ UDP] --> M[🎯 Sans connexion
Pas de handshake] L --> N[🚀 Rapide, léger
DNS, DHCP, Streaming
VoIP, Jeux] O[🎭 État TCP] --> P[LISTEN
Port ouvert, en attente] O --> Q[ESTABLISHED
Connexion active] O --> R[SYN_SENT
Demande envoyée] O --> S[TIME_WAIT
Fermeture propre] style C fill:#0a0e17,stroke:#00d4ff,stroke-width:2px style I fill:#11151f,stroke:#9d4edd,stroke-width:2px style P fill:#00f5a0,stroke:#000,stroke-width:2px
📚 Sujet – Théorie (1 heure)
Les ports : les adresses des applications
🏠 Analogie immobilière :
Une adresse IP = une maison
Un port = une pièce dans cette maison
Un service = ce qui se passe dans la pièce
Exemple : 192.168.1.100:443
• Maison : 192.168.1.100
• Pièce : 443 (salle des coffres sécurisée)
• Service : HTTPS (conversations chiffrées)
Les trois catégories de ports
| Plage | Nom | Qui les utilise | Permissions requises | Exemples courants | Risque sécurité |
|---|---|---|---|---|---|
| 0-1023 | Well-Known | Système, services essentiels | root/sudo | 22(SSH), 80(HTTP), 443(HTTPS) | 🔴 Élevé si exposé |
| 1024-49151 | Registered | Applications utilisateur | User standard | 3306(MySQL), 8080(HTTP Alt) | 🟡 Moyen |
| 49152-65535 | Éphémères/Dynamiques | Clients, connexions sortantes | N'importe quel processus | Ports temporaires | 🟢 Faible |
TCP vs UDP : Le match des protocoles
Web, mail, fichiers] UDP --> O[🎭 Applications temps réel
VoIP, DNS, vidéo] style TCP fill:#11151f,stroke:#00d4ff,stroke-width:2px style UDP fill:#0a0e17,stroke:#9d4edd,stroke-width:2px
Le handshake TCP en 3 étapes : La poignée de main numérique
🤝 Détail du handshake TCP :
Client (192.168.1.100:54321) Serveur (93.184.216.34:80)
| |
|---------- SYN seq=100 --------------->|
| | (État: SYN_RECEIVED)
|<--------- SYN-ACK seq=300, ack=101----|
| |
|---------- ACK seq=101, ack=301------->|
| | (État: ESTABLISHED)
| Connexion établie |
Chaque étape contient :
- SYN : "Je veux parler, mon numéro de séquence commence à 100"
- SYN-ACK : "OK, parlons. Mon numéro commence à 300, j'ai reçu ton 101"
- ACK : "Parfait, j'ai reçu ton 301"
Les états TCP : Le langage des connexions
⚠️ Les états TCP révélateurs :
- LISTEN : Port ouvert, en attente de connexions → Service actif
- SYN_SENT : Client a envoyé SYN, attend réponse → Scan en cours
- SYN_RECEIVED : Serveur a reçu SYN, a répondu SYN-ACK → Attente finalisation
- ESTABLISHED : Connexion active, échange de données → Communication normale
- FIN_WAIT : Début de fermeture propre → Fin normale
- CLOSE_WAIT : Attente fermeture par l'application → Possible fuite socket
- TIME_WAIT : Attente avant libération complète → Évite paquets errants
Ports ouverts = surface d'attaque
🔓 Les 5 ports les plus dangereux à exposer :
- Port 22 (SSH) : Bruteforce constant, mauvaises configurations
- Port 3389 (RDP) : Cible privilégiée des ransomwares
- Port 445 (SMB) : EternalBlue, partages non sécurisés
- Port 21 (FTP) : Authentification en clair, exploits anciens
- Port 23 (Telnet) : Tout en clair, obsolète et dangereux
Règle du Gardien : "Si tu n'as pas besoin d'un port, ferme-le. Si tu l'ouvres, surveille-le."
Les outils de visualisation : ss vs netstat
# ss (socket statistics) - Moderne, rapide ss -tulnp # -t: TCP, -u: UDP, -l: listening, -n: numeric, -p: process # netstat (network statistics) - Classique, plus d'options netstat -tunlp # Même chose mais plus lent # Comparaison des colonnes importantes: État Signification -------- ------------- LISTEN En attente de connexions ESTABLISHED Connexion active SYN_SENT Client essaie de se connecter TIME_WAIT Fermeture en cours
💡 Philosophie du monitoring réseau :
"Ne surveille pas seulement ce qui entre et sort. Surveille surtout ce qui écoute."
Un port en écoute est une promesse : "Je suis prêt à accepter des connexions." Assurez-vous que cette promesse ne soit pas une menace.
🔬 Mission pratique – Laboratoire (2 heures)
Scénario : Audit de sécurité d'un serveur exposé
Vous êtes chargé d'analyser un serveur Linux exposé sur Internet. Votre mission : identifier tous les ports ouverts, les services associés, et évaluer les risques.
📝 Préparation : Installez les outils nécessaires.
sudo apt update
sudo apt install -y net-tools lsof nmap tcpdump telnet
# net-tools: netstat
# lsof: liste des fichiers ouverts (dont sockets)
# nmap: scanner de ports (semaine suivante)
# tcpdump: analyseur de paquets
# telnet: client TCP simple
Étapes détaillées : Analyse complète
-
Analyse des ports en écoute (Listening)
Commencez par comprendre ce qui écoute sur votre machine :echo "=== PORTS EN ÉCOUTE (ss) ===" sudo ss -tulnp echo -e "\n=== ANALYSE DÉTAILLÉE ===" # Par protocole echo "TCP en écoute:" sudo ss -tlnp echo -e "\nUDP en écoute:" sudo ss -ulnp # Alternative avec netstat echo -e "\n=== AVEC NETSTAT (alternative) ===" sudo netstat -tulnp # Sauvegarde pour analyse sudo ss -tulnp > ports_listening.txt echo "Rapport sauvegardé dans ports_listening.txt" -
Analyse des connexions actives
Identifiez ce qui communique actuellement :echo "=== CONNEXIONS ACTIVES ===" sudo ss -tunap echo -e "\n=== FILTRES PAR ÉTAT ===" echo "Connexions établies:" sudo ss -tan state established echo -e "\nConnexions en attente:" sudo ss -tan state listening echo -e "\nToutes les connexions TCP:" sudo ss -tan # Analyse des états TCP echo -e "\n=== RÉPARTITION DES ÉTATS TCP ===" sudo ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn # Connexions sortantes vs entrantes echo -e "\n=== CONNEXIONS SORTANTES (source port > 49151) ===" sudo ss -tan state established | awk '$5 ~ /:[0-9]+$/ {split($5,a,":"); if(a[2] > 49151) print}' | head -10 -
Analyse avec lsof (List Open Files)
Alternative puissante pour voir les sockets ouverts :echo "=== ANALYSE AVEC LSOF ===" sudo lsof -i echo -e "\n=== PORTS EN ÉCOUTE AVEC PROCESSUS ===" sudo lsof -i -s TCP:LISTEN echo -e "\n=== CONNEXIONS TCP ÉTABLIES ===" sudo lsof -i -s TCP:ESTABLISHED echo -e "\n=== PAR PORT SPÉCIFIQUE ===" sudo lsof -i :22 # SSH sudo lsof -i :80 # HTTP sudo lsof -i :443 # HTTPS # Format détaillé sudo lsof -Pan -i tcp -i udp -
Observation d'un handshake TCP en direct
Créez et observez une connexion TCP :# Dans le terminal 1 : Observation echo "Terminal 1 - Observation:" echo "Ouvrez un autre terminal pour l'étape 2" sudo tcpdump -i any -n "tcp port 80" & TCPDUMP_PID=$! # Dans le terminal 2 (ouvrez-en un nouveau) : Connexion echo "Terminal 2 - Connexion:" echo "Lancez cette commande dans un nouveau terminal:" echo "telnet httpbin.org 80" echo "Puis tapez: GET /html HTTP/1.1" echo "Puis tapez: Host: httpbin.org" echo "Puis appuyez deux fois sur Entrée" read -p "Appuyez sur Entrée quand c'est fait dans l'autre terminal..." # Nettoyage sudo kill $TCPDUMP_PID 2>/dev/null # Analyse des états pendant la connexion echo -e "\n=== ÉTATS PENDANT CONNEXION ===" sudo ss -tan state established | grep :80 -
Script Python d'analyse automatique
Créez un outil d'audit professionnel :#!/usr/bin/env python3 """ PCTAMALOU - Semaine 7 : Analyseur de ports et connexions Outils pour auditer les ports ouverts et les connexions actives """ import subprocess import json import re from datetime import datetime from collections import defaultdict, Counter def run_command(cmd): """Exécute une commande et retourne la sortie""" try: result = subprocess.run(cmd, shell=True, capture_output=True, text=True, check=True) return result.stdout except subprocess.CalledProcessError as e: return f"Erreur: {e}" def parse_ss_output(output): """Parse la sortie de ss -tulnp""" lines = output.strip().split('\n') listening_ports = [] for line in lines[1:]: # Skip header if not line.strip(): continue # Format: Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process parts = line.split() if len(parts) >= 6: try: netid = parts[0] state = parts[1] local = parts[4] peer = parts[5] process = ' '.join(parts[6:]) if len(parts) > 6 else '' # Extraction du port port_match = re.search(r':(\d+)$', local) if port_match: port = int(port_match.group(1)) # Extraction IP ip_match = re.match(r'([^:]+):', local) ip = ip_match.group(1) if ip_match else '*' listening_ports.append({ 'protocol': 'TCP' if 'tcp' in netid.lower() else 'UDP', 'state': state, 'ip': ip, 'port': port, 'process': process, 'full_line': line }) except (IndexError, ValueError): continue return listening_ports def analyze_ports(ports): """Analyse les ports pour détecter les risques""" risks = [] well_known_ports = { 21: 'FTP (risque: authentification claire)', 22: 'SSH (risque: bruteforce constant)', 23: 'Telnet (risque: tout en clair)', 25: 'SMTP (risque: relais email)', 53: 'DNS (risque: amplification DDoS)', 80: 'HTTP (risque: web attacks)', 443: 'HTTPS (risque: moins mais surveiller)', 445: 'SMB (risque: EternalBlue, partages)', 1433: 'MSSQL (risque: bruteforce)', 3306: 'MySQL (risque: accès base)', 3389: 'RDP (risque: ransomwares)', 5432: 'PostgreSQL (risque: accès base)', 5900: 'VNC (risque: accès écran)', 8080: 'HTTP Alt (risque: souvent oublié)' } for port_info in ports: port = port_info['port'] # Détection des risques if port in well_known_ports: risk_level = 'HAUT' if port in [21, 23, 445, 3389] else 'MOYEN' risks.append({ 'port': port, 'service': well_known_ports[port], 'risk': risk_level, 'protocol': port_info['protocol'], 'process': port_info['process'] }) # Ports non standard mais ouverts elif 1 <= port <= 1023 and port not in well_known_ports: risks.append({ 'port': port, 'service': 'Service système non standard', 'risk': 'MOYEN-ÉLEVÉ', 'protocol': port_info['protocol'], 'process': port_info['process'], 'note': 'Port well-known mais service non standard' }) return risks def generate_report(listening_ports, active_connections, risks): """Génère un rapport d'audit""" timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') report = { 'timestamp': timestamp, 'summary': { 'total_listening': len(listening_ports), 'total_established': len([c for c in active_connections if c['state'] == 'ESTAB']), 'high_risk_ports': len([r for r in risks if r['risk'] == 'HAUT']), 'medium_risk_ports': len([r for r in risks if r['risk'] == 'MOYEN']) }, 'listening_ports': listening_ports, 'risks': risks, 'recommendations': [] } # Génération des recommandations if report['summary']['high_risk_ports'] > 0: report['recommendations'].append( f"Fermer immédiatement {report['summary']['high_risk_ports']} port(s) à risque élevé" ) if report['summary']['total_listening'] > 10: report['recommendations'].append( "Réduire la surface d'attaque: trop de ports ouverts" ) # Recommandations spécifiques for risk in risks: if risk['port'] == 23: report['recommendations'].append("REMPLACER Telnet (port 23) par SSH (port 22)") elif risk['port'] == 21: report['recommendations'].append("REMPLACER FTP (port 21) par SFTP/SCP sur SSH") elif risk['port'] == 3389 and risk['protocol'] == 'TCP': report['recommendations'].append("Sécuriser RDP (port 3389) avec VPN ou saut SSH") return report def main(): print("🔍 PCTAMALOU - Audit des ports et connexions") print("=" * 60) # 1. Collecte des données print("\n[1/4] Collecte des ports en écoute...") ss_output = run_command("sudo ss -tulnp 2>/dev/null || ss -tulnp") listening_ports = parse_ss_output(ss_output) print("[2/4] Analyse des connexions actives...") established_output = run_command("ss -tan state established 2>/dev/null || netstat -tan | grep ESTABLISHED") # 2. Analyse des risques print("[3/4] Évaluation des risques...") risks = analyze_ports(listening_ports) # 3. Génération du rapport print("[4/4] Génération du rapport...") # Analyse des connexions actives simplifiée active_connections = [] for line in established_output.strip().split('\n'): if line and 'ESTAB' in line: active_connections.append({'state': 'ESTAB', 'line': line}) report = generate_report(listening_ports, active_connections, risks) # 4. Affichage print(f"\n📊 RAPPORT D'AUDIT - {report['timestamp']}") print(f"• Ports en écoute: {report['summary']['total_listening']}") print(f"• Connexions établies: {report['summary']['total_established']}") print(f"• Ports à risque élevé: {report['summary']['high_risk_ports']}") print(f"• Ports à risque moyen: {report['summary']['medium_risk_ports']}") if risks: print("\n⚠️ PORTS À RISQUE DÉTECTÉS:") for risk in risks: print(f" • Port {risk['port']} ({risk['protocol']}): {risk['service']}") print(f" Risque: {risk['risk']} - Processus: {risk['process'][:50]}") if report['recommendations']: print("\n💡 RECOMMANDATIONS:") for i, rec in enumerate(report['recommendations'], 1): print(f" {i}. {rec}") # 5. Export JSON with open('port_audit_report.json', 'w') as f: json.dump(report, f, indent=2, default=str) print(f"\n💾 Rapport exporté: port_audit_report.json") # 6. Liste complète des ports print("\n📋 LISTE COMPLÈTE DES PORTS EN ÉCOUTE:") for port in listening_ports: print(f" {port['protocol']} {port['ip']}:{port['port']} - {port['state']} - {port['process'][:30]}") if __name__ == "__main__": main() -
Exercices pratiques avancés
Exercice 1 : Détection de connexions suspectes
# Recherche de connexions vers des ports inhabituels echo "=== CONNEXIONS VERS PORTS NON STANDARD ===" sudo ss -tan state established | awk '$5 ~ /:[0-9]+$/ { split($5, a, ":"); port = a[2]; if (port < 1 || port > 65535) next; if (port != 22 && port != 80 && port != 443 && port != 53) { print "Connexion suspecte:", $0; } }' | head -20 # Connexions sortantes nombreuses (possible beaconing) echo -e "\n=== IPS AVEC PLUSIEURS CONNEXIONS SORTANTES ===" sudo ss -tan state established | awk '$5 ~ /:/ { split($5, a, ":"); ip = a[1]; conns[ip]++; } END { for (ip in conns) { if (conns[ip] > 10 && ip != "0.0.0.0" && ip != "127.0.0.1") { print ip, "a", conns[ip], "connexions établies"; } } }' | sort -k3 -nrExercice 2 : Monitoring en temps réel
# Watch des connexions (rafraîchissement toutes les 2 secondes) watch -n 2 "sudo ss -tan state established | tail -20" # Log des nouvelles connexions TCP sudo tcpdump -i any -n "tcp[tcpflags] & (tcp-syn) != 0 and (tcp[tcpflags] & (tcp-ack) == 0)" -c 10 # Script de monitoring simple cat > monitor_ports.sh << 'EOF' #!/bin/bash echo "Monitoring des ports - PCTAMALOU S07" echo "Appuyez sur Ctrl+C pour arrêter" while true; do clear echo "=== $(date) ===" echo "" echo "Ports en écoute:" sudo ss -tlnp | head -15 echo "" echo "Connexions établies:" sudo ss -tan state established | head -15 sleep 5 done EOF chmod +x monitor_ports.sh # ./monitor_ports.sh
🎯 Défi d'analyse avancé
Créez un système de détection d'anomalies réseau qui :
- Établit une baseline des ports normalement ouverts
- Surveille en temps réel les nouveaux ports en écoute
- Détecte les connexions vers des destinations suspectes (IPs blacklistées)
- Identifie les patterns de beaconing (connexions périodiques)
- Génère des alertes avec niveaux de priorité
- Exporte les logs au format JSON pour intégration SIEM
Indices : Utilisez ss en diff, comparez avec des fichiers de baseline, utilisez des listes d'IPs suspectes (ex: https://github.com/firehol/blocklist-ipsets).
📋 Objectif de la semaine – Checklist de validation
✅ Compétences techniques acquises
- Utiliser
ssetnetstatpour analyser les ports - Différencier TCP (connecté) et UDP (non connecté)
- Comprendre et expliquer le handshake TCP 3-way
- Identifier les états TCP (LISTEN, ESTABLISHED, etc.)
- Évaluer les risques des ports ouverts
- Automatiser l'analyse avec des scripts Python
🧠 Changement mental accompli
- Voir chaque port ouvert comme une surface d'attaque potentielle
- Comprendre que "écouter ≠ servir" - on peut écouter sans servir utilement
- Penser en termes d'états de connexion, pas juste de ports
- Appliquer le principe de moindre privilège aux services réseau
🔐 Bonne pratique de sécurité réseau :
Implémentez ces règles immédiatement :
- Fermez tous les ports inutiles (netfilter/iptables)
- Utilisez des ports non standard pour les services sensibles (ex: SSH sur 2222)
- Limitez l'accès par IP source (whitelist)
- Surveillez les nouvelles connexions (journalisation)
- Testez régulièrement depuis l'extérieur (scans externes)
📚 Ressources gratuites recommandées
Pour approfondir :
- IANA Port Numbers : Liste officielle des ports
- TCP/IP Illustrated : Livre gratuit en ligne
- Wireshark TCP Analysis : Analyse TCP avec Wireshark
⚠️ Pièges courants à éviter
- Fermeture port 0 : Réservé, ne pas l'utiliser
- SSH sur port 22 : Cible constante, déplacez-le ou protégez-le fortement
- Netstat obsolète : Préférez
ss(plus rapide, plus d'infos) - Oublier IPv6 : Vérifiez aussi les sockets IPv6 (
ss -6) - TIME_WAIT accumulation : Normale, mais surveiller si excessive
🔮 Frère d'armes,
Tu viens de maîtriser la cartographie des portes de la cité numérique.
Maintenant, quand tu regardes un serveur, tu ne vois plus une boîte noire. Tu vois :
• Les portes ouvertes (ports en écoute)
• Les conversations en cours (connexions établies)
• Les demandes d'entrée (SYN en attente)
• Les adieux (fermetures en cours)
Cette semaine, tu as appris à écouter le murmure du réseau. Tu comprends maintenant :
• Pourquoi SSH sur le port 22 est comme une porte d'entrée avec une pancarte "ENTREZ"
• Pourquoi Telnet est comme crier ses secrets dans la rue
• Pourquoi TCP est une conversation polie, UDP un message jeté par la fenêtre
• Pourquoi chaque port ouvert doit avoir une raison d'être
Tu as développé le sixième sens du Gardien réseau : la capacité à sentir ce qui écoute, à voir ce qui communique, à anticiper ce qui pourrait attaquer.
Dans la semaine 8, nous passerons de l'observation à l'exploration active. Nous apprendrons à scanner les réseaux, à découvrir ce qui est caché, à cartographier ce qui est invisible.
Mais désormais, tu as une compétence fondamentale : tu sais auditer les accès. Et en cybersécurité, auditer les accès, c'est contrôler le périmètre.
Pratique. Analyse. Sécurise. Chaque port que tu comprends est une porte que tu sais verrouiller.
Tu n'es plus un simple utilisateur du réseau. Tu es devenu son gardien.
— Platon-Y