万字长文学习云安全STSPolicy注入在漏洞挖掘中的妙用"

admin 2026-10-22 14:52:37 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

万字长文学习云安全 STS Policy注入在漏洞挖掘中的妙用

Z2O安全攻防

2026年10月15日 21:08
北京

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

以下文章来源于亿人安全
,作者行之

亿人安全
.

知其黑,守其白。手握利剑,心系安全。主要研究方向包括:Web、内网、红蓝对抗、代码审计、安卓逆向、CTF。

前言

我是行之,好久都没更新了,发一篇最近分析的文章吧。随着云原生架构的普及,针对凭据与身份边界的攻击正成为主流。正好近期得知朋友挖掘了几个严重漏洞,于是跟他学习了一下思路,然后研读了一下海外云安全文献,发现是通过针对%20STS(Security%20Token%20Service,安全令牌服务)的攻击:借助文件名、接口入参等可控字段篡改%20STS%20令牌下发逻辑,通过%20STS%20Policy%20注入获取高权限临时令牌,由此触发高危云上漏洞。原本计划讲个议题的,但国内相关研究文章偏少,既然没什么文章基础,于是先写篇长文沉淀一下,本文是我的学习过程,会从%20AK/SK、STS%20的基础原理讲起,搭配本地靶场搭建与真实的实战案例,为国内安全同行、白帽子提供攻防思路参考。本文纯手写原创,全文共一万字,欢迎各位安全同行交流探讨,也在此感谢先知社区提供发布平台。

一、先从一个最熟悉的注入说起:SQL

首先讲解STS云注入,我们最好先回到所有人都见过的%20SQL%20注入。它的本质其实是用户输入的数据被当作数据库代码进行了执行,也就是输入流入侵到了控制流的一个过程。

后端这么去写:

SELECT%20\*%20FROM%20uploads%20WHERE%20owner%20=%20'{input}';

开发者心里,input只是一个字符串值。正常输入alice时,数据库看到:

SELECT%20\*%20FROM%20uploads%20WHERE%20owner%20=%20'alice';

但当input变成alice'%20OR%20'1'='1,前面那个单引号先把原字符串闭合,后面的内容就进入了%20SQL%20语法,数据库最后看到的是一个永真条件:

SELECT%20\*%20FROM%20uploads%20WHERE%20owner%20=%20'alice'%20OR%20'1'='1';

记住这条数据流,下面会把同一个解释器换成%20JSON%20和云授权:

用户输入%20→%20字符串拼接%20→%20某门语言的源码%20→%20解释器%20→%20改变了语义

这里关于SQL注入,笔者不再赘述。历史上的很多漏洞都是输入流入侵到了控制流的过程,例如

SSTI(模板注入):输入进入%20Freemarker、Velocity、Jinja2%20的模板语法,${}%20或%20#{}%20之间的内容被模板引擎当代码渲染,变成%20RCE

Log4Shell(Log4j%20JNDI):输入的字符串里带%20${jndi:...},本该只是一行日志,却被%20Log4j%20当成查找指令触发%20JNDI%20加载,RCE。

所以只要我们能够找到输入流和控制流之间的关系,就可以更好的挖掘漏洞。

二、STS到底是个什么东西?

关于STS,很多人挖洞看到的通常是AK、SK、还有一个Token,比如长这个样子。

然后测试的时候一般会尝试能不能../../../或者直接调用一些现有的安全工具对这个下发的sts安全凭证进行测试,我们也可以在公众号上看到一些前辈发的文章和工具

但其实我们在挖掘一个东西之前,要去深入的了解这个东西,于是我们可以看一下云厂商文档对于STS的介绍。

