京东消防猿的Spring 框架的反序列化漏洞的分析与实践

分析

介绍

漏洞介绍

国外的研究人员zero thoughts发现了一个Spring框架的反序列化远程代码执行漏洞。

spring-tx.jar包中的org.springframework.transaction.jta.JtaTransactionManager类存在JNDI反序列化问题。只要创建一个JtaTransactionManager 对象让userTransactionName指向我们注册的RMI链接(如rmi://x.x.x.x:1099/Object)然后将对象发送到有漏洞的服务器,即可执行远程命令。具体细节可以分析漏洞作者的POC代码。

漏洞影响

受影响漏洞服务器主要需要满足如下条件:

  1. CLASSPATH 中包含了 spring-tx.jar,spring-commons.jar,javax.transaction-api.jar

  2. 存在反序列化接口如RMI, JMS, IIOP等

    出现漏洞的关键jar包 spring-tx.jar,并不是spring最基本的包,默认并不使用,所以并不是所有使用了spring框架的应用都受影响,需要具体检查是否包含了spring-tx.jar包。

POC简要复现

环境描述:

Java环境——这里使用的是JDK1.7版本

Maven环境——见下面的maven包 apache-maven-3.3.9-bin.zip

Spring漏洞利用POC——spring-jndi-master.zip

环境搭建:

  1. Java环境安装,略

  2. Maven安装

    直接解压apache-maven-3.3.9-bin.zip ,添加环境变量,然后用mvn –v测试是否安装成功

    如我的maven路径:C:javaapache-maven-3.3.9

    添加环境变量:

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

Mvn –v测试

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

服务器搭建:

Poc里面有两个文件夹server和client

Server用于搭建包含spring的服务器环境,client用于构建反序列化对象并发送给server

服务器搭建命令如下

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

首先进入server目录

然后用mvn install安装spring环境

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

Mvn就是开始安装的maven,server目录下有pom.xml文件。 Mvn install会根据里面的内容来下载安装spring等组件。 最后会将jar包放到target中。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

java -cp “target/*” ExploitableServer 9999命令在9999端口起到有漏洞的服务器程序。

ExploitableServer.java比较简单,创建socket等待连接,读取对象。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

这样便开启了一个连接

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

客户端攻击对象构建:

命令与上面相似:

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

进入目录,安装spring组件,调用代码向服务器发送指令。

Mvn install,客户端也需要安装spring的组件,来使得客户端的java代码能够构造spring对象。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

java -cp “target/” ExploitClient 127.0.0.1 9999 127.0.0.1

“target/ 指定spring路径

ExploitClient 为客户端的main程序

127.0.0.1 9999 127.0.0.1三个参数分别对应为

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

客户端包含三个文件

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

ExploitClient是主程序,包含序列化的过程,一些主要出现漏洞的类,以及数据的发送。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

HttpFileHandler 主要是构建字节流

ExportObject 是功能代码,构建自己的java代码,服务器有权限就能执行。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

执行结果:

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

自检与修复:

由于主要出现漏洞的地方在于Spring-tx.jar包的JtaTransactionManager类中。 可以检测项目中是否有使用spring-tx.jar包。如果有使用可以对JtaTransactionManager类进行重写。同时有防火墙的用户可以先对数据包中的JtaTransactionManager数据进行过滤,直到源码修复。

POC网络传输数据如下,可以先对使用了JtaTransactionManager的报文进行拦截。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

实践

最近在学习反序列化之类漏洞之类的东西,之前也是看别人分析,一直没有实践,这次找到16年的一个漏洞,准备分析调试一下。漏洞环境 https://github.com/zerothoughts/spring-jndi针对上面的技术我特意整理了一下,有很多技术不是靠几句话能讲清楚,所以干脆找朋友录制了一些视频,很多问题其实答案很简单,但是背后的思考和逻辑不简单,要做到知其然还要知其所以然。如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java进阶群:591240817,群里有大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家

漏洞描述

没搜到编号,反正重点是在于学习这个漏洞。首先先把服务端跑起来,服务端代码很简单,是一个serversocket的,监听9999端口,并且抑制等待客户端socket链接过来。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

客户端代码

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

客户端流程如下:

1.客户端代码先监听8088端口,开启一个文件下载服务。其中该地址映射的就是ExportObject.class。 2.将文件地址http://127.0.0.1:8080/ExportObject.class映射到rmi服务上面

3.将ExportObject用JtaTransactionManager封装一下

4.客户端连接服务端9999,然后发送包装后的object

5.服务端接收到object,然后调用readObject 最终会弹出计算器 在分析之前有必要介绍下RMI,Remote Method Invoke 远程方法调用,用于在远端服务器上提供远程对象给客户端?什么意思,就是服务端开启这个服务,然后客户端访问服务端着个接口就可以直接拿到服务器上的对象,它的底层应该就是socket通信,然后传递一个object的。关于它的用法,

使用起来也很简单,这个被传递的对象必须继承IService,然后服务端用rebind函数将这个对象和路径映射起来就可以了,服务端关键代码如下:

IService service02 = new ServiceImpl("service02");//初始化命名空间Context namingContext = new InitialContext();//将名称绑定到对象,即向命名空间注册已经实例化的远程服务对象namingContext.rebind("rmi://localhost/service02", service02);

客户端怎么调用,也很简单

String url = "rmi://localhost/";Context namingContext = new InitialContext(); // 检索指定的对象。 即找到服务器端相对应的服务对象存根 IService service02 = (IService) namingContext.lookup(url + "service02");

只需要调用lookup将该路径传递进去就可以获得IService类的对象了,又做了这个基础后面理解起来就很简单了。

Spring框架中的JtaTransactionManager出了问题,JtaTransactionManager实现了Serializable,并重写了readObject函数,所以当服务端运行到readObject的时候

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

,就会调用JtaTransactionManager类的readObject函数,跟进这个函数

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {ois.defaultReadObject(); this.jndiTemplate = new JndiTemplate(); this.initUserTransactionAndTransactionManager(); this.initTransactionSynchronizationRegistry();}

其中initUserTransactionAndTransactionManager()函数的作用看意思应该是初始化一些参数,进入这个函数

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

继续跟进lookupUserTransaction这个函数

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

最终执行了lookup,如果看了前面的话应该还记得需要跟一个rmi路径,这个路径其实在ExploitClient中就设置了

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

所以最终被带入到lookup里面了,那么会怎样?由于路径是rmi://127.0.0.1:1099/Object ,那怎么样?new 一个Object呗,由于前面用bind将ExportObject和Object绑定了,那么就是执行ExportObject的构造函数咯,构造函数里面就是弹出一个计算器,至此,整个逻辑调通。

京东消防猿的Spring 框架的反序列化漏洞的分析与实践

流程总结

用一张图来总结整个流程比较好,这里借鉴了Seebug上某片文章的图

京东消防猿的Spring 框架的反序列化漏洞的分析与实践京东消防猿的Spring 框架的反序列化漏洞的分析与实践可以关注我的微信公众号一起讨论交流