From b68ce8f17ce3a8f475c4d2fbed5a8a62b3f74141 Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Fri, 18 Sep 2026 15:48:42 +0000 Subject: [PATCH 1/5] docs(aws): relocate Boto3 user-agent guidance --- src/pentesting-cloud/aws-security/README.md | 22 ++++++++++++++++++ .../aws-sts-post-exploitation/README.md | 23 +------------------ 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/pentesting-cloud/aws-security/README.md b/src/pentesting-cloud/aws-security/README.md index 9a546564f9..142aa945e9 100644 --- a/src/pentesting-cloud/aws-security/README.md +++ b/src/pentesting-cloud/aws-security/README.md @@ -399,6 +399,27 @@ export AWS_CA_BUNDLE=~/Downloads/certificate.pem aws ... ``` +### Override Boto3 User-Agent restrictions + +If a policy restricts actions based on the user agent, such as blocking requests from Python Boto3, use the AWS console through a browser or modify the Boto3 user agent with its `before-call` event hook.[[50]](#references) + +```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. + ## References - [1] [Hacking AWS end-to-end - remastered](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ) @@ -450,5 +471,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}} diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md index f5d9f04b34..841e46db22 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md @@ -91,26 +91,6 @@ aws-vault login jonsmith # Open a browser logged as jonsmith The browser extension **** can capture temporary AWS Console credentials by intercepting their network response before they are kept only in browser memory.[[5]](#references) -### **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.[[6]](#references) - -```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.[[2]](#references) @@ -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}} From e7eafbba6aa1710eac51f20d83fb256c7b15cc60 Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Fri, 18 Sep 2026 16:52:59 +0000 Subject: [PATCH 2/5] docs(aws): add User-Agent override guidance --- src/pentesting-cloud/aws-security/README.md | 94 ++++++++++++++++----- 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/src/pentesting-cloud/aws-security/README.md b/src/pentesting-cloud/aws-security/README.md index 142aa945e9..8437929440 100644 --- a/src/pentesting-cloud/aws-security/README.md +++ b/src/pentesting-cloud/aws-security/README.md @@ -66,7 +66,78 @@ 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). + +Create the plugin in a dedicated directory (`~/.aws/plugins`): +```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 "$PLUGIN_DIR" +aws configure set plugins.user_agent_override awscli_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.[[50]](#references) + +```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 @@ -399,27 +470,6 @@ export AWS_CA_BUNDLE=~/Downloads/certificate.pem aws ... ``` -### Override Boto3 User-Agent restrictions - -If a policy restricts actions based on the user agent, such as blocking requests from Python Boto3, use the AWS console through a browser or modify the Boto3 user agent with its `before-call` event hook.[[50]](#references) - -```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. - ## References - [1] [Hacking AWS end-to-end - remastered](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ) From a7d185fe32303939a8e70662ba249254d734b240 Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Fri, 18 Sep 2026 16:56:29 +0000 Subject: [PATCH 3/5] docs(aws): remove useless colon --- src/pentesting-cloud/aws-security/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pentesting-cloud/aws-security/README.md b/src/pentesting-cloud/aws-security/README.md index 8437929440..2eec529d48 100644 --- a/src/pentesting-cloud/aws-security/README.md +++ b/src/pentesting-cloud/aws-security/README.md @@ -66,7 +66,7 @@ aws-permissions-for-a-pentest.md {{#endref}} > [!NOTE] -> After obtaining credentials, determine **who they belong to** and **what they can access** before performing basic enumeration: +> After obtaining credentials, determine **who they belong to** and **what they can access** before performing basic enumeration. ## Evade Basic Detection From 7865a99f8c7c2713d86539bd2e168ada36c5c109 Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Fri, 18 Sep 2026 17:13:07 +0000 Subject: [PATCH 4/5] docs(aws): clarify CLI plugin setup --- src/pentesting-cloud/aws-security/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pentesting-cloud/aws-security/README.md b/src/pentesting-cloud/aws-security/README.md index 2eec529d48..24968e3cea 100644 --- a/src/pentesting-cloud/aws-security/README.md +++ b/src/pentesting-cloud/aws-security/README.md @@ -80,9 +80,11 @@ 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 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. -Create the plugin in a dedicated directory (`~/.aws/plugins`): +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/awscli_user_agent_override.py`: ```python import os @@ -99,7 +101,7 @@ Add the directory and module to the global `[plugins]` section in `~/.aws/config`: ```sh -aws configure set plugins.cli_legacy_plugin_path "$PLUGIN_DIR" +aws configure set plugins.cli_legacy_plugin_path "$HOME/.aws/plugins" aws configure set plugins.user_agent_override awscli_user_agent_override ``` From b0d41f252e4a149999568b6b1ba6a6314e8b65fe Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Fri, 18 Sep 2026 22:48:31 +0000 Subject: [PATCH 5/5] docs(aws): rename AWS CLI user-agent plugin --- src/pentesting-cloud/aws-security/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pentesting-cloud/aws-security/README.md b/src/pentesting-cloud/aws-security/README.md index 24968e3cea..41235f7d51 100644 --- a/src/pentesting-cloud/aws-security/README.md +++ b/src/pentesting-cloud/aws-security/README.md @@ -84,7 +84,7 @@ AWS documents this interface in [AWS CLI Configuration Variables: Plugins](https 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/awscli_user_agent_override.py`: +Create the plugin as `~/.aws/plugins/user_agent_override.py`: ```python import os @@ -102,7 +102,7 @@ Add the directory and module to the global `[plugins]` section in ```sh aws configure set plugins.cli_legacy_plugin_path "$HOME/.aws/plugins" -aws configure set plugins.user_agent_override awscli_user_agent_override +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.