2018年4月5日漏洞公布: https://pivotal.io/security/cve-2018-1270
漏洞影响版本:
- Spring Framework 5.0 to 5.0.4
- Spring Framework 4.3 to 4.3.14
- Older unsupported versions are also affected
Spring框架中通过spring-messaging模块来实现STOMP(Simple Text-Orientated Messaging Protocol),STOMP是一种封装WebSocket的简单消息协议。攻击者可以通过建立WebSocket连接并发送一条消息造成远程代码执行。
使用github地址搭建 https://github.com/Venscor/CVE-2018-1270
然后修改app.js
制作的gif太垃圾了~~
可以看到成功执行了弹出计算器
我们在靶机中点击Connect后,在app.js中,有如下代码,会建立起Websocket连接:
其中header中可以指定了selector
,根据 Stomp Protocol Specification, Version 1.0,通过指定对应的selecttor,可以对订阅的信息进行过滤:
然后我们寻找漏洞代码位置。
在org/springframework/messaging/simp/broker/DefaultSubscriptionRegistry.java 对这个header参数进行了接受和处理:
在我框框下面有一句String selector = SimpMessageHeaderAccessor.getFirstNativeHeader(this.getSelectorHeaderName(), headers);
我们就去看看这个selector是什么,通过调试去查看
发现是T(java.lang.Runtime).getRuntime().exec('calc')也就是命令执行的语句
查看调用栈,发现web应用在handleMessageInternal对消息进行处理,在registerSubscription中注册用户信息,最后调用addSubscriptionInternal对header
参数进行处理,并对selector进行解析并将其保存到这次会话中。
而这一步就将表达式存放到expression中
而要执行这个表达式,我们就只需要去调用getValue()方法执行
可以看到context的值来自message,而message中就有我们的命令执行
然后我们跟到这一步就直接执行了
官方介绍:点击send向服务器发送任意消息,Spring在向用户分发消息的时候会调用filterSubscriptions
对信息进行过滤,就会执行命令expression.getValue(context, Boolean.class))
漏洞本质在获得了非法的context从而执行了SpEL表达式。官方修复是将context替换成messageEvalContext,而使用这个messageEvalContext
,就可以阻止java.lang.Runtime和java.lang.ProcessBuilder等类的解析,从而避免了执行命令。









