
LID — Linux Integrity Drift: Umgehung von AppArmor durch eBPF-Pfadnamen-Umschreibung. Syscall-Argumentmanipulation vor LSM mit null Audit-Fußabdruck. "Linux is Dying"
```
██╗ ██╗██████╗
██║ ██║██╔══██╗
██║ ██║██║ ██║
██║ ██║██║ ██║
███████╗██║██████╔╝
╚══════╝╚═╝╚═════╝
```
— „Linux stirbt“ —
Systematische Entdeckung von Kernel-Codepfaden, die LSM-Sicherheitsgarantien umgehen
Das Tor wurde nie durchbrochen. Es wurde umgangen.
Das Linux Security Module Framework hat eine Kernzusicherung, die seit 20+ Jahren gilt:
Sicherheitsmodule können nur Einschränkungen hinzufügen. Sie können nie welche entfernen.
Diese Zusicherung ist korrekt. LID bricht sie nicht.
LID findet Kernel-Codepfade, die LSM-Hooks vollständig umgehen — Subsysteme, die sicherheitsrelevante Operationen durchführen, ohne das LSM-Framework zu konsultieren. Die Sicherheitsprüfung ist korrekt. Das Problem ist, dass der Kernel nie fragt.
Jeder Fund hat zwei unterschiedliche Dimensionen, die nicht vermischt werden sollten:
Der architektonische tote Winkel. Die Frage ist nicht „kann ein Angreifer das ausnutzen?“ sondern:
Wenn eine sicherheitsrelevante Operation auftritt und die Durchsetzungsschicht sie nie auswertet, haben Sie eine Sichtbarkeitslücke — unabhängig davon, ob ein Angreifer sie heute praktisch ausnutzen kann. Dies ist wichtig für Compliance, Forensik und Annahmen zur Verteidigung in der Tiefe.
Die Frage nach der realen Ausnutzbarkeit:
Diese beiden Dinge sind unterschiedlich. Ein Fund kann eine kritische Sichtbarkeitslücke sein (Ihre Überwachung ist blind), ohne eine praktische Privilegieneskalation zu sein (Angreifer benötigt bereits root). Umgekehrt kann ein Fund ein direkter Eskalationspfad mit minimalen Voraussetzungen sein.
| Finding | Sichtbarkeitslücke | Praktische Eskalation |
|---|---|---|
| LID-001 | Kritisch — AppArmor sieht nichts, Audit-Log leer, null forensische Spur | Begrenzt — erfordert root oder CAP_BPF+CAP_PERFMON (bereits privilegiert). Keine Privilegieneskalation. Auswirkung: Richtlinienumgehung + Blindheit des Audits. |
| LID-002 | Hoch — security_file_receive() feuert nie, fd-Transfer für alle LSMs unsichtbar | Hoch — funktioniert von unprivilegiertem Userspace über io_uring. Überschreitet die LSM-Durchsetzungsgrenze ohne jegliches Privileg. |
| LID-003 | Hoch — security_sb_mount() umgangen, AppArmor-Mount-Richtlinie ist toter Code | Mittel — erfordert Mount-Namespace-Zugriff (CAP_SYS_ADMIN in user ns). In vielen Container-Konfigurationen verfügbar. |
| LID-004 | Kritisch — AppArmor sieht nichts, null BPF-Hooks (0/9), keine Audit-Spur für BPF-Token-Operationen | Mittel — erfordert bpffs-Delegation durch den Host + CAP_BPF im User-Namespace. Verfügbar in Container-Laufzeiten mit BPF-Delegation (LXD/Incus). |
| LID-005 | Mittel — tc-Egress-Klassifizierer auf Container-Interface werten AF_XDP-Verkehr nie aus | Begrenzt — umgeht tc-Egress auf Container eth0 (verifiziert). Cilium NICHT umgangen — erzwingt auf Knoten-seitigem veth-Ingress + Quell-IP-Überprüfung (getestet). Auswirkung auf reine Docker-Setups mit tc-only Egress-Filterung beschränkt. |
Jeder Fund hat spezifische Kernel-/Konfigurations-/Privilegienanforderungen. Wenn Ihre Umgebung nicht übereinstimmt, wird der Fund nicht reproduziert.
| Bedingung | Erforderlich | Anmerkungen |
|---|---|---|
| Kernel version | 5.x+ | Tested on 5.15, 6.1, 6.6, 6.8 |
CONFIG_BPF_SYSCALL | =y | Default on all major distros |
CONFIG_BPF_KPROBE_OVERRIDE | =y | Ubuntu/Debian aktivieren es, RHEL nicht |
CONFIG_SECURITY_APPARMOR | =y | Ziel-LSM muss AppArmor sein |
| AppArmor-Profil | Erzwingend, Verweigerungsregel auf Zielpfad | Funktioniert mit jeder pfadbasierten Verweigerungsregel |
| Privilegien | root oder CAP_BPF + CAP_PERFMON | Kann nicht unprivilegiert ausgeführt werden |
kernel.lockdown | none oder integrity | confidentiality-Modus blockiert kprobe-Anbindung |
kernel.unprivileged_bpf_disabled | Unerheblich | Erfordert dennoch CAP_BPF |
fs.protected_hardlinks | 0 für benutzerübergreifende Links | 1 (Standard) erlaubt weiterhin harte Links desselben Benutzers |
| SELinux statt AppArmor | Funktioniert nicht | SELinux ist inode-basiert, nicht pfadnamen-basiert |
| Bedingung | Erforderlich | Anmerkungen |
|---|---|---|
| Kernel-Version | 6.0+ | IORING_MSG_SEND_FD hinzugefügt in 6.0 |
CONFIG_IO_URING | =y | Standard auf allen großen Distributionen |
| Privilegien | Keine | Funktioniert von unprivilegiertem Userspace |
io_uring_disabled sysctl | 0 (Standard) | 2 blockiert unprivilegiert, 1 blockiert alle |
| Ziel-LSM | Beliebig (SELinux, AppArmor, Smack) | security_file_receive() ist ein generischer LSM-Hook |
kernel.lockdown | Unerheblich | Kein BPF beteiligt |
| Bedingung | Erforderlich | Anmerkungen |
|---|---|---|
| Kernel-Version | 6.9+ | BPF-Token eingeführt in 6.9 |
CONFIG_BPF_SYSCALL | =y | Standard auf allen großen Distributionen |
CONFIG_SECURITY_APPARMOR | =y | Ubuntu/Debian Standard |
| bpffs mit Delegation | Ja | Host muss mit delegate_*-Optionen mounten |
| Privilegien | CAP_BPF im User-Namespace | Trivial für userns-root verfügbar |
| SELinux statt AppArmor | Nicht betroffen | SELinux implementiert alle 9 BPF-Hooks |
| Bedingung | Erforderlich | Anmerkungen |
|---|---|---|
| Kernel-Version | 5.2+ | fsopen/fsmount eingeführt in 5.2 |
CONFIG_SECURITY_APPARMOR | =y | Nur AppArmor ist betroffen |
| Privilegien | CAP_SYS_ADMIN im User-Namespace | Verfügbar mit unshare -m |
| SELinux statt AppArmor | Funktioniert nicht | SELinux implementiert security_sb_kern_mount() |
| Container-Laufzeit | Hängt vom Seccomp-Filter ab | Docker-Standard-Seccomp blockiert fsopen — Podman/LXC möglicherweise nicht |
| Bedingung | Erforderlich | Anmerkungen |
|---|---|---|
| Kernel-Version | 4.18+ | AF_XDP eingeführt in 4.18 |
CONFIG_XDP_SOCKETS | =y | Standard auf allen großen Distributionen |
| Privilegien | CAP_NET_RAW nur | Standard in Docker, Kubernetes-Pods |
| Container-Laufzeit | Docker, K8s, LXC | Standard-Fähigkeitssatz |
| tc-basierte Netzwerkrichtlinie | Ja | Cilium eBPF, Calico, tc u32/flower |