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
Dentro de cada diretório (que representa um recurso), tem os subrecursos
Criando um Cgroups
Listando todos os Cgroups
Definindo um valor pelo Cgroups. Os comandos são "repetidos", porque existe um bug, então deve-se executar os 3 comandos
Verificando o valor
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 processosVeja 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 ooverlay
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