执行成功。
在执行exp的时候,如果开启debug去查看其实不难发现,发送t3的报文头信息以后会在返回包里面回显weblogic的版本号。
可以看到,后面通过正则提取了返回包的数据,拿到该版本号信息。
漏洞分析T3协议接收过来的数据会在weblogic.rjvm.InboundMsgAbbrev#readObject这里进行反序列化操作。
来直接定位到该位置,可以看到断点的位置,里面调用了InboundMsgAbbrev.ServerChannelInputStream#readObject方法,查看一下
这里调用创建一个内部类,并且调用readObject方法,还需要查看一下 ServerChannelInputStream实现。
在这里其实就可以看到ServerChannelInputStream是一个内部类,该类继承ObjectInputStream类,而在这里对resolveClass进行了重写。
但是在此处看到,其实调用的还是父类的resolveClass方法。在resolveClass方法中也没做任何的校验,导致的漏洞产生。
后面来讲讲如何防御到该漏洞。
再谈resolveClassresolveClass方法的作用是将类的序列化描述符加工成该类的Class对象。
前面分析readObject方法的时候,我们得知了shiro就是重写了resolveClass方法导致很多利用链无法使用,但是shiro在编写的时候,并不是为了防御反序列化漏洞才去重写的resolveClass,但是就是这么一个无意间的举动,导致了防御住了大部分攻击。
而在后面的weblogic补丁当中,也会基于这个resolveClass去做反序列化漏洞的防御。
贴上一张廖师傅的博客的反序列化攻击时序图:
那么这里需要思考到一个问题,为什么要在resolveClass进行一个拦截,而不是其他位置?
resolveClass方法的作用是从类序列化描述符获取类的Class对象,如果在resolveClass中增加一个检查,检查一下该类的序列化描述符中记录的类名是否在黑名单上,如果在黑名单上,直接抛出错误,不允许获取恶意的类的Class对象。这样以来,恶意类连生成Class对象的机会都没有。
来看到这个方法,在我的readObject分析文章里面贴出来一张图,readObject的内部使用Class.forName来从类序列化获取到对应类的一个Class的对象。
那么如果这里加入一个过滤,那么这里如果直接抛出异常的话,在readNonProxyDesc调用完resolveClass方法后,后面的一系列操作都无法完成。
参考文章 https://blog.knownsec.com/2020/11/weblogic12c-t3-%e5%8d%8f%e8%ae%ae%e5%ae%89%e5%85%a8%e6%bc%ab%e8%b0%88/ %E5%8E%86%E5%8F%B2T3%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%8F%8A%E8%A1%A5%E4%B8%81%E6%A2%B3%E7%90%86/ https://xz.aliyun.com/t/8443 0x04 修复方案