
LID — Linux Integrity Drift : contournement d'AppArmor via la réécriture de chemin eBPF. Manipulation d'arguments d'appel système avant LSM avec empreinte d'audit nulle. « Linux is Dying »
```
██╗ ██╗██████╗
██║ ██║██╔══██╗
██║ ██║██║ ██║
██║ ██║██║ ██║
███████╗██║██████╔╝
╚══════╝╚═╝╚═════╝
```
— « Linux est en train de mourir » —
Découverte systématique de chemins de code du noyau qui contournent les garanties de sécurité des LSM
La porte n'a jamais été forcée. On l'a contournée.
Le framework des modules de sécurité Linux (LSM) repose sur une garantie centrale qui tient depuis plus de 20 ans :
Les modules de sécurité ne peuvent qu'ajouter des restrictions. Ils ne peuvent jamais les supprimer.
Cette garantie est correcte. LID ne la brise pas.
LID trouve des chemins de code du noyau qui contournent complètement les hooks LSM — des sous-systèmes effectuant des opérations sensibles pour la sécurité sans consulter le framework LSM. La vérification de sécurité est correcte. Le problème est que le noyau ne demande jamais.
Chaque découverte a deux dimensions distinctes qu'il ne faut pas confondre :
Le point aveugle architectural. La question n'est pas « un attaquant peut-il exploiter cela ? » mais :
Si une opération sensible pour la sécurité se produit et que la couche d'application ne l'évalue même pas, vous avez un écart de visibilité — indépendamment de la possibilité pratique pour un attaquant d'en abuser aujourd'hui. Cela compte pour la conformité, la criminalistique et les hypothèses de défense en profondeur.
La question pratique de l'exploitabilité :
Ces deux choses sont différentes. Une découverte peut être un écart de visibilité critique (votre surveillance est aveugle) sans être une escalade de privilèges pratique (l'attaquant a déjà besoin de root). Inversement, une découverte peut être un chemin d'escalade direct avec des prérequis minimaux.
| Découverte | Écart de visibilité | Escalade pratique |
|---|---|---|
| LID-001 | Critique — AppArmor ne voit rien, journal d'audit vide, aucune trace forensique | Limitée — nécessite root ou CAP_BPF+CAP_PERFMON (déjà privilégié). Pas d'escalade de privilèges. Impact : contournement de politique + cécité d'audit. |
| LID-002 | Élevé — security_file_receive() jamais déclenché, transfert de fd invisible pour tous les LSM | Élevé — fonctionne depuis un espace utilisateur non privilégié via io_uring. Franchit la limite d'application LSM sans aucun privilège. |
| LID-003 | Élevé — security_sb_mount() contourné, la politique de montage AppArmor est du code mort | Moyen — nécessite un accès à l'espace de noms de montage (CAP_SYS_ADMIN dans user ns). Disponible dans de nombreuses configurations de conteneurs. |
| LID-004 | Critique — AppArmor ne voit rien, zéro hooks BPF (0/9), aucune trace d'audit pour toute opération de jeton BPF | Moyen — nécessite une délégation bpffs par l'hôte + CAP_BPF dans l'espace de noms utilisateur. Disponible dans les environnements d'exécution de conteneurs avec délégation BPF (LXD/Incus). |
| LID-005 | Moyen — les classificateurs tc egress sur l'interface du conteneur n'évaluent jamais le trafic AF_XDP | Limitée — contourne tc egress sur eth0 du conteneur (vérifié). Cilium PAS contourné — applique sur l'ingress veth côté nœud + vérification IP source (testé). Impact limité aux configurations Docker simples avec filtrage tc egress uniquement. |
Chaque découverte a des exigences spécifiques de noyau/config/privlèges. Si votre environnement ne correspond pas, la découverte ne se reproduira pas.
| Condition | Requis | Notes |
|---|---|---|
| Version du noyau | 5.x+ | Testé sur 5.15, 6.1, 6.6, 6.8 |
CONFIG_BPF_SYSCALL | =y | Par défaut sur toutes les distributions majeures |
CONFIG_BPF_KPROBE_OVERRIDE | =y | Ubuntu/Debian l'activent, RHEL non |
CONFIG_SECURITY_APPARMOR | =y | Le LSM cible doit être AppArmor |
| Profil AppArmor | Enforcing, règle de refus sur le chemin cible | Fonctionne avec toute règle de refus basée sur le chemin |
| Privilèges | root ou CAP_BPF + CAP_PERFMON | Ne peut pas s'exécuter non privilégié |
kernel.lockdown | none ou integrity | Le mode confidentiality bloque l'attachement kprobe |
kernel.unprivileged_bpf_disabled | Sans importance | Nécessite CAP_BPF quoi qu'il arrive |
fs.protected_hardlinks | 0 pour les liens inter-utilisateurs | 1 (par défaut) autorise encore les liens physiques du même utilisateur |
| SELinux au lieu d'AppArmor | Ne fonctionne pas | SELinux est basé sur les inodes, pas sur les noms de chemin |
| Condition | Requis | Notes |
|---|---|---|
| Version du noyau | 6.0+ | IORING_MSG_SEND_FD ajouté dans 6.0 |
CONFIG_IO_URING | =y | Par défaut sur toutes les distributions majeures |
| Privilèges | Aucun | Fonctionne depuis un espace utilisateur non privilégié |
sysctl io_uring_disabled | 0 (par défaut) | 2 bloque les non privilégiés, 1 bloque tout |
| LSM cible | Tout (SELinux, AppArmor, Smack) | security_file_receive() est un hook LSM générique |
kernel.lockdown | Sans importance | Aucun BPF impliqué |
| Condition | Requis | Notes |
|---|---|---|
| Version du noyau | 6.9+ | Jeton BPF introduit dans 6.9 |
CONFIG_BPF_SYSCALL | =y | Par défaut sur toutes les distributions majeures |
CONFIG_SECURITY_APPARMOR | =y | Valeur par défaut Ubuntu/Debian |
| bpffs avec délégation | Oui | L'hôte doit monter avec les options delegate_* |
| Privilèges | CAP_BPF dans l'espace de noms utilisateur | Trivialement accessible au root d'userns |
| SELinux au lieu d'AppArmor | Non affecté | SELinux implémente les 9 hooks BPF |
| Condition | Requis | Notes |
|---|---|---|
| Version du noyau | 5.2+ | fsopen/fsmount introduits dans 5.2 |
CONFIG_SECURITY_APPARMOR | =y | Seul AppArmor est affecté |
| Privilèges | CAP_SYS_ADMIN dans l'espace de noms utilisateur | Disponible avec unshare -m |
| SELinux au lieu d'AppArmor | Ne fonctionne pas | SELinux implémente security_sb_kern_mount() |
| Environnement d'exécution de conteneur | Dépend du filtre seccomp | Le seccomp par défaut de Docker bloque fsopen — Podman/LXC peuvent ne pas le faire |