Skip to content

Latest commit

 

History

History
50 lines (40 loc) · 3.92 KB

File metadata and controls

50 lines (40 loc) · 3.92 KB

TextAndMnemonicHashMap 调用toString 高版本JDK(TextAndMnemonicHashMapToStringHighJDK)

  • 类别:common 别名:— 优先级:10
  • 作者:—
  • 依赖jdk:javax.swing.UIDefaults$TextAndMnemonicHashMap(纯 JDK)

作用

TextAndMnemonicHashMapToString 的高版本 JDK 变体。原理完全相同(HashMap 哈希碰撞 → AbstractMap.equalsTextAndMnemonicHashMap → 内层对象 toString()),唯一区别是在生成 payload 时通过序列化字节流替换 serialVersionUID,把低版本的 UID 改成高版本 JDK 的 UID,从而避免 InvalidClassException,使该 toString 入口在高版本(如 JDK 17)上仍可用。

链接标签

  • 入口 tagsJavaNativeDeserialize —— 承接 Java 原生反序列化入口。
  • 衔接 nextTagsToString —— 之后接「危险 toString」型 gadget。
  • excludes:无。

(与基类标签一致)

源码剖析

本类只覆写 invoke,向上下文追加一条 serialVersionUID 替换指令,其余全部委托给基类:

public class TextAndMnemonicHashMapToStringHighJDK
extends TextAndMnemonicHashMapToString {
    @Override
    public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
        context.put(ContextTag.SUID_REPLACE,
            context.getString(ContextTag.SUID_REPLACE) + ";-4759762391791842796|5869230443415797669");
        return super.invoke(context, chain);
    }
}
  • ContextTag.SUID_REPLACE 是一份「UID 替换清单」,格式为 旧UID|新UID,多条以 ; 分隔。这里追加 -4759762391791842796|5869230443415797669:把某版本 TextAndMnemonicHashMap(或相关类)序列化时写入的旧 serialVersionUID -4759762391791842796,替换为高版本 JDK 的 5869230443415797669
  • 替换发生在 payload 序列化完成后、对字节流做后处理的阶段:框架扫描序列化字节中出现的旧 UID 并逐字节改写为新 UID。这样反序列化端按新 UID 校验类版本即可通过,绕过高低版本 UID 不一致导致的 InvalidClassException
  • super.invoke(...) 复用基类逻辑:chain.doCreate 取内层对象 → getObject 构造两个 TextAndMnemonicHashMap + 哈希碰撞外层 HashMap(详见 基类条目)。

重要坑点(源码 description 明确标注):由于 UID 修改是「字节流替换」这种事后打补丁的方式完成,在二次反序列化场景中可能失效——因为二次反序列化时外层再套一层序列化,内层字节被重新编码/包裹,事先做的字节替换不一定还落在正确位置。

参数(@Param)

@Param;行为与目标 toString 均由链上下文与下游 gadget 决定,UID 替换对由本类硬编码写入 SUID_REPLACE

适用版本与原理要点

  • 面向高版本 JDK(典型如 JDK 17):此时 TextAndMnemonicHashMap 的 UID 与低版本不同,直接用基类会 InvalidClassException,故需本类的字节流 UID 替换。
  • suid: -4759762391791842796 --> 5869230443415797669 即替换映射;面向的目标环境应期望后一个 UID。
  • 不建议用于二次反序列化链(字节替换可能对不上位置)。二次反序列化下宜选其它入口。

所属预设链

  • JDK17 RCE链2[TextAndMnemonicHashMapToStringHighJDK, JacksonToString, TWrapHighVersion, TemplatesImpl2, BytecodeConvert, Exec])—— 作为高版本 JDK 下的 readObject → toString 入口,衔接 JacksonToString 进而走到 TemplatesImpl2 加载字节码执行命令。

关联

  • 基类:TextAndMnemonicHashMapToString
  • 下游(nextTags=ToString,本链实际使用):JacksonToStringTWrapHighVersionTemplatesImpl2
  • 同类高版本 JDK 入口:EventListenerListToStringHighJDK(「JDK17 RCE链」使用)。