diff --git a/src/pentesting-cloud/aws-security/README.md b/src/pentesting-cloud/aws-security/README.md
index 9a546564f9..41235f7d51 100644
--- a/src/pentesting-cloud/aws-security/README.md
+++ b/src/pentesting-cloud/aws-security/README.md
@@ -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.[[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
@@ -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}}
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}}