behind-the-curtain-part-01

What’s Behind the Curtain? AWS Bedrock AgentCore Runtime Tear Down – Part I

Dan Gansel September 14, 2026

What’s Behind the Curtain? AWS Bedrock AgentCore Runtime Tear Down – Part I

Introduction

When you deploy an AI agent to AWS Bedrock AgentCore Runtime, your code runs inside a Firecracker microVM – but it doesn’t run alone. In this three-part series, we tear down the platform internals, document what we found, and assess how well the isolation holds up.


Setting the Stage

AWS Bedrock AgentCore Runtime is pitched as a managed execution environment for AI agents. You bring your agent code and AWS provides the runtime with pillars of enterprise capability such as: identity management, sandboxed tooling, microVM isolation, gateway, observability, etc.

image-22-1024x553

AgentCore Runtime feature overview core pillars

The research question was straightforward: what actually runs inside this microVM alongside your code?

AgentCore supports two deployment methods – uploading agent code to S3, or pointing to an ECR container image. We chose ECR because it was easier to bake arbitrary tools into the image.

image-16-1024x134

AgentCore console showing the “Agent source” picker – S3 Source vs ECR Container

We built a container image with netcat installed, deployed it as an AgentCore Runtime, and connected back with a reverse shell. From that terminal session, we started probing.

image-24-1024x488

Research setup: reverse shell via netcat into the container session, then probe MMDS


The MicroVM Metadata Service

The first target was the metadata service at 169.254.169.254. In a Firecracker microVM, this is the MMDS (MicroVM Metadata Service) – the equivalent of EC2’s Instance Metadata Service (IMDS), but provided by the Firecracker hypervisor directly.

Enumerating the MMDS paths revealed these entries:

image-12

MMDS path enumeration results

A quick check of the IAM credentials confirmed they belonged to our own configured role – not a foreign identity.

The tags endpoint was more interesting. Alongside standard metadata, two entries stood out:

image-19

Unusual MMDS tags

Curling the presigned log URLs revealed something we weren’t expecting:

image-23-1024x215

Presigned log URL output showing “kepler” bucket name, AWS-internal account ID, ASIA credentials, and PutObject action.

The URL pointed to an S3 bucket in an AWS-internal account – kepler-... – with embedded temporary credentials (ASIA...) and a single allowed action: PutObject. A KMS key ID was provided alongside it for server-side encryption.

We were looking at the logging pipeline for “Project Kepler.” The Runtime ships internal platform logs to an AWS-owned S3 bucket using pre-signed URLs delivered through the metadata service.

We confirmed the write path worked – a PutObject to the kepler bucket succeeded with HTTP 200 and returned the full KMS key ARN:

image-18-1024x269

Successful PutObject returning the full KMS key ARN

To understand who’s behind the identity embedded in the presigned URL, we used two techniques:

First, we ran aws sts get-access-key-info against the ASIA… access key embedded in the presigned URL to identify the owning account:

image-13-1
image-14

Result: the credentials belong to an AWS-internal account

This confirmed the credentials belong to an AWS-internal account, not our own – the logging pipeline runs under AWS’s identity.

Second, we set a VPC Endpoint Policy with an explicit deny and replayed the PutObject request – the resulting AccessDenied error leaked the full IAM role ARN:

VPC Endpoint Policy deny error leaking the IAM role ARN behind the presigned URL credentials

Meanwhile, running tcpdump revealed constant metadata pulls – something inside the microVM was periodically requesting the presigned log URL from MMDS:

image-25-1024x498

tcpdump output showing periodic GET requests for aws_presigned-log-url

Our container wasn’t alone. Something else was running inside this microVM, periodically reading the log configuration from MMDS and shipping logs to AWS’s internal S3 bucket.

The question became: who is sending these logs?


Container Escape – Breaking Out of the Box

To answer that question, we needed to see what was running outside the container and some extra privileges. That meant a container escape.

Container escapes typically require two preconditions: an exposed container runtime socket, and overly permissive Linux capabilities. We checked both.

Docker socket: Not present.

image-15

Probe for docker socket

Containerd socket: Present, with read/write permissions. And we were running as root.

image-17-1024x116

Probe for containerd socket

Linux capabilities: CAP_SYS_ADMIN was present, along with a few other capabilities.

image-21-1024x186

Probe for linux capabilities

Both preconditions met. The escape technique was textbook: use the containerd socket to launch a new privileged container with the host filesystem mounted.

image-20-1024x441

Container escape flow

This technique revealed the AgentCore platform binaries among them: Agent, Proxy, Logger, and Sandbox. These are the internal components of Project Kepler, running alongside your code in the microVM. The Logger was our periodic MMDS reader.

*Later on, AWS GA’d InvokeAgentRuntimeCommand – a public API that executes commands inside the running agent container via ctr exec. This is the same privileged context where the escape primitives live. The original escape required deploying an image with tooling baked in, this API removes that precondition. Any principal with the IAM permission can reach the escape against an unmodified agent.

Conclusion

In this post, we explored the internals of an AWS Bedrock AgentCore Runtime microVM – starting from a reverse shell, through the MicroVM Metadata Service where we discovered presigned URLs pointing to an AWS-internal S3 bucket and a hidden logging pipeline, to a container escape that revealed four platform binaries running alongside our code.

Next time, we’ll turn that foothold into something more creative – hijacking AWS’s own logging pipeline through an MMDS man-in-the-middle, intercepting the platform proxy’s TLS traffic to capture live invocation requests, and forging internal JWTs to invoke container sessions off the books.


This research was presented at Cloud Village, DEF CON, by Dan Gansel of Upwind Security.

Contents

Further Reading

upwind-code

Upwind Code Expands Enterprise Coverage to Azure DevOps and Bitbucket Cloud

Modern development organizations rarely keep all their code in one place. Teams may use different version control platforms because of acquisitions, business-unit preferences, regional requirements, or existing development workflows. But when code is spread across multiple providers, application security coverage can become fragmented too. Today, Upwind Code adds support for Azure DevOps and Bitbucket Cloud.…
Blue-agent

Upwind Blue Agent – Increasing the Scope and tooling to a new level of incident response

Cloud attacks do not stay within the boundaries of a single security tool. An intrusion can begin with an API request, execute a process inside a Kubernetes workload, modify a file, contact an external host, use a cloud identity, and change cluster state, all as part of the same incident. But the evidence needed to…
Upwind-Sentinel

Upwind for Microsoft Sentinel – Available on Marketplace and Security Store

Security teams should not have to switch between tools to understand what is happening across their cloud environments. That’s why we’re excited to announce that the Upwind solution for Microsoft Sentinel is now available through the Microsoft Marketplace and the Microsoft Security Store. The integration brings Upwind security data directly into Microsoft Sentinel, helping security…
Add the Upwind RSS Feed to Slack
Connect the Upwind RSS Feed to your Slack.
Follow the how-to here.
Threat RSS
Add the Upwind RSS Feed to Slack
Connect the Upwind RSS Feed to your Slack.
Follow the how-to here.
Main RSS