
Defensives Sicherheitsdemo: seL4-Mikrokernel-Gateway schützt anfällige ICS vor CVE-2019-14462
Ein defensives Sicherheitsforschungsprojekt, das Protocol-Break- und Packet-Forwarding-Architekturen zum Schutz industrieller Steuerungssysteme vor Cyberangriffen vergleicht.
Dokumentation:
- Netzwerkarchitektur – Netzwerkdiagramme und Datenverkehrsfluss
- Container-Architektur – Beziehungen der Docker-Container
- CVE-Erklärungen – Details zu Schwachstellen und Angriffsmechanismen
Moderne ICS/SCADA-Systeme sind Ziel anspruchsvoller Angriffe wie FrostyGoop, der im Januar 2024 über Modbus-TCP auf ukrainische Fernwärmesysteme abzielte und mehr als 600 Haushalte bei Minusgraden ohne Heizung zurückließ. Herkömmliche Sicherheitslösungen (Firewalls, IDS) verwenden Packet-Forwarding-Architekturen, die den Datenverkehr inline überwachen, aber eine einzige TCP-Verbindung durchgängig aufrechterhalten.
Dieses Projekt demonstriert eine Alternative: ein Protocol-Break-Gateway auf Basis des formal verifizierten seL4-Mikrokernels. Durch die Beendigung von TCP-Verbindungen und die Validierung von Protokollsemanitiken vor dem Aufbau neuer Verbindungen zu geschützten Geräten bietet diese Architektur stärkere Sicherheitsgarantien.
| Aspekt | Protocol-Break (seL4) | Packet-Forwarding (Snort) |
|---|---|---|
| CVE-2019-14462 | BLOCKED (Längenvalidierung) | DETECTED (Quickdraw-Regeln) |
| CVE-2022-0367 | BLOCKED (Adressvalidierung) | DETECTED (benutzerdefinierte Regeln) |
| CVE-2022-20685 | IMMUNE (kein Preprozessor) | VULNERABLE (IDS DoS) |
| CVE-2024-1086 | IMMUNE (kein Linux-Kernel) | VULNERABLE (teilt Host-Kernel) |
| Unbekannte Varianten | BLOCKED (strukturelle Validierung) | MISSED (keine Signatur) |
| TCP-Statusangriffe | BLOCKED (Verbindung beendet) | Möglich |
| Angriffsfläche | ~1.000 LoC (Mikrokernel) | ~500.000 LoC (Linux + Snort) |
┌─────────────────────────────────────────────────────────────────────────────┐
│ Docker Network: ics-untrusted (192.168.96.0/24) │
│ │
│ ┌───────────────────────┐ ┌───────────────────────┐ │
│ │ seL4 Gateway │ │ Snort IDS │ │
│ │ Port 502 │ │ Port 503 │ │
│ │ │ │ │ │
│ │ • Protocol-break │ │ • Packet-forwarding │ │
│ │ • TCP termination │ │ • Inline inspection │ │
│ │ • Length validation │ │ • Rule-based detection│ │
│ └───────────┬───────────┘ └───────────┬───────────┘ │
│ │ │ │
├───────────────┼───────────────────────────────┼─────────────────────────────┤
│ Docker Network: ics-protected (192.168.95.0/24) │
│ │ │ │
│ └───────────────┬───────────────┘ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ PLC (District Heating) │ │
│ │ Vulnerable libmodbus 3.1.2 │ │
│ │ Port 5020 (direct access) │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
# Lege dein seL4-Kernel-Image ab unter:
gateway/sel4-image/capdl-loader-image-arm-qemu-arm-virt
# Alle Container bauen
sudo docker compose build
# Einzelne Container starten
sudo docker compose up plc # Nur PLC
sudo docker compose up gateway # seL4-Gateway + PLC
sudo docker compose up snort # Snort IDS + PLC
# Alle starten
sudo docker compose up
# Über seL4-Gateway (geschützt - Protocol-Break)
echo -ne '\x00\x01\x00\x00\x00\x06\x01\x03\x00\x00\x00\x01' | nc localhost 502 | xxd
# Über Snort IDS (geschützt - Packet-Forwarding)
echo -ne '\x00\x01\x00\x00\x00\x06\x01\x03\x00\x00\x00\x01' | nc localhost 503 | xxd
# Direkt zum PLC (ungeschützt - anfällig)
echo -ne '\x00\x01\x00\x00\x00\x06\x01\x03\x00\x00\x00\x01' | nc localhost 5020 | xxd
| Port | Pfad | Architektur | Schutz |
|---|---|---|---|
| 502 | Client → seL4 → PLC | Protocol-Break | Validiert Modbus-Struktur |
| 503 | Client → Snort → PLC | Packet-Forwarding | Regelbasiertes IDS |
| 5020 | Client → PLC (ASAN) | Direkt | CVE-2022-0367-Modus |
| 5022 | Client → PLC | Direkt | CVE-2019-14462-Modus (Profil: cve14462) |
Hinweis: Der Standard-PLC läuft jetzt im CVE-2022-0367-Modus mit ASAN. Verwende
--profile cve14462für CVE-2019-14462-Tests.
Der PLC verwendet die absichtlich anfällige libmodbus 3.1.2. Der Angriff nutzt vertrauenswürdige MBAP-Längenfelder aus:
# PLC im CVE-2019-14462-Modus starten
sudo docker compose --profile cve14462 up plc-14462
# Angriffswerkzeuge bauen
cd cve_tools && make
# Ungeschützten PLC angreifen (Absturz)
./cve_14462_attack 127.0.0.1 5022
# Über seL4 angreifen (BLOCKED)
./cve_14462_attack 127.0.0.1 502
# Über Snort angreifen (DETECTED durch Quickdraw-Regeln)
./cve_14462_attack 127.0.0.1 503
Ein Grenzprüfungsfehler in modbus_mapping_new_start_address() ermöglicht einen Heap-Underflow über Funktionscode 0x17 (Write and Read Registers):
# Standard-PLC läuft im CVE-2022-0367-Modus mit ASAN
sudo docker compose up plc
# Angriffswerkzeuge bauen
cd cve_tools && make
# PLC angreifen – ASAN erkennt Heap-Buffer-Overflow
./cve_0367_attack 127.0.0.1 5020
# Mit benutzerdefinierten Parametern angreifen
./cve_0367_attack 127.0.0.1 5020 88 0x4141 # Beschädigt tab_registers-Zeiger
./cve_0367_attack 127.0.0.1 5020 72 0xFFFF # Beschädigt nb_registers
# Über seL4 angreifen (BLOCKED – Adressvalidierung)
./cve_0367_attack 127.0.0.1 502
# Über Snort angreifen (DETECTED durch benutzerdefinierte Regeln)
./cve_0367_attack 127.0.0.1 503
Technische Details:
start_registers=100, gültige Adressen sind 100–109write_address < 100, was einen negativen Array-Index verursachtmb_mapping-Struktur inklusive Zeiger beschädigenSnort 2.9.18 hat einen Integer-Overflow in seinem Modbus-Preprozessor, der eine Endlosschleife verursacht und jeglichen Datenverkehr durch das IDS vollständig blockiert:
# 1. Überprüfen, ob Snort funktioniert (sollte Modbus-Antwort zurückgeben)
echo -ne '\x00\x01\x00\x00\x00\x06\x01\x03\x00\x00\x00\x01' | nc -w 2 localhost 503 | xxd
# 2. Snort-IDS angreifen
./cve_20685_attack 127.0.0.1 503
# 3. Überprüfen, ob Snort eingefroren ist (sollte ohne Antwort auslaufen)
echo -ne '\x00\x01\x00\x00\x00\x06\x01\x03\x00\x00\x00\x01' | nc -w 5 localhost 503 | xxd