安全矩阵

 找回密码
 立即注册
搜索
查看: 1827|回复: 0

Spel的研究总结

[复制链接]

260

主题

275

帖子

1065

积分

金牌会员

Rank: 6Rank: 6

积分
1065
发表于 2022-6-29 09:10:21 | 显示全部楼层 |阅读模式
本帖最后由 luozhenni 于 2022-6-29 09:10 编辑

Spel的研究总结
原文链接:Spel的研究总结
KyoDream 衡阳信安 2022-06-29 00:00 发表于山东

前言
我看完CVE-2022-22963,便着手深入Spel表达式,希望能够深入研究Spel究竟出现在哪些地方,怎么挖掘新的漏洞。
挺感谢导师的帮助的,毕竟我实在太菜了,连反馈邮箱都不会写。

项目
考虑到这么多的组件如果一个个去尝试,显得太累了,我把自己实验时的代码都做成一个集合,放出来,方便有兴趣的师傅们一起讨论(项目:spel search)。先介绍各个组件使用Spel的情况。


spring-cloud-starter-netflix-turbine
application.properties
turbine.cluster-name-expression="T(Runtime).getRuntime().exec('calc')"无法配合actuator,需要/actuator/env、/actuator/restart
其中/actuator/restart时,会异常,导致服务崩溃


spring-cloud-stream
@StreamListener注解
@StreamListener(value = Sink.INPUT, condition = "T(Runtime).getRuntime().exec('calc')")注解是一个不可控的点


Spring-cloud-kubernetes
application.properties
spring.cloud.kubernetes.discovery.filter=T(Runtime).getRuntime().exec('calc')可配合/actuator/env,但是无法命令执行,原因如下
执行Spel时需要执行上下文,SimpleEvaluationContext并不支持T(Runtime)
因此如果执行会报以下问题


Spring-data-jpa
@Query
@Query(value="select * from user where id = ?#{T(Runtime).getRuntime().exec('calc')}", nativeQuery=true)可以getshell,但是可以忽略危害性。


Spel场景总结
基本上可以确定的是,Spel的存在可能基本是存在于配置类与注解中的。我在其他与Spring cloud相关的组件也存在一些Spel解析的地方但都是在配置类或者注解中,并且还是硬编码,这就没有放出来的意义了。


CVE-2022-22980
在我不断的挖掘过程中,终于找到了一个算是有问题的Spel表达式注入了。Spring-data-mongodb。说实话,这个漏洞挖掘起来应该没个运气都找不到。本人开始也不觉得是个漏洞,但是综合考虑了@Query和@Aggregation设计的目的,以及spring data jpa也支持这个,但是两者解析却存在十分大的差距,便觉得这个问题从正常角度确实不太算一个合法的漏洞,只能算是一个危险的API。但是从设计的角度,我觉得它是属于安全BUG。


spring data jpa与spring data mongodb
其实拿spring data jpa来说,jpa也同样支持@Query中做spel。但是如果你尝试用类似于
@Query(value="?#{?0}", nativeQuery=true)

jpa的Spel解析
spring data jpa也支持spel,如下
@Query(select * from user where name= ?#{?1},nativeQuery=true)public User getUserByName(String name);spring data jpa有两处会解析spel,第一次在启动的时候会触发,第二处在收到请求时触发。
启动解析Spel
先会经过if(!containsExpression(query))判断,这里的比较属于硬编码比较
即比较查询语句是否存在
#{#entityName}这里的#entityName会被解析成Entity Pojo实体的类名称。所以无法控制。
接收请求解析Spel
当HTTP发起请求查询数据库,会走到org.springframework.data.jpa.repository.query.QueryParameterSetterFactory中的create方法
通过debug分析parse.parseExpression后,最后走到 org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression
最终经过eatExpression()时抛出异常,因为eatExpression直接分析 ?0 是否spel表达式,这里并没有 将 ?0 去引用来解析spel。也就是如果一定要spel命令执行,SQL必须是以下内容
@Query("select * from user where name = #{T(Runtime.getRuntime().exec('command'))}")

Mongodb的解析
与上相似,Mongodb同样在@Query也支持Spel。初次之外,@Aggregation也支持Spel解析
@Query(":#{?0}")User getDataInfo(String info);与JPA相似,能控的参数,都在请求后解析Spel,启动的Expression完全不可控,所以不考虑启动的问题。以下是Mongodb解析Expression的重要位置
(org.springframework.data.mongodb.util.json.ParameterBindingJsonReader)。


其中PARAMETER_BINDING_PATTERN.matcher(expression)会检查表达式中是否为
\?(\d+)比如?0、?1、?2等等

expression.replace(inSpelMatcher.group(),getBindableValueForIndex(index).toString());会直接将占位符替换成请求查询的内容。接着evaluateExpression函数直接对Spel表达式解析。


对比小结
可以看到,例如Spring data系列的其他数据库依赖,基本逻辑是与jpa相关的,但是唯独mongodb存在这个问题(可能mongodb数据库有他独特的地方所以导致这个可能),但是无论如何,我测试多次,也只有mongodb出现在使用spel时,?0这样的占位符会被提前解析成请求的数据。


有趣的问题
在我正准备全面的测试究竟哪些版本会出问题的时,我以为3.4.0以下的都存在这个问题,可是经过测试,似乎只有最新版的3.4.0是存在的。这让我感觉疑惑。
答案:一行代码的血泪

代码可能模糊,所以还是给出链接3.3.x(点击跳转)与3.4.x(点击跳转)
在解析@Query中的SQL语句是,会经过org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec中的decode方法。其中reader.readStartDocument()会尝试解析,确定是否正确,或异常的SQL。如果使用?:#{}这样的表达式,其实这里会报错的。在报错之后就是抛异常。我们都知道Java在处理异常时都是向上抛异常的,所以这里的异常会被decode中的try处理
由于返回的是一个Object对象不是Map,所以在catch中的处理就正常的结束了,这里catch竟然吃掉了异常!所以导致异常的SQL语句最终变成“正常的SQL语句”。而3.3.x乃至低版本,reader.readStartDocument();都在try之外,导致异常最终会被程序捕获,导致后面的spel的解析走不了。


攻防下的思路
上文都提到了Spel的一些挖掘情况,现在聊一些基于上面的研究对攻防的意义。
我也找了不少的配置可以解析Spel的,为什么这么做,因为我考虑到另一个组件的存在——actuator。
说实话,虽然actuator未授权的情况基本很少,但是存在这个actuator/env未授权时,很多情况下还是停留在信息泄露,LandGrey的一个项目SpringBootVulExploit中已经详细描述了大部分的场景。我也在思考Spel在配置中的情况下,是否可以起到一定的作用,以至于放大actuator的危害,至少是个RCE吧。

来源:先知(https://xz.aliyun.com/t/11478#toc-0)

注:如有绘画请联系删除



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-30 00:36 , Processed in 0.012556 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表