Arquitetura do Docker

Se você está lendo este artigo, suponho que você sabe como o Docker funciona sob o capô, no entanto, vamos recapitular rapidamente os principais conceitos:

Cliente Docker

Essa é a parte que costuma ser mais utilizada pelos usuários, o cliente é a CLI para o daemon do Docker e ajuda a gerenciar contêineres, imagens e registros.

Ele também pode ser usado para gerenciar redes e volumes usados por contêineres.

Alguns dos comandos que você pode usar no cliente Docker:

#RUN A NGINX CONTAINER WITH PORT 80 BINDING HOST-CONTAINERdocker run -d -p 80:80 nginx#PULL UBUNTU 22.04 DOCKER IMAGEdocker pull ubuntu:22.04#SHOWS DOCKER IMAGES IN YOUR DOCKER SYSTEMdocker images#HELPER FOR DOCKER NETWORKSdocker network#HELPER FOR DOCKER VOLUMESdocker volume

Docker Daemon

O daemon do Docker é, na verdade, o núcleo do ambiente docker, ele executa contêineres, extrai imagens e gerencia todas as redes e volumes.

Você pode usar o daemon do Docker por meio de um cliente ou, se quiser dificultar as coisas, poderá se conectar diretamente ao soquete do Docker. Ele escuta solicitações de API.

Registro do Docker

O registro do Docker é onde as imagens do Docker são armazenadas.

Por padrão, o Docker verifica se há imagens no Docker Hub, mas, se configuradas, as imagens serão extraídas do registro definido. Além disso, um registro pode ser público ou privado com autenticação.

Ameaças ao ambiente do Docker

Soquete do Docker

O soquete do Docker /var/run/docker.sock é o soquete UNIX que o Docker está escutando e pertence ao usuário root. Esse é o principal ponto de entrada para a API do Docker.

Causa raiz:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock <image_name>:<image_tag>

Um invasor pode emitir solicitações para o daemon do Docker (em execução como raiz no host do Docker) para:

  • iniciar um contêiner privilegiado e sair deste;
  • puxe uma imagem pública de backdoor, execute-a e entre nela e fuja.

Exemplo de ataque:

- find / -name docker.sock 2>/dev/null- docker images- docker run -it -v /:/host <image_name>:<image_tag> chroot /host bash

O soquete do Docker pode ser local, como vimos acima, e pode até ser exposto à Internet se você executar seu daemon do docker com esses sinalizadores:

-H tcp://0.0.0.0:XXX

Nesse caso, o soquete do Docker seria exposto à porta especificada em XXX e pode ser acessado pela Internet.

Contêiner privilegiado

Por padrão, os contêineres do Docker são “sem privilégios” e não podem, por exemplo, executar um daemon do Docker dentro de um contêiner do Docker.

O sinalizador —privileged fornece todos os recursos ao contêiner. Quando o operador executa a execução do docker — com privilégio, o Docker habilitará o acesso a todos os dispositivos no host, bem como definirá alguma configuração no AppArmor ou no SELinux para permitir que o contêiner tenha quase o mesmo acesso ao host como processos em execução fora dos contêineres no host.

Causa raiz:

docker run -d --privileged <image_name>:<image_tag>

Um invasor pode montar o sistema de arquivos host e usar o chroot para acessar o host.

Exemplo de ataque:

 - capsh --print - fdisk -l - mount /target/disk /mnt/ - chroot /mnt/ bash

Abuso de recursos

Em geral, você deve verificar os recursos do contêiner, se ele tiver algum dos seguintes, você poderá sair dele ou fazer coisas ruins (a exploração é bastante longa e diferente em cada cenário):

CAP_SYS_ADMINCAP_SYS_PTRACECAP_SYS_MODULEDAC_READ_SEARCHDAC_OVERRIDECAP_SYS_RAWIOCAP_SYSLOGCAP_NET_RAWCAP_NET_ADMIN

Você pode verificar os recursos de contêiner atuais usando:

capsh --print

Rede compartilhada

Causa raiz:

docker run -d --network host <image_name>:<image_tag>

Um invasor com um ponto de apoio inicial no contêiner vulnerável pode girar para outros contêineres. Se houver contêineres de gerenciamento, por exemplo, Portainer, o invasor poderá usá-los para instanciar uma máquina privilegiada que pode ser usada para quebrar.

Você pode descobrir a interface para a rede do Docker em execução:

ip addr

A máquina host cria principalmente uma interface que atua como gateway para a rede Docker e, geralmente, o primeiro endereço IP do intervalo é usado para isso. Por padrão, o intervalo de IP para a rede do Docker é 172.17.0.0/16 e a máquina host terá o endereço IP 172.17.0.1. Se o endereço IP do contêiner for 172.17.0.1, pode-se concluir que o contêiner compartilha o namespace da rede host.

Abuso de associação ao grupo

Os membros do grupo do Docker podem executar operações do Docker. Essa opção permite que todos os usuários não root usem o Docker, supondo que o daemon do Docker esteja sendo executado com root. No entanto, essa associação pode ser abusada para executar o escalonamento de privilégios na máquina host do Docker.

Verifique se o usuário pode executar operações do Docker e verifique-o verificando o arquivo _/etc/_group:

- docker images- cat /etc/group | grep docker

Abuso em contêineres

