漏洞复现 - Spring Data Rest 远程命令执行漏洞(CVE-2017-8046)
基础知识
今天和昨天的漏洞都跟SpEL有关。SpEL是Spring的表达式语言,支持在运行时查询和操作对象图,可以与基于XML和基于注解的Spring配置还有bean定义一起使用。由于它能够在运行时动态分配值,可节省大量Java代码。
用bean做实验:
调用结果:
漏洞原理
在REST API的Patch方法中(实现RFC6902),path的值被传入setValue
,导致执行了SpEL表达式,触发远程命令执行漏洞。
复现环境
在ubuntu 16.04虚拟机中用vulhub靶场提供的docker容器来复现
jdk版本1.7
影响版本
pivotal Spring Data REST < 2.5.12 2.6.7 3.0 RC3
pivotal Spring Boot < 2.0.0M4
pivotal Spring Data < Kay-RC3
复现过程
1. 进入vulhub目录:spring/CVE-2017-8046,启动docker容器
2.发送如下请求,利用SpEL表达式执行恶意代码:
3.查看结果,恶意代码执行成功
这里的SpEL用的就是基础知识里面提到的第二种使用方式,使用了java.lang.Runtime类的getRuntime().exec方法,可是这里为啥要转成byte[],不直接传字符串?
试了下直接调SpelExpression是可以直接传字符串的:
再发一次之前的PATCH请求,直接传字符串T(java.lang.Runtime).getRuntime().exec(new java.lang.String('touch /tmp/success')),没有成功,好吧,可能是源程序里面的参数类型是byte[]吧。。
看了一下Spring目录后面的几个目录,都是SpEL命令执行造成的,原理差不多,就不一一复现了。
本文仅用于技术学习和交流,严禁用于非法用途,否则产生的一切后果自行承担。