Weblogic:T3反序列化历史漏洞学习(一)
CVE-2015-4852
影响版本
影响版本:
- Oracle WebLogic Server 12.2.1.0
- Oracle WebLogic Server 12.1.3.0
- Oracle WebLogic Server 12.1.2.0
- Oracle WebLogic Server 10.3.6.0
漏洞复现
自带cc3.2.0,利用ysoserial生成CommonsCollections1的payload然后嵌入T3协议即可
1 |
|
测试环境:10.3.6.0 jdk7u21
成功创建文件
1 |
|
漏洞分析
weblogic.rjvm.InboundMsgAbbrev#readObject
读取T3协议传输过来的数据并进行反序列化
ServerChannelInputStream#resolveClass
直接调用父类的resolveClass,没有做任何防御
利用链就是CommonsCollections1的,简单梳理一下:
- weblogic.rjvm.InboundMsgAbbrev#readObject
- AnnotationInvocationHandler#readObject
- AnnotationInvocationHandler#invoke
- LazyMap#get
- 触发transform
漏洞修复
在resolveClass中引入了 ClassFilter.isBlackListed进行过滤
CVE-2016-0638
影响版本
影响版本:
- Oracle WebLogic Server 12.2.1.0
- Oracle WebLogic Server 12.1.3.0
- Oracle WebLogic Server 12.1.2.0
- Oracle WebLogic Server 10.3.6.0
漏洞复现
利用工具:https://github.com/5up3rc/weblogic_cmd
IDEA中配置参数
1 |
|
成功创建文件
1 |
|
漏洞分析
这个漏洞本质上是对CVE-2015-4852补丁,也就是resolveClass的绕过,既然通过黑名单来过滤,那么就找一个不在黑名单里的类就可以了。
weblogic.jms.common.StreamMessageImpl
这个类不再黑名单里,它的readExternal方法接收序列化数据作为参数,然后被对参数进行反序列化,然后再执行该参数反序列化后对应类的readObject。简单来说只要把之前CVE-2015-4852的payload装进weblogic.jms.common.StreamMessageImpl
,然后在执行weblogic.jms.common.StreamMessageImpl#readExternal
的触发readObject进行反序列化。
Weblogic反序列化过程中是会自动调用反序列化对象的readExternal方法的,参考一下反序列化时序图
理一下绕过resolveClass的原理:
- ServerChannelInputStream的resolveClass检验到是StreamMessageImpl,不在黑名单里面,通过。
- 然后在反序列化流程中会调用StreamMessageImpl的readExternal,readExternal内部又new了新的ObjectInputStream(以后简称ois)并从缓冲区读反序列化数据再次调用readObject,这里原生的ois就是原生的resolveClass方法没有过滤。
weblogic.jms.common.StreamMessageImpl#readExternal
可以看到这里对传入的var1再次进行了反序列化,注意这里对传入的反序列化字节流是有条件的:
- 判断读取的第一个字节是否为1
PayloadFactoryImpl.ceatePaload
方法中需要读取到var1(恶意类数据流)的长度.
Weblogic-cmd工具中重写了StreamMessageImpl.writeExternal
,这样就能生成符合要求的序列化数据
接下来简单看一下工具执行过程:
1.首先构造CC1的利用链,这个很熟悉了
CC1前半段,构建transformers数组
CC1后半段
注意最后红框里的部分,是把cc链的给封装到StreamMesssageImpl里
2.selectBypass调用了重写过的StreamMessageImpl,然后用Serializables.serial序列化,payload就是序列化过的CC链对象
StreamMessageImpl#writeExternal
这个方法被重写过,在writeObject序列化的时候就可以生成符合要求的序列化数据了
3.Serializables是把序列化的过程封装成了函数
漏洞修复
进一步对ObjectInputStream做了限制,这样不能绕过resolveClass了
CVE-2016-3510
影响版本
影响版本:
- Oracle WebLogic Server 12.2.1.0
- Oracle WebLogic Server 12.1.3.0
- Oracle WebLogic Server 12.1.2.0
- Oracle WebLogic Server 10.3.6.0
漏洞复现
还是使用weblogic-cmd
改一下TYPE
执行参数
1 |
|
成功创建文件
漏洞分析
原理跟CVE-2016-0638一样,找到不在黑名单的类然后再利用这个类反序列化。
这次的类是weblogic.corba.utils.MarshalledObject
在执行readResolve的时候会读取this.objBytes,然后赋值给新的ObjectinputStream再进行反序列化,这样又可以绕过resolveClass了,我们只需要把之前的payload放进this.objBytes就可以了
来看看weblogic-cmd的执行过程
来到serialData这里
selectBypass这里就跟刚才不一样了
可以看到是把CC链的对象封装进了MarshalledObject对象,然后return,执行Serializables.serial序列化对象
漏洞修复
总结
CVE-2016-0638和CVE-2016-3510本质上都是在绕过resolveClass黑名单,核心思想是找不在黑名单的类,在反序列化这个类的时候再反序列化CC链的对象,这是因为只要new了新的ObjectInputStream,并从缓冲区读反序列化数据再次调用readObject,这里新的ObjectInputStream用的是原生的resolveClass方法,绕过了过滤。
参考链接
https://xz.aliyun.com/t/8701#toc-5
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!