
Reproducteur conteneurisé pour l'escalade de privilèges Linux CVE-2021-22555, avec des profils d'atténuation seccomp et des conseils de déploiement pour les clusters Kubernetes et OpenShift.
Tout d'abord, cela intègre le code d'exploitation depuis ici sous forme d'un conteneur pré-construit pratique : https://github.com/google/security-research/tree/master/pocs/linux/cve-2021-22555
Conteneur pré-construit : quay.io/cgwalters/cve-2021-22555
Une atténuation robuste consiste à activer seccomp qui refuse clone(CLONE_NEWUSER). La documentation Kubernetes upstream contient des informations à ce sujet - mais laisse le déploiement de la politique sur le nœud à l'utilisateur. Dans OpenShift 4, nous avons le machine-config-operator qui peut gérer cela.
Seccomp n'est pas vraiment abordé dans la documentation officielle. Cependant, le guide de sécurité mentionne au moins certains aspects, tout comme ce blog.
cri-o dans la version 4.7 est livré avec une politique seccomp par défaut, mais elle n'est pas activée par défaut. podman et docker sont également livrés avec une politique, et elle est activée par défaut (mais elles diffèrent, voir ci-dessous).
La politique cri-o ne refuse pas clone(CLONE_NEWUSER) par défaut - et c'est également le cas pour la politique podman. Cependant, la politique par défaut de docker refuse clone(CLONE_NEWUSER) :
[root@cosa-devsh ~]# rpm -q podman moby-engine
podman-3.1.2-1.fc33.x86_64
moby-engine-19.03.13-1.ce.git4484c46.fc33.x86_64
[root@cosa-devsh ~]# podman run --rm -ti registry.fedoraproject.org/fedora:34 /bin/sh -c 'unshare -U --keep-caps true'
[root@cosa-devsh ~]# echo $?
0
[root@cosa-devsh ~]# docker run --rm -ti registry.fedoraproject.org/fedora:34 /bin/sh -c 'unshare -U --keep-caps true'
unshare: unshare failed: Operation not permitted
errchan: json: cannot unmarshal array into Go struct field systemdEventMessage.MESSAGE of type string
[root@cosa-devsh ~]# echo $?
1
[root@cosa-devsh ~]#
Ou en d'autres termes : docker n'est pas vulnérable par défaut, contrairement à podman et cri-o. (TODO : vérifier containerd)
L'article de blog openshift/seccomp-for-fun-and-profit aborde certains de ces points et renvoie à un profil généré par l'auteur. Cette politique refuse bien clone(CLONE_NEWUSER).
Par commodité, ce dépôt contient une copie de ce profil dans more-restricted.json, et un fichier Butane qui génère un objet MachineConfig qui déploiera ce profil sur les workers.
Utilisez le fichier pod d'exemple qui contient :
securityContext:
seccompProfile:
type: Localhost
localhostProfile: more-restricted.json
Nous obtenons :
$ oc logs pod/cve-2021-22555
[+] Linux Privilege Escalation by theflow@ - 2021
[+] STAGE 0: Initialization
[*] Setting up namespace sandbox...
[-] unshare(CLONE_NEWUSER): Operation not permitted
Ce qui devrait rendre l'exploit inaccessible.
Cependant, cela nécessite que les pods adhèrent volontairement. Encore TODO : Explorer si une politique seccomp peut être rendue obligatoire via un SecurityContextConstraint, ou si nous avons besoin d'un webhook d'admission mutant.