
Riproduttore containerizzato per l'escalation dei privilegi Linux CVE-2021-22555, con profili di mitigazione seccomp e indicazioni di distribuzione per cluster Kubernetes e OpenShift.
Innanzitutto, questo include il codice dell'exploit da qui come pratico contenitore pre-costruito: https://github.com/google/security-research/tree/master/pocs/linux/cve-2021-22555
Contenitore pre-costruito: quay.io/cgwalters/cve-2021-22555
Una forte mitigazione consiste nell'abilitare seccomp per negare clone(CLONE_NEWUSER). La documentazione upstream di Kubernetes contiene alcune informazioni al riguardo, ma lascia all'utente la distribuzione della policy sul nodo. In OpenShift 4, abbiamo il machine-config-operator che può gestirlo.
Seccomp non è realmente discusso nella documentazione ufficiale. Tuttavia, la guida alla sicurezza ne menziona almeno una parte, così come questo blog.
cri-o nella 4.7 include una policy seccomp predefinita, ma non è abilitata di default.
Sia podman che docker includono anch'essi una policy, e è abilitata di default (ma differiscono, vedi sotto).
La policy cri-o non nega clone(CLONE_NEWUSER) di default - e questo vale anche per la policy di podman. Tuttavia, la policy predefinita di docker nega 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 ~]#
In altre parole: docker non è vulnerabile a questo di default, mentre podman e cri-o lo sono. (TODO: controllare containerd)
L'articolo del blog openshift/seccomp-for-fun-and-profit discute parte di questo e collega a un profilo generato dall'autore. Questa policy nega clone(CLONE_NEWUSER).
Per comodità, questo repository contiene una copia di quel profilo in more-restricted.json, e un file Butane che genera un oggetto MachineConfig per distribuire quel profilo ai worker.
Usa il file pod di esempio che contiene:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: more-restricted.json
Otteniamo:
$ 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
Il che dovrebbe rendere l'exploit irraggiungibile.
Tuttavia, questo richiede che i pod aderiscano. Ancora TODO: esplorare se una policy seccomp può essere resa obbligatoria tramite una SecurityContextConstraint, o se serve un mutating admission webhook.