其中我们可以看到一个有趣的东西,就是它的名字叫做Security%20Token%20Service,翻译过来就是安全令牌服务,那么为什么要这个东西呢,其实在早期阶段,存储桶刚出来的时候。很多开发在做文件上传,喜欢把AccessKey%20Secret硬编码在前端,来做文件上传。后来通过很多工具,例如Hae、或者Yakit,都可以对此类密钥进行扫描。互联网上关于AKSK的利用工具也是层出不穷。例如笔者曾经用过的一款teamssix%20的cf(Cloud%20Exploit%20Framework,云利用工具)(现已停更),就有很多的功能。因此云厂商后来统一推荐用%20STS:简单来说,就是由可信后端保管长期凭证,或者通过%20RAM%20角色获取调用%20STS%20的权限(这里用的比较多的就是PutObject和GetObject),再针对当前这一次上传签发一组临时凭证。这组凭证的有效期可以很短,权限也可以通过会话%20Policy%20进一步收窄,比如只允许向指定存储桶、指定目录,甚至指定对象上传文件。这样一来,长期%20AK/SK%20就不需要进入前端;即使临时凭证意外泄露,攻击者能够利用的时间和权限范围也都比较有限。

如果还是听不懂的话,我们可以来看看这个例子

很多业务都有\"用户往对象存储传文件\"的场景:工单附件、客服图片、头像、竞赛作品上传。把长期%20AccessKey%20放进浏览器是不可能的(谁拿到页面谁能复用),所以正常做法是:

用户登录业务系统;

浏览器要传文件时,先问业务后端要一份

短期凭证

;

业务后端用自己的长期身份,向云厂商申请一枚%2015%20分钟的临时凭证(STS);

浏览器拿着这枚临时凭证,

直接

把文件传到对象存储。

三、一个简单的输入流入侵到了控制流案例

如果放到代码上,我们可以手搓一个真实的业务环境,这里就拿官网的API文档举例

这里我们需要先去创建一个RAM%20用户,拿到AccessKey%20ID%20和%20AccessKey%20Secret

{

\"Version\":%20\"1\",

\"Statement\":%20[

//Statement%20是具体的授权规则列表

{

\"Effect\":%20\"Allow\",

//Effect%20表示这条规则的效果。常见取值有:Allow:允许。Deny:拒绝。这里默认是Allow放过去

\"Action\":%20\"oss:PutObject\",

//动作,这里可以从文档里面获取,PutObject就是可以上传对象,ListObject就是列出对象

\"Resource\":%20\"acs:oss:\:\:examplebucket/exampledir/\*\"

//持有这份权限的身份,可以向%20examplebucket%20存储桶中所有以%20exampledir/%20开头的对象写入文件,但没有读取、删除或访问其他目录的权限。

}

]

}

在权限编辑页面,我们可以选择对角色权限进行编辑,以上是笔者自己从官网获取到的

oss%20:%20PutObject

│%20 %20 %20 %20│

│%20 %20 %20 %20└──%20具体操作:写入对象

└──────────%20云服务:对象存储%20OSS

oss:PutObject%20主要用于向%20OSS%20上传或写入对象。比如:

exampledir/avatar.png

exampledir/report.pdf

exampledir/2026/07/demo.txt

Resource 表示这条权限可以作用在哪些资源上。把它拆开来看:

acs : oss : \ : \ : examplebucket / exampledir/\*

│     │     │   │          │              │

│     │     │   │          │              └─ 对象名称前缀

│     │     │   │          └──────────────── Bucket 名称

│     │     │   └─────────────────────────── 阿里云账号范围

│     │     └─────────────────────────────── 地域region

│     └───────────────────────────────────── 云服务

└─────────────────────────────────────────── 阿里云资源名称前缀

为什么我不能任意对象读取?

在传统文件系统中: exampledir/../../target.txt 会被路径解析函数归一化为: ../target.txt 因此可能逃出原来的目录。 但 OSS 使用的是 Object Key,不是真实文件路径。阿里云官网明确说明,OSS 本身没有传统文件系统的文件夹概念,只是通过 Key 中的 / 模拟目录效果。所以在 OSS 语义中: exampledir/../../target.txt 通常表示的就是一个完整 Key: Key = \"exampledir/../../target.txt\" .. 并不天然具有“返回上级目录”的含义。它不会自动变成: target.txt 如果会话 Policy 是: \"Resource\": \"acs:oss:\:\:examplebucket/exampledir/\*\" 那么 exampledir/../../target.txt 即使被接受,仍然只是一个以 exampledir/ 开头的 Key。它不会因此覆盖 Bucket 根部真正名为 target.txt 的对象。

