Skip to content

Latest commit

 

History

History
51 lines (40 loc) · 4.27 KB

File metadata and controls

51 lines (40 loc) · 4.27 KB

将Java反序列化数据转为XMLDecoder格式(XMLDecoder)

  • 类别:common 别名:— 优先级:22
  • 作者:4ra1n
  • 依赖:无第三方 Maven 依赖(目标端需存在 oracle.toplink.internal.sessions.UnitOfWorkChangeSet 类,典型为 WebLogic 环境)

作用

这是一个格式转换(sink 前置封装)构件:把链中内层产出的「Java 原生序列化字节数组」翻译成一段 WebLogic Async SOAP + XMLDecoder 报文,用于打 XMLDecoder 反序列化场景(如 WebLogic CVE-2019-2725)。它本身不触发代码执行,而是把已经准备好的 Java 序列化 payload 嵌入到 XMLDecoder 能解析的 XML 里,借 UnitOfWorkChangeSet 在服务端再次触发 Java 原生反序列化。

链接标签

  • 入口 tagsOther —— 自由入口标签,不挑上一环,通常作为整条链最外层的输出封装。
  • 衔接 nextTagsJavaNativeDeserializePayloadCustomJavaDeserialize —— 之后必须接一个「能产出 Java 原生序列化字节」的下游(内层链),因为本构件的输入是 byte[]
  • excludes:无。

源码剖析

private static String template = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n ...
 <class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void>%s</void></class>
 ... </soapenv:Envelope>";

public Object getObject(Object object) throws Exception {
 byte[] serialized = (byte[])object;
 return String.format(template, XMLDecoderUtil.generateClassBytesXml(serialized));
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
 return this.getObject(chain.doCreate(context));
}
  • invokechain.doCreate(context) 取内层对象。由 nextTags 约束,内层链最终产出的是一段 Java 原生序列化后的字节数组byte[]),而不是普通对象——这正是 getObject 第一行 (byte[])object 强制转型所要求的。
  • getObject 把这段字节交给 XMLDecoderUtil.generateClassBytesXml(serialized),将二进制序列化流转成 XMLDecoder 可识别的 <byte>/<array> 逐字节 XML 表示,再用 String.format 填入模板的 %s 占位。
  • 模板内 <class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void>...</void></class>:XMLDecoder 会实例化 UnitOfWorkChangeSet,并把这段字节数组喂给它的构造器 —— 该类构造器内部对字节数组执行 ObjectInputStream 反序列化,从而在服务端把嵌入的 Java 序列化 payload「二次」还原并触发。
  • 因此本构件是「Java 原生反序列化 payload → XMLDecoder XML」的桥:外层是 XMLDecoder/XML 文本入口,内层复用任意 Java 原生反序列化 gadget(如 CommonsCollections/CB 系列打成的字节)。

说明:XMLDecoderUtil.generateClassBytesXml 为工具类,未带 @GadgetAnnotation,不在本文档 gadget 目录内;其职责即把 byte[] 序列化流编码为 XMLDecoder 的字节数组 XML 片段。

参数(@Param)

本类无 @Param,无用户可配字段;一切输入来自内层链产出的字节数组。

适用版本与原理要点

  • 面向 XMLDecoder 反序列化入口,典型目标为 WebLogic(Async WorkContext 反序列化,CVE-2017-10271 / CVE-2019-2725 家族)。
  • 依赖服务端 classpath 存在 oracle.toplink.internal.sessions.UnitOfWorkChangeSet(TopLink,WebLogic 自带),由它完成从 XML 内嵌字节到 Java 对象的二次反序列化。
  • 本构件只做「封装/编码」,真正的 RCE 能力取决于内层 Java 原生反序列化链是否可用;两段解耦,便于替换内层 gadget。

所属预设链

usedInChains 为空 —— 自由构件,未直接出现在 51 条预设链中。作为 XMLDecoder/WebLogic 场景的最外层封装,需自行搭配内层 Java 原生反序列化链使用。

关联

  • 下游(nextTags=JavaNativeDeserializePayload / CustomJavaDeserialize):任意产出 Java 原生序列化字节的链,例如以 CommonsBeanutils1 为首、末端接 TemplatesImpl → BytecodeConvert → Exec 的经典链,再由本构件封装为 XMLDecoder 报文。
  • 同族(同为「格式/字节转换」类):BytecodeConvert 等 sink 前置封装构件。