Skip to content
Open
Show file tree
Hide file tree
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
76 changes: 75 additions & 1 deletion src/pentesting-cloud/aws-security/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,80 @@ aws-permissions-for-a-pentest.md
{{#endref}}

> [!NOTE]
> After you have managed to obtain credentials, you need to know **to who do those creds belong**, and **what they have access to**, so you need to perform some basic enumeration:
> After obtaining credentials, determine **who they belong to** and **what they can access** before performing basic enumeration.

## Evade Basic Detection

Be aware that API requests made by the AWS CLI include details such as the operating system and version in the `User-Agent` header. CloudTrail records this information in API events, and detection services such as [GuardDuty](aws-services/aws-security-and-detection-services/aws-guardduty-enum.md) can use related activity for detection. Alerts may even be generated for operating systems commonly associated with security testing, such as Kali Linux or Parrot OS.

For more information about the relevant logs and detections, see the [CloudTrail](aws-services/aws-security-and-detection-services/aws-cloudtrail-enum.md) and [GuardDuty](aws-services/aws-security-and-detection-services/aws-guardduty-enum.md) sections.

### Override the AWS CLI User-Agent

AWS CLI v2 supports Python plugins that can replace the complete `User-Agent`
header on every request. This works with the installed `aws` executable and does
not require patching or rebuilding it.

AWS documents this interface in [AWS CLI Configuration Variables: Plugins](https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#plugins). AWS describes CLI v2 plugin support as **"completely provisional"** and says that **"there are no guarantees that a particular plugin or even the CLI plugin interface will be supported in future versions of the AWS CLI v2."** In practice, the interface may change or be removed, so pin the AWS CLI version and test upgrades if you depend on this plugin.

The AWS CLI reads `~/.aws/config` automatically, but it does not automatically import every Python module under `~/.aws`. The plugin system must be enabled explicitly in the global `[plugins]` section. AWS states that you **"must define the `cli_legacy_plugin_path` variable"** and that the CLI then loads each configured plugin by importing its Python module and calling `awscli_initialize`.

Create the plugin as `~/.aws/plugins/user_agent_override.py`:
```python
import os

def awscli_initialize(event_hooks):
def override_user_agent(request, **kwargs):
value = os.environ.get("USER_AGENT")
if value is not None:
request.headers["User-Agent"] = value

event_hooks.register_last("request-created", override_user_agent)
```

Add the directory and module to the global `[plugins]` section in
`~/.aws/config`:

```sh
aws configure set plugins.cli_legacy_plugin_path "$HOME/.aws/plugins"
aws configure set plugins.user_agent_override user_agent_override
```

The plugin is loaded for every AWS CLI invocation, but it changes the header only when `USER_AGENT` is set.

You can test the override with:

```shell
export USER_AGENT="aws-cli-ua-test"
aws --profile white-box-account sts get-caller-identity
```

Then inspect the event in CloudTrail. In the AWS Console, go to:

```txt
CloudTrail → Event history → Region us-east-1 → Event name GetCallerIdentity → JSON view
```

### Override Boto3 User-Agent restrictions

If a policy restricts actions based on the `User-Agent`, such as blocking requests from Boto3, you can use the AWS Management Console in a browser or modify the Boto3 `User-Agent` with its `before-call` event hook.<sup>[[50]](#references)</sup>

```python
import boto3

session = boto3.Session(profile_name="lab6")
client = session.client("secretsmanager", region_name="us-east-1")

client.meta.events.register(
"before-call.secretsmanager.GetSecretValue",
lambda params, **kwargs: params["headers"].update({"User-Agent": "my-custom-tool"}),
)

response = client.get_secret_value(SecretId="flag_secret")
print(response["SecretString"])
```

This changes the Boto3 SDK request header for one operation; it does not change the AWS CLI user agent globally.

## Basic Enumeration

Expand Down Expand Up @@ -450,5 +523,6 @@ aws ...
- [47] [Cloud Custodian repository](https://github.com/cloud-custodian/cloud-custodian)
- [48] [PacBot repository](https://github.com/tmobile/pacbot)
- [49] [StreamAlert repository](https://github.com/airbnb/streamalert)
- [50] [Extensibility guide - Boto3 documentation](https://docs.aws.amazon.com/boto3/latest/guide/events.html)

{{#include ../../banners/hacktricks-training.md}}
Original file line number Diff line number Diff line change
Expand Up @@ -91,26 +91,6 @@ aws-vault login jonsmith # Open a browser logged as jonsmith

The browser extension **<https://github.com/AI-redteam/clier>** can capture temporary AWS Console credentials by intercepting their network response before they are kept only in browser memory.<sup>[[5]](#references)</sup>

### **Bypass User-Agent restrictions from Python**

If there is a **restriction to perform certain actions based on the user agent** used (like restricting the use of Python Boto3 based on the user agent), it is possible to use the previous technique to **connect to the web console via a browser**, or directly **modify the Boto3 user-agent** with its `before-call` event hook as follows.<sup>[[6]](#references)</sup>

```python
import boto3

# Shared by ex16x41
# Create a client
session = boto3.Session(profile_name="lab6")
client = session.client("secretsmanager", region_name="us-east-1")

# Change user agent of the client
client.meta.events.register( 'before-call.secretsmanager.GetSecretValue', lambda params, **kwargs: params['headers'].update({'User-Agent': 'my-custom-tool'}) )

# Perform the action
response = client.get_secret_value(SecretId="flag_secret")
print(response["SecretString"])
```

### **`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,7 +110,6 @@ This operation creates a temporary federated session rather than a persistent IA
- [3] [NetSPI/aws_consoler](https://github.com/NetSPI/aws_consoler)
- [4] [99designs/aws-vault](https://github.com/99designs/aws-vault)
- [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)
- [6] [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)

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