实例元数据(metadata)是关于实例信息的一组信息合集,用于配置和管理运行中的实例,metadata
包含不同类型的数据,包括DNS信息,主机名,region相关信息,VPC信息,网络类型与安全组,账号,RAM角色、系统事件等信息。一般分为一下两大类:
基本实例元数据
,包括基本信息与系统事件信息动态实例元数据
,包含动态生成的标识数据,一般用于身份的标识验证
需要注意的是,虽然metadata
只能通过在实例本身进行访问获取,但是获取到的数据是不受身份验证或加密保护的。这一点的存在也导致了SSRF漏洞在云平台、甚至云服务上有了新的用处,即获取metadata
实例元数据进而利用。
metadata
的利用大部分集中在实例具有RAM角色或者存在IAM角色,这时可以通过metadata的接口获取到临时Token,这个临时Token具有该角色的所有权限,如读取存储桶、读取日志、执行指令、甚至创建后门账号、后门实例等等。 下面以Alibaba Cloud
和Gppgle Cloud Platform
的metadata
利用为例。
Alibaba Cloud Metadata Exploit
首先是阿里云,在阿里云ECS实例中即可访问100.100.100.200/latest/meta-data
,会返回所涉及的基础元数据信息。当然这些数据虽然比较敏感,但其实只是机器的基本信息,并没有什么太大的危害,而当只有该实例被授权了RAM角色时,这时候通过metadata
可以获取临时STS token,进而获取该角色的所有权限。
要可以被利用,则首先需要该实例具有RAM角色权限,通过如下方式授权。RAM角色是阿里云的身份管理的一个概念,可以理解为一组权限列表的集合。
这里我们新建一个AliyunTestRole
并只授权Logstore的读取权限。之后再在ECS访问时,便会新出现/ram
路径,通过/ram/security-credentials/
可以获取RoleName,再通过/ram/security-credentials/RoleName
即可获得STS Token.
这样我们拿到了临时Token,之后我们在尝试通过这个token来获取logstore日志:
|
|
可以看到,通过aliyun-cli
利用STS Token即可做该角色所有权限的事情。这里再介绍最为常见高危的一种,创建账号并可以登陆控制台。当然,这个要求该角色具备这些权限。 首先通过STS Token的 createUser
创建一个用户,并配置密码,之后授权AdministratorAccess
管理员权限,
之后登录便可具有控制台的权限,注意登录名是userName@账号id
的形式,账号id可以通过aliyun ram GetAccountAlias
获取。
至此利用成功,除了可以创建后门账号登陆外,有了token也有很多其他的利用方式,这里不再赘述,有兴趣可以看我的云上利用常见总结。
Google Cloud Platform Exploit
和aliyun类似的思路和步骤,GCP
的整体思路和流程也基本一致。谷歌的metadata使用域名的方式进行访问,因此使用metadata.google.internal
或直接使用其解析的保留地址IP 169.254.169.254
均可。我们首先在VM里面去直接请求下,我们可以看到,直接通过curl请求显示403错误,缺失了Metadata-Flavor:Google
header字段。可以看到,这一点google的有着更严格的限制,基本杜绝了通过SSRF漏洞来获取metadata
的数据内容,因为正常业务请求时基本不会带上这个字段,这一点确实比阿里云做的好。除此之外,还有以下的限制:
- 请求需带
Metadata-Flavor:Google
header - 不接受任何包含
X-Forwarded-For
字段的请求,这些请求一般是转发过来的
我们带上Metadata-Flavor:Google
header之后,可以正常返回了。
GCP对新建的每个实例会默认附带一个服务账号,这个服务账号有3种可选的访问权限范围,默认、全部及自定义。可以通过metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
获取token并根据metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes
获取访问权限范围。这里注意token会返回一堆.....
这个忽略去掉就好了,我一开始还以为是脱敏处理拿不到token。拿到token后可以使用google api来进行token验证。
我们来看看默认的策略具有什么权限:
|
|
我们可以看到,其实这里访问范围是对存储桶有读权限的,这里的读是针对项目的所有bucket生效,这一点非常重要。 我们通过API即可获取存储桶,进而获取文件内容。
除了读取数据,我们还可以通过写入元数据SSH密钥的方式获取实例控制权限,前提是具有auth/compute
访问范围。首先是获取metadata fingerprint
,
|
|
最后即可通过密钥证书直接登录获取服务器权限。