diff --git a/content/aws/avoiding-detection/guardduty-pentest-botocore.md b/content/aws/avoiding-detection/guardduty-pentest-botocore.md new file mode 100644 index 00000000..33631311 --- /dev/null +++ b/content/aws/avoiding-detection/guardduty-pentest-botocore.md @@ -0,0 +1,82 @@ +--- +author_name: Raajhesh Kannaa Chidambaram +title: Bypass GuardDuty Pentest Findings via Botocore Config +description: Override the default botocore user-agent string in boto3 to prevent GuardDuty PenTest findings from firing. +--- + +# Bypass GuardDuty Pentest Findings via Botocore Config + +
+ +- :material-account-edit:{ .lg .middle } __Original Idea__ + + --- + + This article is based on [Hacking the Cloud Issue #453](https://github.com/Hacking-the-Cloud/hackingthe.cloud/issues/453). + +
+ +## Background + +AWS [GuardDuty](https://aws.amazon.com/guardduty/) inspects the `User-Agent` header in AWS API requests (recorded in CloudTrail) to detect calls made from known penetration testing distributions. When it sees user-agent strings containing identifiers for Kali Linux, ParrotOS, or Pentoo Linux, it triggers a [PenTest finding](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-iam.html#pentest-iam-kalilinux) such as: + +- `PenTest:IAMUser/KaliLinux` +- `PenTest:IAMUser/ParrotLinux` +- `PenTest:IAMUser/PentooLinux` + +The [existing article](guardduty-pentest.md) on this topic covers using Burp Suite as an intercepting proxy to rewrite the `User-Agent` header for the AWS CLI. That approach works but requires setting up a proxy, dealing with TLS certificates, and routing all traffic through Burp. + +If you are working directly with the AWS SDK (boto3/botocore), there is a simpler option: override the user-agent string natively using `botocore.config.Config`. + +## How It Works + +When you create a boto3 session or client, botocore builds a user-agent string that includes your OS, Python version, and botocore version. On Kali Linux, that string will contain something like `kali` in the platform identifier, which is what triggers the GuardDuty finding. + +The [`botocore.config.Config`](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html#botocore-config) class accepts a `user_agent_extra` parameter, but more importantly, you can use `user_agent_appid` or directly patch the user-agent to replace the entire string. Starting with newer versions of botocore, you can set `user_agent_appid` in the config, but the most reliable way to fully control the user-agent is to override it at the session level. + +## Technique + +The following snippet creates a boto3 session with a completely custom user-agent string, removing any OS-specific identifiers that GuardDuty would flag: + +```python +import boto3 +from botocore.config import Config + +# Define a clean user-agent that does not reveal your OS +custom_config = Config( + user_agent_extra="", # prevent appending extra info +) + +session = boto3.Session() + +# Patch the user-agent at the session level +session._session.user_agent_name = "Boto3" +session._session.user_agent_version = "1.35.0" +session._session.user_agent_extra = "" + +# Create clients using this session +sts = session.client("sts", config=custom_config) +print(sts.get_caller_identity()) +``` + +After running this, the `User-Agent` header in your API requests will look something like `Boto3/1.35.0 Python/3.12.0 Botocore/1.35.0` with no mention of Kali, Parrot, or Pentoo. + +You can verify what user-agent is being sent by checking CloudTrail. The `userAgent` field in the event record will reflect whatever you set. + +### Picking a Realistic User-Agent + +To blend in, pick a user-agent value that matches what the target environment likely uses. For example, if the account runs Lambda functions with Python 3.12, a user-agent like `Boto3/1.35.0 Python/3.12.0 Botocore/1.35.0` would look normal in CloudTrail logs. You can reference [Pacu's user-agent list](https://github.com/RhinoSecurityLabs/pacu/blob/master/pacu/user_agents.txt) for realistic values. + +## Limitations + +- **SDK only.** This technique works for boto3/botocore. The AWS CLI builds its own user-agent string and appends additional metadata (CLI version, command name, etc.) that you cannot control through `botocore.config.Config` alone. For CLI use cases, the [Burp Suite proxy method](guardduty-pentest.md) is still the recommended approach. +- **Internal attribute access.** Setting `session._session.user_agent_name` relies on botocore internals. While this has been stable across many releases, it could change in a future version. Test before relying on it in an engagement. +- **CloudTrail is not the only signal.** GuardDuty uses multiple data sources. Changing your user-agent avoids the PenTest finding specifically, but other findings based on network traffic, DNS logs, or anomalous API behavior will still fire. + +## Detection Guidance + +If you are on the defensive side: + +- **Do not rely solely on GuardDuty PenTest findings.** The user-agent string is attacker-controlled and trivially spoofed. Treat PenTest findings as a bonus signal, not a primary detection. +- **Baseline user-agent patterns.** Build detections in CloudTrail that alert on user-agent strings that are unusual for your environment. A sudden appearance of a generic `Boto3/1.35.0` with no Lambda or SDK context in an account that normally uses the CLI could be suspicious. +- **Monitor for `botocore.config` usage patterns.** If you control the compute environment, watch for code that patches `_session.user_agent_name` or sets unusual `Config` values.