CVE-2016-1000027: Spring Framework HttpInvoker 反序列化漏洞分析
0x00 漏洞背景与详情
- 漏洞名称:Spring Framework HttpInvoker 远程代码执行漏洞
- CVE 编号:CVE-2016-1000027
- 影响组件:Spring Framework (
spring-web) - 影响版本:
- Spring Framework < 4.3.6
- Spring Framework 5.0.0.M1 - 5.0.0.M5
- 漏洞类型:Java 反序列化漏洞
- 危险等级:高危 (CVSS 9.8)
CVE-2016-1000027 是 Spring Framework 中一个经典的反序列化漏洞。该漏洞存在于 Spring 的 HTTP 远程调用(HTTP Invoker)机制中,攻击者可以通过向受影响的端点发送特制的序列化对象,在目标服务器上实现任意代码执行。
0x01 漏洞原理分析
Spring HttpInvoker 是一种基于 HTTP 协议的远程调用机制,它使用 Java 原生序列化来传输 RemoteInvocation 和 RemoteInvocationResult 对象。
漏洞的核心在于 org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter 类。当该类被配置为导出某个服务时,它会处理 HTTP POST 请求。在处理过程中,它会调用 readRemoteInvocation 方法从请求的输入流中读取数据:
由于该方法直接使用了 Java 原生的 ObjectInputStream.readObject(),且在反序列化之前没有对类进行任何白名单过滤或安全校验,攻击者可以构造包含恶意 Gadget Chain(如 Apache Commons Collections, Spring Beans 等)的序列化对象。
当 readObject() 被执行时,如果目标应用的 Classpath 中存在易受攻击的库,恶意代码就会被触发,导致远程代码执行。
0x02 漏洞 POC 与高级利用姿势
POC 构造思路
利用 ysoserial 工具生成一个针对 CommonsCollections1 利用链的 Payload,并将其作为二进制数据发送给 HttpInvoker 接口。
生成 Payload:
发送请求: 假设受影响的接口地址为
http://target.com/remoting/OrderService。
进阶利用姿势
1. 内存马(Memshell)注入
由于反序列化漏洞可以执行任意 Java 代码,在文件监控严格的环境中,注入内存马是实现持久化控制的最佳选择。在 Spring 环境下,常见的注入姿势包括:
- Controller 型:通过反射向
RequestMappingHandlerMapping动态注册一个新的Controller接口。 - Interceptor 型:向 Spring 的拦截器链(
Interceptor)中插入恶意逻辑。 - 利用思路:通过
RequestContextHolder.getRequestAttributes()获取当前请求的HttpServletRequest,进而获取WebApplicationContext,动态加载并注册恶意类。
2. 回显技术(Echo Technique)
在不出网环境或需要获取命令执行结果时,常用的 Spring 回显方案包括:
- RequestContextHolder 方案:获取当前的
HttpServletResponse对象,将执行结果直接写入 Response Body。 - 异常回显(Exception-based Echo):将命令执行结果作为异常信息抛出,结果会显示在 500 错误页面中。
真实利用案例
在某大型企业内部,OA 系统使用了 Spring HttpInvoker 进行各模块间的业务调用。由于接口缺乏鉴权且直接暴露在内网中,渗透测试人员在获取某台内网机器权限后,通过目录扫描发现了该 RPC 接口。利用 ysoserial 结合内网环境中的旧版本 commons-collections 库,并在无法出网的情况下采用了 异常回显技术,成功在 OA 服务器上执行了命令并获取了核心业务数据库配置。
0x03 应急排查与日志痕迹分析建议
1. 漏洞环境排查
- 依赖检查:检查项目的
pom.xml或build.gradle,查看spring-web的版本是否在受影响范围内。 - 代码审计:全局搜索项目中是否配置了
HttpInvokerServiceExporter。- XML 配置:
<bean class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> - Java 配置:
new HttpInvokerServiceExporter()
- XML 配置:
- 指纹识别:使用工具扫描 Web 路径,寻找可能存在的 RPC 端点(常见路径如
/remoting/*,*.remote等)。
2. 日志痕迹分析
- Web 访问日志:
- 特征路径:关注所有指向
HttpInvoker映射路径的 HTTP POST 请求。 - 异常响应:反序列化攻击如果由于环境不支持失败(例如类转换异常),日志中通常会记录大量的 500 Internal Server Error。
- 特征路径:关注所有指向
- 流量特征分析:
- 魔数识别:Java 序列化流量的头部包含固定的魔数
AC ED 00 05(十六进制)。可以在 IDS/IPS 或 WAF 日志中检索请求体起始位置包含此特征的记录。
- 魔数识别:Java 序列化流量的头部包含固定的魔数
- 应用堆栈日志:
- 在
catalina.out或业务日志中,寻找java.io.ObjectInputStream相关的异常堆栈。 - 重点关注类似
java.lang.ClassCastException: org.apache.commons.collections.map.LazyMap cannot be cast to org.springframework.remoting.support.RemoteInvocation的报错,这通常是反序列化攻击尝试的直接证据。
- 在
0x04 修复与缓解建议
- 升级组件:升级 Spring Framework 到 4.3.6+ 或 5.x 稳定版(需要注意的是,Spring 官方在较新版本中已完全废弃了该功能)。
- 禁用不必要的功能:如果业务不需要基于 HTTP 的 Java 序列化远程调用,应直接移除
HttpInvokerServiceExporter的相关配置。 - 安全反序列化:如果必须使用,应自定义
HttpInvokerServiceExporter,重写createObjectInputStream方法,使用带有白名单严格校验的ObjectInputStream。 - 网络隔离:此类 RPC 接口严禁直接暴露在互联网上,应通过防火墙或安全组仅允许内网受信 IP 访问。