
Reprodutor conteinerizado para a escalada de privilégios no Linux CVE-2021-22555, com perfis de mitigação seccomp e orientações de implantação para clusters Kubernetes e OpenShift.
Primeiro, isto incorpora o código do exploit daqui como um contêiner pré-construído e útil: https://github.com/google/security-research/tree/master/pocs/linux/cve-2021-22555
Contêiner pré-construído: quay.io/cgwalters/cve-2021-22555
Uma forte mitigação é habilitar o seccomp que nega clone(CLONE_NEWUSER). A documentação upstream do Kubernetes
tem algumas informações sobre isso - mas deixa a implantação da política no nó a cargo do usuário. No OpenShift 4, temos o machine-config-operator
que pode lidar com isso.
O seccomp não é realmente discutido na documentação oficial. No entanto, o guia de segurança menciona ao menos parte disso, assim como este blog.
cri-o na versão 4.7 acompanha uma política seccomp padrão, mas ela não está habilitada por padrão.
podman e docker também acompanham uma política, e ela está habilitada por padrão (mas elas diferem, veja abaixo).
A política do cri-o não nega clone(CLONE_NEWUSER) por padrão - e isso também é verdade para a política do podman. No entanto, a política padrão do 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 ~]#
Ou, em outras palavras: docker não é vulnerável a isso por padrão, mas podman e cri-o são. (TODO: verificar containerd)
A publicação do blog openshift/seccomp-for-fun-and-profit
discute parte disso e traz um link para um perfil gerado pelo autor. Essa política de fato nega clone(CLONE_NEWUSER).
Para conveniência, este repositório contém uma cópia desse perfil em more-restricted.json e um arquivo Butane que gera um objeto MachineConfig que implantará esse perfil nos workers.
Use o arquivo de pod de exemplo, que contém:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: more-restricted.json
Obtemos:
$ 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
O que deve tornar o exploit inalcançável.
No entanto, isso exige que os pods optem por participar. Ainda TODO: Explorar se uma política seccomp pode se tornar obrigatória por meio de uma SecurityContextConstraint, ou se precisamos de um webhook de admissão de mutação.