在云计算环境中的渗透,与传统渗透相比,新增加了许多新的攻击面,同时也因为云计算的特点我们需要转变渗透的思维,用云计算的方式去思考云渗透。
基础知识
在云渗透开始之前,我们需要首先阐述标题中提到的云服务端点概念。首先我们需要知道,云api通常被视为云计算的一个基础特征,用户通过访问api去管理对应的云服务。
在实际的使用中,往往会将调用云api的过程封装成sdk,供开发者使用。而在sdk的基础上,还会封装成更方便用户使用的client。
使用client发起的请求和直接调用云api实际上是一致的,以阿里云为例
这里aliyun CLI会先去访问location-readonly确定Endpoint再发起请求,最终发起的请求和在云api平台上发起的请求是一致。
这里的Endpoint,阿里云称为服务地址。实际上在不同的云他有不同的称呼,比如在腾讯云则称为请求域名。在移动云被称为终端节点。在aws和azure都被称为service endpoints。
由于endpoint本身就会有很多种意思,而上述的称谓都有出现歧义的情况,所以这里,我推荐百度搜索“云服务 endpoint url”,百度ai很贴心的解释了这个:
为了方便阐述,这个endpoint在本文被称为云服务端点。
然后,我们需要知道渗透的云归属的类别。云计算通过可以简单地分成公有云、私有云、混合云、多云。
公有云即我们所熟知的阿里云、腾讯云、华为云等对公众开放的云服务,公有云不限制消费者为特定群体,并且消费者在不同的云服务层次上所承担的责任按照责任共担模型来进行划分。
私有云是专属于某个企业或者组织的云,消费者只能是该企业成员。也有企业通过租用第三方云供应商的基础设施来搭建私有云,这种特殊的私有云被称为托管私有云。托管私有云只是让渡了部分建设权给第三方云供应商,云的归属主体仍然是企业。
混合云是由至少两种云组成,通过混合云管理层屏蔽了不同云之间的差异,将云视为一个整体。
多云是集中管理多个不同的云,与混合云不同的是,多云的各个云是相对独立的。
当我们在渗透非公有云时,完全的自建云需要我们得知云api具体用法和云服务端点地址,如果云api的实现方式是依据某个公有云来制作或直接托管公有云的话,则需要得知 云服务端点 和 依据的公有云即可。
那么无论怎么样,侦查云服务端点都是必不可少的一环。下面将用一个实战经历来讲述这个过程。
实战过程
在公司的一次攻防演练的过程中,我通过web的一个任意文件读取漏洞获取到目标服务器的数据库帐号密码,恰好这是一个开放ssh的linux公有云服务器,经过尝试发现,数据库帐号密码同服务器密码,于是很顺利地利用ssh登录到服务器中。
经过文件的翻找,我在这台服务器中找到了有一个配置文件,其中包括了一组accesskey密钥和secretkey密钥以及一个自建的云服务端点地址。通过这一个配置文件发起了对非公有云环境的横向,下面是攻击路线的概览:
关于云服务端点前面已经介绍,对于具体的实施可以参考k8s的apiserver处理来自 kubectl的请求。
我们注意3号攻击路线,这里我们分了两个分支,主要看右边的攻击路线,如下图所示,我们通过翻找文件,拿到了一个包含一组AKSK密钥和一个私有S3 云服务端点的python脚本
在这个python脚本中,目标使用了一个的aws s3的sdk,大致操作是通过向云服务端点请求对s3云服务进行操作,获取bucket内的一个object里的文件,并且读取里面的内容。
亚马逊AWS(Amazon Web Services (AWS) )是国外的一个云服务供应商,类似于国内的阿里云,s3是aws 提供的一项对象存储产品服务,类似国内的oss云存储桶。一个存储桶内有多个bucket,每个bucket内存放object,object通常就是具体的文件,文件的内容则是object的key。对象存储的结构如同所示:
经过侦查,我在4号攻击路线中发现这个云服务端点指向的地址IP是国内的一个非公有云IDC机房。
那么按照云计算划分方式,我们可以认为,这可能是一个托管s3云服务的混合云或者采用s3 云api规范的私有云。
为了方便阐述,我们暂且认定这是个私有云。
像这样的云,如果直接拿着accesskey密钥和secretkey密钥去aws-cli里面进行操作而忽视云服务端点的话,是无效的,因为aws-cli默认请求的云服务端点是aws自身的云服务端点。具体参考aws的官方文档:
当我得知这是一个对象存储并且使用自定义云服务端点时,我首先想到的是使用华为云的obs browser准备读取存储桶中的内容,即攻击路线5。
华为云的obs browser这款对象存储管理工具可以通过可视化的方式去管理对象存储类的资产,并且兼容s3协议支持自定义云服务端点 。
遗憾的是,当我在obs browser上通过指定云服务端点和填入accesskey密钥和secretkey密钥去访问目标,结果发现只能列出存储桶中bucket的名称,其他的栏目都是空的,当我点击bucket试图查看里面的文件时,发现无法进行。
后来经过测试发现,obs browser对于非华为云存储桶的支持程度是不一样的,有些需要在云服务端点中手动拼接region才能进入,有些则可以直接进,因此利用华为云obs browser管理其他云供应商的存储桶,是一种方法,但不一定好用。
既然无法使用可视化工具进行管理,我又回到最开始的脚本文件中,我重新审视并决定用aws-cli工具进行操作,因为脚本文件中使用了aws s3的sdk,那么无论目标是否为s3公有云,使用aws-cli进行发送请求必然是符合 云api请求规范的。
通过 --云服务端点-url 参数附加上指定的云服务端点 地址,如果目标有SSL证书强制校验的话,则需要在请求时附加上证书文件,这里不存在强制校验,仅仅只是要求使用https协议,所以可以直接--no-verify去跳过证书警告
在这里,我找到了一个py文件,里面有其他云数据库的帐号密码,可以继续横向即攻击路线6。
除此之外,我还思考了一个问题,面对私有云,能否可以像公有云一样,直接操作其他的资源,比如说我用s3 的云服务端点去实现类似 aws iam list-user (列举当前云的iam用户)的操作呢?
经过尝试我发现是不可以的,也就是攻击路线7遇到的情况,大致类似于下面的操作:
这里我通过阿里云改变云服务端点来模拟私有云的请求。当我们请求操作阿里云的rds(云数据库),不附加云服务端点,会使用默认云服务端点,请求正常。
请求操作rds,但云服务端点换为ram(访问控制服务)的云服务端点,则会报错:
请求操作ram,指定云服务端点为ram的云服务端点则正常使用:
通过这个简单的例子,可以得知,不同的操作实际上是去向不同的云服务端点发起请求,并且不能混用。
还有另一个非通用结论是,解析云服务端点为IP后,再放入--endpoint中请求也是无法正常操作的,大家可以尝试一下。
因此,由于不存在一个云服务端点可以处理所有云服务的情况,我们需要去做枚举云服务端点的操作才能横向到其他的云服务。
通过更仔细地观察脚本文件,我发现存储桶对应的云服务端点叫ossxxx.xxx.com,那么我们可以去猜测可能存在的访问控制云服务端点、云服务器云服务端点等其他云产品的云服务端点。
但按照aws的命名规则,对象存储叫s3,而阿里云的命名规则才是存储桶是oss,也就是说这里的云服务端点的命名并不遵循AWS的叫法,而是按照创建者自己理解的命名去制作的云服务端点。
综合考虑下来,我认为这个命名大概率会取某个公有云的相同命名。
为了去嗅探这个云服务端点,我开始搜集了aws、google cloud、azure、阿里云、腾讯云、华为云六家对应云服务的缩写,最终做成了一个字典:
https://github.com/shadowabi/S-BlastingDictionary/blob/main/CloudService.txt
如下图所示:
在制作完字典后,我发现直接用cli配合字典利用批处理来批量发送请求的动静有点大而且不够方便。因此我觉得还可以进一步操作,在最小动静的前提下实现自动侦查。
经过思考,我发现利用dns查询的方式是最隐蔽的探测域名的方法,并且利用dns的srv记录,若存在则可以以非爆破的形式完成端口发现的任务。
这个方法来源于同为狼组的Esonhugh师傅 的k8spider项目:
https://github.com/Esonhugh/k8spider
确定了第一步是DNS侦查之后,还需要去确定侦查到的结果尽可能过滤无用数据,因此我在此基础上,做了一款专门的工具,工作流程如下图 :
这是最终的成果: https://github.com/wgpsec/EndpointSearch
题外话:EndpointSearch这个工具不仅仅可用于探测非公有云的云服务端点,受到Black Hat 2023议题:Evading Logging in the Cloud: Bypassing AWS CloudTrail的启发,他也可以用于侦查公有云的非生产云服务端点。
通过这个流程,我们仅仅使用了web探活程度的动静就搜集到可能的云服务端点。由于互联网上众多的网络资产测绘引擎在不断扫描资产,因此这个动静将会掩盖在互联网众多扫描行为中。
有了这个工具,我通过攻击路线8横向到其他的云服务中。
如何防御
这取决于创建者是如何理解和使用云计算的,通常情况下,公有云的云服务端点是公开的,因为他的消费者是来自互联网的所有人,因此不会去限制对云服务端点的访问。换言之,创建者需要根据自己的业务需求去考虑是否做边界准入的限制。
既然云服务端点的边界准入限制不是必然存在的,就需要有更多的防线,在纵深防御策略的指导下,需要假设防线失效后的后续防护手段。
不限制准入不代表不需要警惕陌生的请求者,因此针对异地访问的告警机制是很有必要的。
然而,告警并不会真正拦截恶意的攻击者,他只是尽快通知管理员进行研判的一个手段,在实际实践中,管理员不看告警或者没有及时看告警的,又或者攻击者绕过告警发起攻击,也是可能的。
我们再次假设前两道防线都已经失效了,此时攻击者取得的成果大小取决于攻击者使用的AKSK权限有多高,这就涉及一个IAM身份管理的安全构建问题,是否遵循最小特权原则和职责分工原则。举个反面例子,长期使用主账号的AKSK,泄漏之后攻击者直接是管理员,相当于域环境下域管帐号被控制。
除此之外,事后能否利用操作审计进行溯源追踪,发现问题根源(AK泄漏事件的源头),这也是云安全构建需要关注的问题。
同样的,区别于公有云,云api可能会存在安全漏洞,例如越权问题。
公有云有权责共担模型,可以使消费者只需要关注非常小的一部分安全,而选择私有云或混合云,就需要承当更多的安全责任。
参考链接
https://recon.cloud
https://www.cloudflare.com/zh-cn/learning/security/api/what-is-a-cloud-api/
https://www.cloudflare.com/zh-cn/learning/security/api/what-is-api- endpoint/
https://docs.aws.amazon.com/general/latest/gr/rande.html#global- endpoints
https://learn.microsoft.com/en-us/cli/azure/use-azure-cli-rest-command?tabs=bash
https://ecloud.10086.cn/op-help-center/doc/article/48179
https://cloud.tencent.com/document/product/1278/46697
https://next.api.aliyun.com/product/Rds
https://cloud.google.com/vpc/docs/private-service-connect?hl=zh-cn
https://aws.amazon.com/cn/blogs/china/announcing-aws-cloud-control-api/
https://help.aliyun.com/zh/oss/user-guide/access-to-oss-resources-from-ecs-instances-by-using-an-internal-endpoint-of-oss?spm=a2c4g.11174283.0.i2
https://github.com/Esonhugh/k8spider
https://github.com/shadowabi/S-BlastingDictionary/blob/main/CloudService.txt
https://github.com/wgpsec/EndpointSearch
本文作者:
shadowabi,雪诺安全攻防工程师,狼组安全团队成员,CSA大中华区云渗透测试工作组成员