Se o daemon Containerd estiver sendo executado na máquina host e o utilitário ctr estiver instalado, ele poderá ser abusado para atacar o host e obter privilégios de root.

O utilitário ctr pode ser usado por outro usuário na máquina host, se disponível para ele.

The attack can make requests to Containerd daemon that is running with root privileges, run a container and mount host file system to it, then use chroot to get root access from inside the container.

abuso de runc

Se o tempo de execução do contêiner runc estiver instalado na máquina e qualquer pessoa puder executar o comando runc, ele poderá ser abusado para atacar o host e obter privilégios de root.

O invasor pode fazer solicitações para o daemon runc que está sendo executado com privilégios de root, executar um contêiner e montar o sistema de arquivos host nele, usar chroot para obter acesso root de dentro do contêiner.

Abuso da ferramenta de gestão

Se uma ferramenta de gerenciamento, por exemplo, Portainer, estiver sendo executada com senha fraca ou estiver vulnerável, isso pode levar à aquisição da máquina host.

Um invasor pode fazer login nele, iniciar um contêiner privilegiado e — de dentro do contêiner recém-lançado — chroot para o sistema de arquivos host.

vulns ou psw

Registro inseguro do Docker

Se um registro privado do Docker não estiver usando autenticação ou não for forte o suficiente, ele poderá ser atacado.

Um invasor pode interagir com o registro do Docker, interagir com sua máquina e baixar imagens sem usar o Docker.

Recolha de informações:

- curl http://<target_registry>:5000/v2/_catalog- curl http://<target_registry>:5000/v2/<repository_name>/tags/list- curl http://<target_registry>:5000/v2/<repository_name>/manifests/<tag>- curl -s http://<target_registry>:5000/v2/<repository_name>/blobs/<blobSum_value> --output     <output_filename>.tar

Imagens falsas (backdoor)

O invasor pode extrair a imagem original do registro, entender a estrutura e criar uma nova imagem com um backdoor. Em seguida, o invasor pode substituir a imagem no registro do Docker e aguardar que alguém/algo a implante.

O invasor pode extrair uma imagem multiuso do Registro, entender a estrutura e criá-la para fornecer ao shell do invasor acesso após a implantação. Em seguida, o invasor pode substituir a imagem no registro do Docker e aguardar que alguém/algo a implante. Neste ponto, as técnicas descritas aqui podem ser usadas para obter acesso root no host do Docker.

Auditoria e segurança no Docker

Audite o soquete do Docker e proteja-o

  • Verifique as permissões do soquete UNIX: outros não devem ter nenhum acesso.
  • Verifique se há soquete TCP e verifique se o soquete TCP está escutando somente na interface local ou se a autenticação está implantada nele.

O soquete TCP padrão do Docker não está protegido, por exemplo, tcp://<host_ip>:2375, por isso precisamos implementar:

  • Autenticação.
  • Canal criptografado.

Como?

  • Usando SSH.
  • Usando TLS (porta TCP 2376).

Grupo de Docker de auditoria

  • Verifique os membros (/etc/group): os não membros não poderão acessar o Docker.

Auditar a configuração do Docker

  • Verifique se há registros inseguros permitidos (/etc/docker/daemon.json).

Ferramentas para segurança do Docker

Fixação de contentores

Seccomp

Seccomp (modo de computação de segurança) é um recurso do kernel Linux que atua como um filtro syscall. Não é uma sandbox, mas frequentemente usada com sandboxes para bloquear syscalls.

O Seccomp-eBPF (modo 2) é suportado pelo Docker para restringir as chamadas de sistema dos contêineres, diminuindo efetivamente a área de superfície. O perfil Seccomp pode ser definido na forma de um arquivo JSON. O perfil Seccomp padrão do Docker é uma lista branca que bloqueia 44 syscalls.

Confira este link para saber mais.

AppArmor

AppArmor é um aprimoramento do kernel para confinar programas a um conjunto limitado de recursos. Vincula atributos de controle de acesso a programas, em vez de usuários.

Um artigo aprofundado no AppArmor virá em breve!

Remapeamento de namespace do usuário

Essa técnica permite mapear um usuário de contêiner para o ID de usuário inexistente do host.
Por exemplo, raiz no contêiner, UID = 0, mesmo usuário no host, UID = 27072; como o usuário não existe, sem privilégios!

Impactos:

  • nenhum modo privilegiado;
  • sem chrooting usando bind mount.

Saiba mais: https://docs.docker.com/engine/security/userns-remap/

Modo sem raiz

É possível executar o daemon do Docker no modo sem raiz. Infelizmente, existem algumas limitações conhecidas: https://docs.docker.com/engine/security/rootless/#known-limitations

Conclusões

  1. Os contêineres do Docker fornecem um método seguro de isolar aplicativos do sistema host subjacente, se não forem usados indevidamente.
  2. É importante garantir que todas as imagens usadas no Docker sejam de fontes confiáveis e sejam atualizadas regularmente.
  3. Proteger o daemon, as imagens de contêiner e os contêineres do Docker é uma etapa importante para garantir que os aplicativos em execução no Docker sejam seguros.
  4. A implementação de controle de acesso e monitoramento baseados em função pode ajudar a garantir que o Docker seja usado com segurança.
  5. Não se esqueça da segurança no host!

Artigo Original