Docker

Recursos de um Virtualizador

Cgroups

Cada container possui sua própria Cgroups (Control Groups ou Grupo de Controle). O Cgroups é responsável por controlar CPU, memória, rede e leitura/escrita de rede de cada container

Diretório onde ficam os recursos do Cgroups

/sys/fs/cgroup

Dentro de cada diretório (que representa um recurso), tem os subrecursos

Criando um Cgroups

cgcreate -g memory:<nome>

Listando todos os Cgroups

lscgroup
lscgroup | grep i docker

Definindo um valor pelo Cgroups. Os comandos são "repetidos", porque existe um bug, então deve-se executar os 3 comandos

cgset -r memory.memsw.limit_in_bytes=160M grupo_de_teste
cgset -r memory.limit_in_bytes=160M grupo_de_teste
cgset -r memory.memsw.limit_in_bytes=160M grupo_de_teste

Verificando o valor

cgget -r memory.limit_in_bytes grupo_de_teste

Deletando um Cgroups

Namespace

Listando os Namespace

Rede

Criando rede Namespace

Listando redes Namespace

Executando comando em uma rede do Namespace

Acessando bash dentro do namespace de rede

Instalação e Configuração do Docker

Instalando

Adicionando o usuário no grupo:

OBS.: Depois que instalado, faça logout no sistema

Informações Básicas

Versão do Docker

Informações detalhadas do Docker

Executando Hello World

Imagens

Imagens no mundo Docker, são como templates que servirão de base para executar um container.

Procurando por uma Imagem

Baixando um Imagem

Listando Todas as Images

Removendo Todas as Images

Remove todas as imagens que não estão "tagiadas" (possuem TAG).

Utilize docker images para ver as imagens que estão "tagiadas"

Containers

O Container é uma instância de uma Imagem em execução naquele momento, que pode ter status como start e stop, e pode ser destruída e gerada rapidamente a qualquer momento.

Verificando Somente os Containers que estão em execução

Verificando Todos os Containers

Diferentemente do comando acima, este exibe também os Containers que estão em Stop.

Listando Somente o ID dos Containers em Execução

Listando o ID de dos Todos os Containers

Executando um Container a Partir de um Imagem

O parâmetro --rm irá excluir o container (caso já exista).

DICA.: Pode-se utilizar --mount no lugar de -v, pois ambos tem o mesmo efeito. Porém o --mount tem uma saída mais detalhada (verbose) e para utilizar services, somente --mount é suportado

Criando um Container e Interagindo com o /bin/bash

As vezes pode ser necessário chamar o nome da imagem, seguido da sua versão (TAG). Execute docker images para ver a versão. Um exemplo do comando anterior utilizando a versão, seria como no exemplo abaixo:

Criando um Container e Executando um Comando

Inicializa um Container a partir de uma Imagem sem deixar o Terminal preso

Por padrão, o Docker irá deixar seu terminal preso, por isso deve utilizar a opção -d (detached), para oculte a sua saída e deixe o terminal livre para utilizar em outro propósitos.

Acessando Portas (aleatórias) de um Container externamente

Isso serve para utilizar a porta do Container como se fosse localmente.

Definindo Portas do Container Externamente

Diferente da opção -P, este permite escolher qual porta iremos acessar via localhost.

Verificando Portas de Determinado Container

Definindo o Diretório onde irá executar determinado Comando

Definindo Variáveis de Ambiente

Note que pode repetir o parâmetro -e quantas vezes for necessário.

Startando um Container

Startando um Container que já foi finalizado, porém deixando o Terminal em Modo Interativo

Parando Container de Forma Mais Rápida

Por padrão o docker demora 10 segundos para parar um serviço

Parando Todos os Containers

Executa determinado Comando em um Container que já está sendo Executado

Parando (Stop) um Container e Removendo ao Mesmo Tempo

Volume

Criando um Volume

Deletando um Volume

Listando Todos os Volumes

Inspecionando Volume

Verificando Montagens (volume) de um Container

Network

Ao criar uma rede própria (Network), podemos fazer com que um container se comunique com outros containers através do hostname

Criando uma Network

Listando as Networks

Criando um Container em uma Network

Inspeciona Determinada Network

Útil para ver quais containers estão conectadas na rede

Removendo uma Network

Dockerfile

Buildando

Caso o seu arquivo chame exatamente Dockerfile, não é preciso passar o parâmetro -f. Se atente também no ponto que está no final do comando

Docker Compose

Executando o docker-compose.yml

Utilize a opçao -d para jogar o processo em background e não ficar com o terminal preso. Utilize o parâmetro -f para especificar o arquivo de configuração ou deixa em branco para ficar como default, onde o irá ser procurado um arquivo chamado docker-compose.yml no diretório atual.

Listando os Serviços do docker-compose

Parando (Stop) e Removendo Todos os Containers do docker-compose

Reiniciando os Containers do docker-compose

Verificando se Está em um Docker

Assim que conseguir uma Reverse Shell ou termos qualquer tipo de acesso/interação, é importando analisarmos se estamos lidando com um Docker. Podemos fazer isso das seguintes maneiras:

  • Veja se existe o arquivo /.dockerenv

  • Verifique o hostname, que geralmente tem código (Container ID) no nome

  • Execute ps -eaf e verifique os processos. Geralmente Docker tem uma quantidade reduzida de processos

  • Veja se no início do phpinfo.php o nome da máquina é algo como "Linux 23d24ff620b3 5.10.0-22-amd64 #1 SMP Debian 5.10.178-3 (2023-04-22) x86_64"

