CVE-2018-1270源码分析与漏洞复现(spring-messaging 表达式注入)
漏洞概述
CVE-2018-1270 是 Spring 框架中的一个高危远程代码执行(RCE)漏洞,影响版本为 Spring Framework 5.0–5.0.4 和 4.3–4.3.14。攻击者通过构造包含恶意 SpEL(Spring Expression Language)表达式的 STOMP(Simple Text-Orientated Messaging Protocol)消息,利用 Spring Messaging 模块的路径解析缺陷,触发任意代码执行。该漏洞的 核心问题在于 SpEL 表达式解析时使用了高权限的上下文环境。
技术细节分析
1. 漏洞成因
- SpEL 表达式注入
Spring Messaging 在处理 STOMP 消息的selector
头部时,直接将用户输入的值作为 SpEL 表达式解析。攻击者可通过构造形如T(java.lang.Runtime).exec("calc")
的恶意表达式注入到selector
字段,触发远程代码执行。 - 高危上下文配置
漏洞版本的DefaultSubscriptionRegistry
类使用StandardEvaluationContext
解析表达式,该上下文允许完全访问 Java 类和方法(包括反射操作)。修复后改用SimpleEvaluationContext
,仅支持基础数据绑定,限制危险操作。
2. 漏洞触发流程
- 建立 WebSocket 连接:客户端通过 SockJS 与服务器建立 WebSocket 连接,并在
CONNECT
帧的headers
中注入恶意selector
字段。 - 订阅消息:发送
SUBSCRIBE
帧时,服务端将selector
值解析为 SpEL 表达式并存储到会话中。 - 触发执行:当客户端发送
SEND
帧时,服务端调用filterSubscriptions
方法对消息进行过滤,执行存储的表达式,触发代码执行。
2.源码分析
漏洞入口点:addSubscriptionInternal
方法
代码定位:org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#addSubscriptionInternal
源码:
1 |
|
触发条件:
当客户端通过 STOMP 协议向服务端发送 SUBSCRIBE
帧时,服务端处理订阅请求的逻辑会调用此方法。
关键逻辑:
- 从客户端请求头中提取
selector
字段的值。 - 将
selector
的值作为 SpEL 表达式进行解析:1
expression = this.expressionParser.parseExpression(selector);
- 将解析后的表达式与订阅信息(会话 ID、订阅 ID、目标地址)一起存储到内存中:
1
this.subscriptionRegistry.addSubscription(sessionId, subsId, destination, expression);
漏洞入口特性:
- 用户可控输入:
selector
字段完全由攻击者构造(如T(java.lang.Runtime).exec("calc")
)。 - 高危上下文:使用
StandardEvaluationContext
(默认支持反射、类加载等危险操作)。 - 无过滤机制:未对
selector
进行任何合法性校验或关键字过滤。
表达式执行点:filterSubscriptions
方法
代码定位:org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#filterSubscriptions
源码:
1 |
|
触发条件:
当服务端收到 SEND
帧(即向订阅目标地址发送消息)时,服务端会遍历所有订阅该地址的客户端,并根据其订阅时指定的 selector
表达式进行消息过滤。
关键逻辑:
- 从订阅信息中获取存储的 SpEL 表达式。
- 使用
StandardEvaluationContext
执行表达式:1
standardEvaluationContext = new StandardEvaluationContext(message);
漏洞触发特性:
- 表达式动态执行:存储的恶意表达式在此处被实际执行。
- 上下文绑定消息对象:
EvaluationContext
绑定了当前消息对象(message
),为攻击者提供更多利用可能。
方法关系与漏洞触发流程
1. 依赖关系:
时序依赖:
addSubscriptionInternal
是前置操作(订阅阶段),filterSubscriptions
是后续操作。
漏洞利用必须通过 先订阅后发送消息 的流程完成。数据依赖:
filterSubscriptions
中执行的表达式来源于addSubscriptionInternal
阶段存储的expression
对象。
2. 攻击链时序:
1 |
|
漏洞复现
环境搭建
使用 Vulhub 提供的 Docker 环境:
1 |
|
访问 http://target:8080
启动存在漏洞的 Spring STOMP 示例。
攻击步骤(反弹shell)
1.kali
攻击机开启监听
2.使用python
脚本发送恶意请求
1 |
|
靶场ip和监听地址和端口改为自己的
3.执行脚本并验证
- 反弹shell成功
修复建议
- 升级版本
- Spring Framework 5.0.x 用户升级至 5.0.5。
- Spring Framework 4.3.x 用户升级至 4.3.15 或更高版本。
- 输入过滤
对selector
头部进行正则校验,禁止包含T()
、.
等 SpEL 关键字。 - 禁用高风险功能
若非必要,关闭基于 STOMP 的消息路由功能。
总结
CVE-2018-1270 的根源在于 Spring Messaging 对用户输入的过度信任与高危上下文的结合。其修复方案通过限制表达式执行权限,有效降低了攻击面。
参考链接