STS 身份注入攻击
STS简介    STS全称安全凭证服务(Security Token Service),在云服务中最常用到的临时身份管控方案。无论是在前端文件上传、亦或是子账号权限分配,他通过主(子)账户,去调用权 2024-12-31 10:11:7 Author: govuln.com(查看原文) 阅读量:41 收藏

STS简介

    STS全称安全凭证服务(Security Token Service),在云服务中最常用到的临时身份管控方案。无论是在前端文件上传、亦或是子账号权限分配,他通过主(子)账户,去调用权限下发的API,在API参数中,配置相应的权限字符串(Policy),服务端则会解析用户上传的权限字符串,给出相应的的临时账户,一般由accessKey、accessKeySecret、STS Token组成。下面列举下国内常见的STS文档:

阿里云
https://help.aliyun.com/zh/ram/product-overview/what-is-sts
百度云
https://cloud.baidu.com/doc/IAM/s/Qjwvyc8ov
华为云
https://support.huaweicloud.com/usermanual-organizations/org_20_0038.html
腾讯云
https://cloud.tencent.com/document/product/1312/48195 

STS身份注入攻击

    身份注入漏洞一般发生在云租户允许用户去自定义权限字符串(Policy)中的部分元素时存在,例如在对象存储上传时,服务端使用STS进行权限控制,但是又允许用户输入上传的后缀、目录或大小时,会存在问题。这里我们以腾讯云为例(腾讯云STS已经在去年末,通过API服务侧限制Policy进行止血,理论不再会存在此类型漏洞)大概理一下此类漏洞的原理以及利用方式。

    在文档中,我们可以看到,Policy的生成,依赖于 CAM 策略语法

    所谓的CAM策略语法,实际上就是一个由versionstatement组成的json字符串,其中statement是我们需要给STS临时身份授权的具体策略列表,由核心元素包括委托人(principal)、操作(action)、资源(resource)、生效条件(condition)以及效力(effect)组成的json列表组合而成。下面是一个示例:

{  "version""2.0",  "statement": [    {      "principal": {        "qcs": [          "qcs::cam::uid/1238423:uin/3232523"        ]      },      "effect""allow",      "action": [        "cos:PutObject",        "cos:GetObject",        "cos:HeadObject",        "cos:OptionsObject",        "cos:ListParts",        "cos:GetObjectTagging"      ],      "resource": [        "qcs::cos:ap-beijing:uid/1238423:bucketA-1238423/",        "qcs::cos:ap-guangzhou:uid/1238423:bucketB-1238423/object2"      ],      "condition": {        "ip_equal": {          "qcs:ip""10.121.2.10/24"        }      }    },    {      "principal": {        "qcs": [          "qcs::cam::uid/1238423:uin/3232523"        ]      },      "effect""allow",      "action""cmqqueue:SendMessage",      "resource"""    }  ]}

    看完上面的示例,这里给一个很简单的案例,我们在开发上传API的时候,如果想要用户只能上传目录(dir)为userid,后缀(ext)为.txt的文件,应该如何进行去编写业务逻辑?

    一般来说,业务会考虑从session中取得userid,后缀或是文件名,则可能从用户输入的参数中获取,再接入到我们的statement中,这样我们的策略就会变成(一般在后端调用不会存在换行符,这里为了美化展示,加上了换行符):

{  "version""2.0",  "statement": [    {      "principal": {        "qcs": [          "qcs::cam::uid/1238423:uin/3232523"        ]      },      "effect""allow",      "action": [        "cos:PutObject"      ],      "resource": [        "qcs::cos:ap-beijing:uid/1238423:bucketA-1238423/{dir}/{filename}.{ext}"      ]    }  ]}

    到这里,其实此类漏洞就已经很明显了,当我们的ext是用户可控的话,我们就可以构造出,类似于:

ext=txt"]},{"effect": "allow","action":[""],"resource":["qcs::cos:","qcs::cvm:*

    最终,发送到API的statement就成了我们修改过的恶意的,可以接管cos、以及cvm的statement,美化后如下:

{  "version""2.0",  "statement": [    {      "principal": {        "qcs": [          "qcs::cam::uid/1238423:uin/3232523"        ]      },      "effect""allow",      "action": [        "cos:PutObject"      ],      "resource": [        "qcs::cos:ap-beijing:uid/1238423:bucketA-1238423/{dir}/{filename}.txt"	  ]	}, {      "effect""allow",      "action":["*"],      "resource":[          "qcs::cos:*",          "qcs::cvm:*"      ]    }  ]}

    在这个payload中,我们构造了两个statement,第一个为按照业务预期的,控制了后缀以后的statement,第二个则是由我们注入后,可以直接控制用户CVM、与COS所有权限的statement。当然,如果云服务的API server后端是使用的是一些特性比较多的JSON解析方案,payload还可以有更多变化,例如

ext="]}]}//ext=","qcs::cvm:"],"effect""allow","action": ["","

    具体如何拓展可参考各家使用JSON解析方案的支持语法,以及各家自身的具体实现。

修复方案

    此类漏洞修复方案,一般分为三种,其中两种需要深入每一处业务使用,最后一种只可以整体去避开此类风险。

  1. 类似SQL注入、SLS注入一样,在每次调用API之前,对用户输入的内容进行过滤与校验。

  2. 使用官方给出的SDK去调用,官方SKD一般会通过JSONObject类的方案去生成请求参数,会很大程度上避免这个问题,但是如果API Server有比较离谱的实现,就是另外一回事了。

  3. 使用权限限制较多的子账户去下发STS身份,这样可以避免注入后获取List、FullAccess等敏感权限。


文章来源: https://govuln.com/news/url/ZNND
如有侵权请联系:admin#unsafe.sh