flowpaper java_Spring Web Flow 远程代码执行漏洞分析(CVE-2017-4971)

Spring 严重的漏洞历来都不算多,之前比较严重的那个问题是 Spring 的 JavaBean 的自动绑定功能,导致可以控制 class ,从而导致可以利用某些特性执行任意代码,但是那个漏洞比较鸡肋,不是每次都能触发。

由于 Spring 的框架越来越多,而且后面引入了 SpringEl 作为默认的表达式解析方式,所以一旦引入了类似于 OGNL 的表达式,很可能会带来一些安全问题,本次漏洞就是由于 Spring Web Flow 的数据绑定问题带来的表达式注入,从而导致任意代码执行。

一. 漏洞简介

这个漏洞在今年6月初刚被提交(传送门), 官方并没有详细的信息,通过官方描述和补丁的对比,我们可以大致推断应该是 Spring Web Flow 在 Model 的数据绑定上面,由于没有明确指定相关 model 的具体属性导致从表单可以提交恶意的表达式从而被执行,导致任意代码执行的漏洞,这个漏洞利用除了版本的限制之外还有两个前置条件,这两个前置条件中有一个是默认配置,另外一个就是编码规范了,漏洞能不能利用成功主要就取决于后面的条件。

整体来说这个漏洞危害应该还是有一些的,如果满足2个前置条件,那么直接 RCE 是没什么问题的。在分析这个漏洞之前需要一些 Spring Web flow 的基础知识,给大家推荐这篇文章。

二. 漏洞分析

一开始我也不清楚这个漏洞到底是怎么触发,对于这个漏洞的理解,最好去看下 Spring Web Flow 的教程,搞明白里面的 view-state 是啥,这里不过多对 Spring Web Flow 的基础知识过多解释,那么我们直接看补丁,如下图:

2c7c63fcb44ce0cfed0d5a90f6492e11.png

我们发现这里对 addEmptyValueMapping(DefaultMapper mapper, String field, Object model) 这个方法里面表达式解析的实现类进行了替换,直接使用了 BeanWrapperExpressionParser 来解析,关于这个类我们后面再详细说,那么知道触发漏洞的函数后,我们就可以用 Eclipse 或者 Spring Tools 来跟踪下函数调用栈,具体如下:

bce71cde6c02f8d35858d3cacb496118.png

通过调用关系我们可以发现一共有一下两个函数调用了 addEmptyValueMapping 方法

addDefaultMappings(DefaultMapper mapper, SetparameterNames, Object model)

addModelBindings(DefaultMapper mapper, SetparameterNames, Object model)

这里通过调用关系我们可以大概的搞明白 Spring Web Flow 的执行顺序和流程,由 flowcontroller 决定将请求交给那个 handler 去执行具体的流程,这里我们需要知道当用户请求有视图状态处理时,会决定当前事件下一个执行的流程,同时对于配置文件中我们配置的 view-state 元素,如果我们指定了数据的 model ,那么它会自动进行数据绑定,xml 结构如下(这里以官方的example中的 book 项目为例子)

5e97f828c931afdf7e24b5fbee44ed7b.png

言归正传,本次漏洞出现的原因就是在 view-state 节点中数据绑定上,我们继续跟踪

addEmptyValueMapping 方法的调用过程,这里通过 eclipse 我们可以发现 bind 方法间接的调用了

addEmptyValueMapping 函数,

73a9522fc6862d6fc12aae3f5d83e47a.png

到这里我们知道了addEmptyValueMapping 函数存在表达式执行的点,我们现在来详细看下这个

addEmptyValueMapping 函数,如下图

ab54a781dd4dab924b22b8f1847acc64.png

这里我们可以看见,只有控制了 field 参数才能出发漏洞,所以我们重点是找到有没有点我们可以控制从而控制 field 参数来进行任意代码执行,这里明确目标后,我们回过头来看 addDefaultMappings 和

addModelBindings 这两个函数,既然这两个函数都调用了存在缺陷的函数,那么我们看看这两个函数的区别是什么,而且那个函数能能能控制 field 参数,两个函数的区别如下:

bb4155eda2bc3421bc47d8e667af026e.png

9d4fe08ec89a033ee023c1219c0f5f79.png

这里比较明显的区别就是 addModelBindings 函数中 for (Binding binding : binderConfiguration.getBindings()) 存在这样一个循环,而且就是这个循环的控制决定了 field 参数的值,经过进一步分析,这里控制 field 的参数的决定性因素就是 binderConfiguration 这个变量所控制的值,这里经过源码的跟踪我们可以发现,binderConfiguration 函数的值就是 webflow-*.xml 中 view-state 中 binder 节点的配置,所以这个函数的值来源于配置文件,所以这个函数我们无法控制,从而无法触发漏洞,所以我们重点来看看 addDefaultMappings 这个函数,我们发现 addDefaultMappings 中我们可以控制 field 参数,所以我们重点来看看如何去触发这个函数。

