Sécurité des Systèmes Embarqués
Apprenez les principes de sécurité pour protéger les objets connectés : chiffrement, authentification, vulnérabilités et bonnes pratiques de développement sécurisé
En 2016, le botnet Mirai a infecté plus de 600 000 objets connectés (caméras, routeurs) en exploitant des mots de passe par défaut, provoquant une panne Internet massive. La sécurité des systèmes embarqués n'est pas une option, c'est une nécessité absolue !
Objectifs d'apprentissage
- Comprendre les enjeux de sécurité des systèmes embarqués
- Identifier les principales vulnérabilités des objets connectés
- Maîtriser les bases du chiffrement symétrique et asymétrique
- Implémenter une authentification sécurisée
- Appliquer les bonnes pratiques de développement sécurisé
Erreurs courantes à éviter
- Utiliser des mots de passe par défaut (admin/admin)
- Transmettre des données sensibles en clair (sans chiffrement)
- Stocker des clés de chiffrement en dur dans le code
- Négliger les mises à jour de sécurité du firmware
Contenu du cours
# Simulation de détection de vulnérabilités IoT
# Scanner de sécurité basique pour objets connectés
import hashlib
import random
import re
class ScannerSecuriteIoT:
"""Simule un scanner de vulnérabilités pour IoT"""
# Mots de passe faibles courants
MOTS_DE_PASSE_FAIBLES = [
"admin", "password", "12345", "123456", "root",
"default", "guest", "admin123", "password123",
"1234", "user", "test", "changeme", "00000000"
]
# Ports dangereux
PORTS_DANGEREUX = {
21: "FTP (transfert fichiers non chiffré)",
23: "Telnet (accès distant non chiffré)",
80: "HTTP (web non chiffré)",
8080: "HTTP alternatif",
502: "Modbus (protocole industriel non sécurisé)",
1883: "MQTT sans TLS"
}
def __init__(self):
self.vulnerabilites = []
self.score_securite = 100
def verifier_mot_de_passe(self, mot_de_passe):
"""Analyse la force d'un mot de passe"""
problemes = []
# Longueur minimale
if len(mot_de_passe) < 8:
problemes.append("Trop court (< 8 caractères)")
self.score_securite -= 15
# Mot de passe commun
if mot_de_passe.lower() in self.MOTS_DE_PASSE_FAIBLES:
problemes.append("Mot de passe trop commun/par défaut")
self.score_securite -= 30
# Complexité
if not re.search(r'[A-Z]', mot_de_passe):
problemes.append("Pas de majuscule")
self.score_securite -= 5
if not re.search(r'[0-9]', mot_de_passe):
problemes.append("Pas de chiffre")
self.score_securite -= 5
if not re.search(r'[!@#$%^&*(),.?":{}|<>]', mot_de_passe):
problemes.append("Pas de caractère spécial")
self.score_securite -= 5
if problemes:
self.vulnerabilites.append({
'type': 'MOT_DE_PASSE_FAIBLE',
'severite': 'CRITIQUE' if len(problemes) > 2 else 'HAUTE',
'details': problemes
})
return len(problemes) == 0
def scanner_ports(self, ports_ouverts):
"""Analyse les ports ouverts"""
ports_problematiques = []
for port in ports_ouverts:
if port in self.PORTS_DANGEREUX:
ports_problematiques.append({
'port': port,
'service': self.PORTS_DANGEREUX[port]
})
self.score_securite -= 10
if ports_problematiques:
self.vulnerabilites.append({
'type': 'PORTS_NON_SECURISES',
'severite': 'HAUTE',
'details': ports_problematiques
})
return len(ports_problematiques) == 0
def verifier_chiffrement(self, protocole_utilise):
"""Vérifie l'utilisation du chiffrement"""
protocoles_securises = ['HTTPS', 'TLS', 'SSL', 'MQTTS', 'WSS', 'SSH']
protocoles_non_securises = ['HTTP', 'FTP', 'Telnet', 'MQTT']
if protocole_utilise.upper() in protocoles_non_securises:
self.vulnerabilites.append({
'type': 'TRANSFERT_NON_CHIFFRE',
'severite': 'CRITIQUE',
'details': f"Le protocole {protocole_utilise} n'est pas chiffré"
})
self.score_securite -= 25
return False
return protocole_utilise.upper() in protocoles_securises
def verifier_firmware(self, version, derniere_version, signe_numeriquement):
"""Vérifie l'état du firmware"""
if version != derniere_version:
self.vulnerabilites.append({
'type': 'FIRMWARE_OBSOLETE',
'severite': 'MOYENNE',
'details': f"Version {version} < {derniere_version}"
})
self.score_securite -= 10
if not signe_numeriquement:
self.vulnerabilites.append({
'type': 'FIRMWARE_NON_SIGNE',
'severite': 'HAUTE',
'details': "Le firmware n'est pas signé numériquement"
})
self.score_securite -= 15
def generer_rapport(self):
"""Génère un rapport de sécurité"""
self.score_securite = max(0, self.score_securite)
print("\n" + "="*60)
print(" RAPPORT D'AUDIT SÉCURITÉ IoT")
print("="*60)
# Score global
if self.score_securite >= 80:
niveau = "🟢 BON"
elif self.score_securite >= 50:
niveau = "🟡 MOYEN"
else:
niveau = "🔴 CRITIQUE"
print(f"\n📊 SCORE DE SÉCURITÉ : {self.score_securite}/100 ({niveau})")
# Vulnérabilités détectées
print(f"\n🔍 VULNÉRABILITÉS DÉTECTÉES : {len(self.vulnerabilites)}")
for vuln in self.vulnerabilites:
icone = "🔴" if vuln['severite'] == 'CRITIQUE' else "🟠" if vuln['severite'] == 'HAUTE' else "🟡"
print(f"\n{icone} [{vuln['severite']}] {vuln['type']}")
if isinstance(vuln['details'], list):
for detail in vuln['details']:
if isinstance(detail, dict):
print(f" - Port {detail['port']}: {detail['service']}")
else:
print(f" - {detail}")
else:
print(f" - {vuln['details']}")
# Recommandations
print("\n" + "="*60)
print("📋 RECOMMANDATIONS")
print("="*60)
if self.score_securite < 100:
print("\n1. Changer immédiatement les mots de passe par défaut")
print("2. Désactiver les services non nécessaires (Telnet, FTP)")
print("3. Utiliser HTTPS/TLS pour toutes les communications")
print("4. Mettre à jour le firmware vers la dernière version")
print("5. Activer la signature numérique du firmware")
print("\n" + "="*60)
# Démonstration du scanner
print("=== SCAN DE SÉCURITÉ D'UN OBJET CONNECTÉ ===\n")
scanner = ScannerSecuriteIoT()
# Simuler un scan d'appareil IoT (caméra IP par exemple)
print("Appareil : Caméra IP GeneriCam v2.0")
print("Adresse IP : 192.168.1.42")
print("\n--- Analyse en cours ---\n")
# Test 1 : Mot de passe
print("1. Vérification du mot de passe...")
mdp_ok = scanner.verifier_mot_de_passe("admin123")
print(f" Résultat : {'✅ OK' if mdp_ok else '❌ FAIBLE'}")
# Test 2 : Ports ouverts
print("\n2. Scan des ports...")
ports = [22, 23, 80, 443, 554] # SSH, Telnet, HTTP, HTTPS, RTSP
ports_ok = scanner.scanner_ports(ports)
print(f" Ports ouverts : {ports}")
print(f" Résultat : {'✅ OK' if ports_ok else '❌ PORTS DANGEREUX'}")
# Test 3 : Chiffrement
print("\n3. Vérification du chiffrement...")
chiffre = scanner.verifier_chiffrement("HTTP")
print(f" Protocole : HTTP")
print(f" Résultat : {'✅ CHIFFRÉ' if chiffre else '❌ NON CHIFFRÉ'}")
# Test 4 : Firmware
print("\n4. Analyse du firmware...")
scanner.verifier_firmware("2.0.1", "2.3.5", signe_numeriquement=False)
# Rapport final
scanner.generer_rapport()Quiz de validation
1. Quelle attaque a compromis 600 000 objets connectés en 2016 en exploitant des mots de passe par défaut ?
2. Quel type de chiffrement utilise la même clé pour chiffrer et déchiffrer ?
3. Pourquoi ECDSA est-il préféré à RSA pour les systèmes embarqués ?
4. Dans l'authentification challenge-response, que ne transite JAMAIS sur le réseau ?
5. Que signifie le principe 'Fail-secure' en sécurité ?
