Skip to content

Latest commit

 

History

History
102 lines (78 loc) · 7.04 KB

某weblogic的T3反序列化0day分析.md

File metadata and controls

102 lines (78 loc) · 7.04 KB

某weblogic的T3反序列化0day分析

公司小兄弟发给我一个py样本,是今日捕获的某weblogic 0day,咱们来分析一下。

使用我的javaSerializationTools工具,来分析这个样本。结果如图

jdk7u21调试一下

当然,weblogic 12已经不支持在jdk版本低于1.8的jdk下运行。

我们可以很明显的看到,这个是反序列化gadgets中7u21的变种。唯一不同的是com.sun.org.apache.xalan.internal.xsltc.trax被用java.rmi.MarshalledObject代替。要了解这个为什么可以绕过weblogic黑名单,我们要了解一下weblogic 反序列化的黑名单究竟是什么

在java反序列化的过程中,会层层解析所需要的类,而weblogic就是控制解析反序列化的类,如果碰到可能触发恶意操作的类的名称,则直接打断反序列化流程。

而weblogic在处理jdk 7u21这条反序列化gadgets中,为了平衡拦截的效果与不影响业务,选择拦截com.sun.org.apache.xalan.internal.xsltc.trax这个类。而这个类恰恰也是绝大多数java反序列化中最为关键的一环。

所以,如果我们想要绕过weblogic针对7u21的反序列化拦截的黑名单,则需要找到com.sun.org.apache.xalan.internal.xsltc.trax的替代。

我在这里简单分析一下7u21中AnnotationInvocationHandlercom.sun.org.apache.xalan.internal.xsltc.trax的过程。因为在poc中只有这里改变了。

Templates类的newTransformer方法,会将属性_bytecodes,通过调用java的defineClass去生成一个类,并将其实例化,也就是调用静态代码块的代码。

AnnotationInvocationHandler,创建一个Templates的jdk动态代理,在hashmap出现哈希碰撞的时候,在hashmap中会调用AnnotationInvocationHandler的equal方法,equal方法会调用自身的equalImpl方法。最终会调用被代理对象的每个方法,去生成结果,相关代码如下

private Boolean equalsImpl(Object var1) {
       // 判断var1是否为AnnotationInvocationHandle,var1是templates,pass
        if (var1 == this) {
            return true;
          // 构造限制点,type属性限制了var1必须为this.type的类实例
        } else if (!this.type.isInstance(var1)) {
            return false;
        } else {
            //这里获取了当前成员的方法
            Method[] var2 = this.getMemberMethods();
            int var3 = var2.length;
            for(int var4 = 0; var4 < var3; ++var4) {
                Method var5 = var2[var4]; //遍历获取方法
                String var6 = var5.getName(); //获取方法名字
                Object var7 = this.memberValues.get(var6);//获取memberValues中的值
                Object var8 = null;
                // Proxy.isProxyClass(var1.getClass()
                // 判断varl是不是代理类,显然不是,pass
                AnnotationInvocationHandler var9 = this.asOneOfUs(var1);
                if (var9 != null) {
                    var8 = var9.memberValues.get(var6);
                } else {
                    try {
                        // 这里直接进行了方法的调用核心。
                        // var5是方法名,var1是可控的类
                        // var1.var5()
                        var8 = var5.invoke(var1);
                        private Method[] getMemberMethods() {
        if (this.memberMethods == null) {
            this.memberMethods = (Method[])AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
                public Method[] run() {
                    Method[] var1 = AnnotationInvocationHandler.this.type.getDeclaredMethods();
                    AccessibleObject.setAccessible(var1, true);
                    return var1;
                }
            });
        }
        return this.memberMethods;
    }

因为newTransformer方法恰好为Templates的第一个方法,如果是第二个方法的话,会导致执行第一个方法的时候出错而中断整个反序列化链。

而poc中,使用了java.rmi.MarshalledObject这个类,我们来分析一下。

java.rmi.MarshalledObject中,getMemberMethods方法返回的一个方法是getget代码如下

    public T get() throws IOException, ClassNotFoundException {
        if (objBytes == null)   // must have been a null object
            return null;
        ByteArrayInputStream bin = new ByteArrayInputStream(objBytes);
        // locBytes is null if no annotations
        ByteArrayInputStream lin =
            (locBytes == null ? null : new ByteArrayInputStream(locBytes));
        MarshalledObjectInputStream in =
            new MarshalledObjectInputStream(bin, lin);
        @SuppressWarnings("unchecked")
        T obj = (T) in.readObject();
        in.close();
        return obj;

一看就懂了,将objBytes属性作为反序列化的流,从中解析对象。我们知道,weblogic中,必须要调用FilteredObjectInputStream,才可以在反序列化过程中使用反序列化的黑名单。如果类中私自调用ObjectInputStream,则不会应用weblogic反序列化的黑名单。从而绕过

剩下的流程就与7u21的触发流程就一样了,只需要把objBytes随心所欲的替换为你喜欢的反序列化就可以,在这里无视weblogic黑名单。

当然,我拿到的样本,只是一个简单的回显代码,并没有太复杂的操作。

解决方案

  1. 这个反序列化漏洞并不只是影响jdk7u21,因为我们知道8u21是7u21的变种,理论上将jdk 8u21以下的jdk都受到此反序列化gadget的影响。
  2. 直接关闭iiop/t3这两个协议

poc的java生成代码,大家可能一看就明白了