现在我们基本上可以确定了 addDefaultMappings 函数是我们触发漏洞的关键点,那么如上图所示,bing 函数中调用了这两个函数,那么我们可以看出只有当 binderConfiguration 为空的时候才能触发我们的漏洞,那么我们刚才也说了 binderConfiguration 这个值是由配置文件中是否有 binder 节点来控制的(这里需要注意的是程序执行到 bind 方法的前置条件是 view-state 节点中是否配置了 model 属性,即绑定的

javabean 对象是什么),而且 addDefaultMappings 函数中 parameterNames 参数就是我们从表单中传递的值,所以到这里漏洞的触发流程和触发条件基本上清楚了,触发条件如下:

在 webflow 配置文件中 view-state 节点中指定了 model 属性,并且没有指定绑定的参数,即 view-state 中没有配置 binder 节点

而且 MvcViewFactoryCreator 类中 useSpringBeanBinding 默认值(false)未修改

这里为什么一定要 useSpringBeanBinding 的值为 false ,我们来看一下 addEmptyValueMapping 函数,这里的 expressionParser 变量的声明类是 ExpressionParser 接口,那么决定最后 expressionParser.parseExpression(field, parserContext) 这个函数来执行任意表达式是这个变量的赋值,那么在 spring web flow 中这个 expressionParser 的默认值就是 WebFlowELExpressionParser 的实例,这个类表达式默认的解析是有 spel 来执行的,具体可以去跟踪函数,那么在org.springframework.webflow.mvc.builder.MvcViewFactoryCreator.createViewFactory(Expression, ExpressionParser, ConversionService, BinderConfiguration, Validator, ValidationHintResolver)这个类如下图:

0d3a0f373314c1d4a9c6ed6d1f90cde2.png

我们可以看见如果 useSpringBeanBinding 这个属性为 false 那么久使用默认的解析类,如果这个值为 true 就由 BeanWrapperExpressionParser 这个类来解析,这个类的 parseExpression 函数我们来看看

cfe01c25cbcb773fe3983e2e964d7805.png

首先决定了能不能执行的第一个控制变量是 allowDelimitedEvalExpressions ,这个默认值是 false ,所以这里是执行不了表达式的。

所以这里必须满足 useSpringBeanBinding 这个默认值不被改变。

这里需要注意一点,我们构造的恶意参数名称必须以_开头,具体原因看 addDefaultMappings 函数中的

fieldMarkerPrefix 变量。

OK,到这里漏洞的触发条件和流程已经很明确了,下面说说具体怎么利用。

三. 漏洞利用

这次漏洞测试是以 Spring Web flow 官方的 Example 中的例子来进行,因为这里的某个 flow 满足我们的条件,具体配置如下:

488c9b9b393de17f737d649b7bc395ef.png

项目地址,这里在测试时需要注意修改

org.springframework.webflow.samples.booking.config.WebFlowConfig.mvcViewFactoryCreator()

方法中的改成 factoryCreator.setUseSpringBeanBinding(false); 因为这个工程修改了

useSpringBeanBinding 的默认值。

这里直接到订阅图书,上图说了在 reviewBooking flow 中就能出发,如下图:

12407ebc7347468cd5dfa569e747e094.png

点击 confirm ,然后抓包添加恶意参数变量,如下图:

333b8f3d144ed16fbc8f1e6f5f9a66b1.png

OK,大功告成。

参考资料

帮发小广告:

为了更好的和广大安全爱好者交流,我们搭建了个交流社区,社区主要聚焦在威胁发现以及安全数据分析等领域,我们希望有更多的朋友能加入,能一起分析知识、共同进步。社区地址:https://threathunter.org/,

感谢大家支持。

本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/322/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
针对PHP远程代码执行漏洞(CVE-2022-31625),以下是一些修复方法: 1. 更新到最新版本:确保你的PHP版本是最新的,因为漏洞修复通常会包含在更新中。请访问PHP官方网站或者使用包管理工具来获取最新版本。 2. 禁用危险函数:在php.ini配置文件中,禁用危险函数可以帮助防止远程代码执行。可以使用disable_functions指令来禁用一些敏感函数,如eval()、exec()、system()等。 3. 安全配置:检查你的PHP配置文件,确保安全设置已经启用。例如,禁用动态加载扩展、限制文件上传目录和大小、禁用远程文件包含等。 4. 输入验证和过滤:在你的应用程序中对用户输入进行严格的验证和过滤,以防止恶意代码注入。 5. 使用安全框架或库:使用安全框架或库来帮助防止远程代码执行漏洞。这些框架通常提供安全的默认配置和内置的安全功能。 6. 定期更新和监控:定期检查并更新你的应用程序和相关组件,以确保及时修复已知漏洞。同时,监控应用程序的日志和网络流量,以便及时发现异常行为。 请注意,这些方法只是一些常用的修复措施,具体的修复方法可能会因系统配置和应用程序的特定情况而有所不同。建议在修复漏洞之前,先进行充分的测试和备份。此外,如果你不确定如何处理或无法解决该漏洞,请咨询安全专家或PHP开发人员的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值