Gerenciando Containers sem o Docker Client

CTR

Ferramenta substituda do docker, que também permite realizar diversas operações com containers

Listando todos as imagens

Listando todos os containers

Iniciando um container. Note que o nome da imagem está no padrão da saída do primeiro comando do ctr, então o alpine:latest, seria o equivalente a docker.io/library/alpine:latest.

RUNC

Primeiro vamos criar nosso arquivo config.json no diretório atual, através do comando:

Edite o arquivo config.json, e no nó root, mude o valor de readonly para false. E logo abaixo no nó mounts, crie uma chave nova em mounts[0], com o seguinte valor:

Crie o diretório rootfs

Agora execute o runc

Docker Socket

Caso a porta 2375 esteja aberta, é possível acessar o docker do host. Não existe mecanismo de segurança eficaz para isso (não é possível colocar senha), então o melhor é deixá-lo em um servidor privado, pois caso esteja exposto, qualquer pessoa poderá acessá-lo.

Docker Registry

Um Docker Registry é utilizado para armazenar e compartilhar imagens docker. Geralmente o Docker Registry público possui uma segurança boa, como por exemplo Docker Hub, porém o Registry Privado não, pois depende da própria segurança da empresa.

Geralmente no NMAP, iremos encontrar uma saída do tipo

Verificando todas os repositórios

O comando acima só é possível quando o Registry está desprotegido por senha. Caso precise de senha, utilize o HTTP HEAD para ver o tipo de autenticação e depois realize um ataque de Brute Force. Para o exemplo abaixo, a saída no HEAD deve ser www-authenticate: Basic realm="Registry Realm"

Para verificar se as credenciais estão corretas, utilize o comando abaixo:

Pegando as tags dos repositórios

Recupera o manifest identificado pelo nome e referência, onde a referência pode ser uma tag ou digest. Também é possível realizar uma solicitação via HEAD para receber detalhes do Header Response

Com a saída do comando acima, vá em fsLayers e selecione um dos (ou todos) valores de blobSum, de cima para baixo (geralmente com o padrão sha256:<hash>). Feito isso, execute o comando abaixo para baixar os arquivos do container. Geralmente vamos ter 3 ou mais Blobs, sendo o primeiro (de baixo pra cima), a Base que são os arquivos do SO, o segundo que contém os Metadatas e o(s) último(s) que será o Diferencial, ou seja, os arquivos que foram modificados.

Automatizando o Download de Arquivos

Iniciando um Registro Local

Escapando do Container Docker

Capsh

Mostra todos os Capabilities que o Container está executando. Se tiver muitas Capabilities, provavelmente está com um Container Privilegiado, o que é um vetor de ataque. Verifique se a Capability cap_sys_admin está ativa, e se positivo, podemos sair do Docker e acessar o host hospedeiro.

Execute então os comandos abaixo e verifique:

  • df -h = Exibe o overlay apontando para o /

  • fdisk -l = Exibe o /dev/sda1

Caso positivo, poedmos acessar os arquivos da máquina hospedeira, então execute:

Após entrar no /mnt, execute os comandos abaixo para acessar comandos no SO hospedeiro (dependendo do cenário, pode ou não funcionar).

Caso não funcione a execução de comandos no SO, não se preocupe, pois você ainda tem acesso aos arquivos do sistema. Então basta inserir um novo usuário com privilégios root no host hospedeiro e depois acessá-lo de alguma forma, como por exemplo, via SSH

API Docker

Bypass para montar Container com Volume. Primeiro pegue a versão da API (por exemplo 1.41)

Agora crie um container com o volume criado

Inicie e acesse o container

Entre no diretório e enjaule

Deixe o bash com SUID Bit ativo

Saio do Docker e volte para a máquina principal (usuário comum do SO) e faça o PrivEsc

Meterpreter

Caso tenha comprometido um host e esteja com o Meterpreter, utilize os posts abaixo para verificar se o alvo usa docker e então pegar suas credenciais.

Criando Container Privilegiado com Bypass

Privileged Bypass

Útil em casos onde temos acesso ao comando docker, porém não podemos criar containers priviligiados (--privileged).Utilize a maneira abaixo para realizar bypass

Forense

Container Diff

Ferramenta desenvolvida pelo Google para analisar imagens Docker, tanto local quanto remoto.

Instalando

Salvando uma imagem em seu estado atual em arquivo tar

Verificando histórico de modificações de uma imagem

Verificando pacotes adicionados

Docker Diff

Vendo alterações realizadas depois que o container foi montado. Verifique se arquivos sensíveis como /etc/shadow foi alterados, pois isso pode ser indício de um ataque. Na saída podemos ver que as alinhas começam com C (Created), D (Deteled) e A (Altered)

Caso encontre arquivos suspeitos e queira analisar melhor, utilize o comando abaixo para baixá-los. Como exemplo, iremos utilizar o /etc/shadow

Crie um novo container com o arquivo original

Copie o arquivo original para a máquina local

Agora verifique a diferença entre esses arquivos (o que foi modificado e o original)

CRIU (Checkpoint and Restore In Userspace)

Ferramenta que permite criar pontos de restauração de Conatainers

Instalando

Sites

Last updated

Was this helpful?