简单来说就是无论你在客户端怎么传递,到了调用的时候其实还是会以字符串的形式进行传入,不能从输入流入侵到控制流。

哪些情况下会真的出现跨范围写入

这里自己学习了开发角度,就可以很容易明白如下这个案例

\"Statement\": [

{

\"Effect\": \"Allow\",

\"Action\": [

\"oss:GetObject\",

\"oss:PutObject\"

],

\"Resource\": [

\"acs:oss:\:\:BUCKET/uploads/alice/123.png\"

]

},

{

\"Effect\": \"Allow\",

\"Action\": [

\"oss:ListObjects\"

],

\"Resource\": [

\"acs:oss:\:\:BUCKET\"

]

}

]

}

但如果所有上传请求都直接获得第二条 Statement,那么普通用户无需输入\*,申请一次正常 STS 就可能列桶。这属于上传凭证权限配置过宽,你也可以理解成脱裤子放屁,直接sts拿cdk探测权限就探测出来了,无论你输入啥他肯定都有这个权限

所以在输入\*的时候其实并不会当作资源通配符去解析,也就不存在列桶的问题

九:文末

STS Policy 注入的价值,其实仍然在于输入流入侵控制流这个老问题。当文件名、目录、扩展名、Object Key 等原本只应作为业务数据使用的参数,跨越数据边界进入 JSON Policy、模板、命令或查询语句时,它们就可能改变原本的授权语义。最终造成的未必都是传统意义上的代码执行,也可能是动作范围扩大、资源范围扩大、跨目录访问、对象覆盖,甚至临时凭证权限提升。

所以审计 STS 相关接口时,重点不只是看有没有下发临时凭证,而是要继续思考:用户输入最终进入了哪里?服务端生成了怎样的Action、Resource、Condition 和 Object Key?角色上限是什么?这份临时凭证在数据面实际可以做什么?

感谢 weiwei、zer0one、Clown 、知名小朋友等师傅在案例、思路和测试细节上提供的帮助。

参考文献

[1] 《STS 身份注入攻击》

https://mp.weixin.qq.com/s/RGHT7brTuLaJ91ouaLvRzQ

[2] 阿里云 RAM:AssumeRole API

https://help.aliyun.com/zh/ram/developer-reference/api-sts-2015-04-01-assumerole

[3] 阿里云 RAM:权限策略基本元素

https://help.aliyun.com/zh/ram/user-guide/policy-elements

[4] 腾讯云 CAM:策略语法

https://cloud.tencent.com/document/product/598/10603

[5] AWS IAM:Session Policies

https://docs.aws.amazon.com/IAM/latest/UserGuide/access\_policies.html#policies\_session

[6] AWS STS:AssumeRole API

https://docs.aws.amazon.com/STS/latest/APIReference/API\_AssumeRole.html

    多款产品入选!|《工业控制系统信息安全产品及服务指南(2026版)》发布" 网络安全文章

    多款产品入选!|《工业控制系统信息安全产品及服务指南(2026版)》发布"

    工业控制系统信息安全产业联盟发布《工业控制系统信息安全产品及服务指南(2026版)》,交大捷普自主研发的工业防火墙、工业网闸及漏洞扫描系统等多款国产化产品入选。该指南旨在为工业用户提供选型参考,应对IT与OT融合趋势下的合规升级与安全挑战。捷普未来将持续深耕工业互联网安全领域,赋能产业融合发展。
    等级保护建设:安全建设管理—产品采购和使用" 网络安全文章

    等级保护建设:安全建设管理—产品采购和使用"

    本文解析等级保护中产品采购和使用管理要求,强调依法采购合规网络安全产品、密码产品符合国家密码管理要求、开展选型测试并建立候选产品名单,融入供应链安全治理理念,参考国际标准,形成覆盖全生命周期的安全管理机制,为等保建设提供可操作指导。
    评论:0   参与:  0