记一次失败的Weblogic IIOP Gadget挖掘
字数 2022 2025-08-29 08:31:53
Weblogic IIOP Gadget挖掘与分析
前言
本文记录了一次针对Weblogic IIOP协议的反序列化漏洞挖掘过程,虽然最终因补丁问题未能成功利用,但整个思路和过程具有很高的学习价值。文章详细分析了从sink点发现到构造利用链的全过程,并探讨了T3与IIOP协议在反序列化时的差异。
关键知识点
1. Sink点分析
核心sink点:com.tangosol.coherence.transaction.internal.storage.KeyBackingMap#put
-
当
this.m_context是ReplicatedCache$BackingMapContext时,反序列化会进入:BackingMapContext#getValueFromInternalConvertergetConverterFromInternal
-
this.__m_ConverterFromInternal是transient的,反序列化时为空 -
逻辑会创建新的
converter并调用convert方法转换受控的oVal对象
Converter分析:
- 类型固定为
ReplicatedCache$ConverterFromInternal - 这是一个二阶反序列化类型的sink点
2. Gadget构造
2.1 利用链补全
- 使用常见source点自动化扫描
- 找到可利用的source点后,结合
BadAttributeValueExpException前半段完成利用链
2.2 Javaassit的妙用
问题:com.tangosol.coherence.component.util.daemon.queueProcessor.Service类实现了Serializable但官方不希望它被序列化
解决方案:
- 使用Javaassit强行修改
writeObject方法为$1.defaultWriteObject();
其他应用:
- 简化payload构造:可以审计代码后用Javaassit移除无用逻辑
- 示例:
KeyBackingMap构造方法中的context.getCacheService().getInfo().getServiceName()调用链可以简化
3. T3与IIOP协议差异
3.1 T3协议
- 成功利用未打补丁的Weblogic
- 最新补丁后失败原因:Oracle为T3添加了
ABBREV_CLASSES白名单
3.2 IIOP协议
失败原因分析:
-
反序列化时序问题:
- 即使设置了
__m_MessageClassMap,在逻辑执行时成员变量还未被赋值 - IIOP进入
readObjectOverride而非readObject0,导致depth始终为0
- 即使设置了
-
异常处理差异:
- IIOP反序列化
Component时registerValidation抛出异常 - 进入T3情况下不会进入的
validateObject
- IIOP反序列化
3.3 解决方案思路
"转换"思路:将IIOP"转换"为正常流后再利用
- 参考历史漏洞CVE-2016-3510的实现方式
4. 补丁分析
失败根本原因:
- 测试时少打了一个关键补丁
- 补丁前:
fromBinary可利用 - 补丁后:
this.setFilter默认为true,fromBinary加了黑名单
技术细节深入
1. 反序列化时序问题
在IIOP协议下,反序列化过程:
- 进入
readObjectOverride而非常规的readObject0 - 导致
depth计数器始终为0 - 触发
Component类的验证机制异常 - 进入非常规的
validateObject流程
2. T3白名单绕过可能性
虽然文章提到"空白太小写不下",但暗示T3白名单是可以绕过的,可能的思路包括:
- 利用白名单内的类进行代理或包装
- 通过反射或其他机制动态加载类
- 结合其他协议或功能进行间接利用
经验总结
- 补丁验证:漏洞测试时必须确保测试环境补丁状态与目标一致
- 协议差异:T3和IIOP在反序列化实现上有本质差异,不能简单等同
- 工具辅助:Javaassit等字节码操作工具在复杂gadget构造中非常有用
- 历史漏洞参考:CVE-2016-3510等历史漏洞的利用思路可以复用于新场景
后续研究方向
- 深入分析IIOP和T3协议在反序列化机制上的具体差异
- 探索T3白名单的绕过方法
- 研究Weblogic补丁机制,寻找可能的补丁绕过方式
- 探索其他可能的sink点和利用链
参考实现代码片段
// Javaassit修改Service类的示例代码
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("com.tangosol.coherence.component.util.daemon.queueProcessor.Service");
CtMethod m = cc.getDeclaredMethod("writeObject");
m.setBody("{$1.defaultWriteObject();}");
cc.toClass();
// 简化KeyBackingMap构造的示例思路
// 原复杂调用链:context.getCacheService().getInfo().getServiceName()
// 可替换为固定字符串或简化逻辑
结论
虽然这次漏洞挖掘因补丁问题未能最终成功,但整个过程展示了Weblogic反序列化漏洞挖掘的完整思路和方法论,对安全研究人员具有很高的参考价值。特别是对IIOP和T3协议差异的分析,为后续类似漏洞的挖掘提供了重要启示。