feat: support springmvc shell generate

This commit is contained in:
ReaJason
2024-12-22 16:29:02 +08:00
parent 91181ffc55
commit 77e5371fa8
50 changed files with 1546 additions and 181 deletions
+8
View File
@@ -0,0 +1,8 @@
FROM openjdk:17
WORKDIR /app
COPY build/libs/vul-springboot3.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT java $JAVA_OPTS -jar app.jar
+20
View File
@@ -0,0 +1,20 @@
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.3.7'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.reajason.javaweb.vul'
version = ''
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
}
@@ -0,0 +1,10 @@
package com.reajason.javaweb.vul.springboot3;
public class ClassDefiner extends ClassLoader {
private ClassDefiner() {
}
public static Class<?> defineClass(byte[] code) {
return new ClassDefiner().defineClass(null, code, 0, code.length);
}
}
@@ -0,0 +1,12 @@
package com.reajason.javaweb.vul.springboot3;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class VulSpringboot3Application {
public static void main(String[] args) {
SpringApplication.run(VulSpringboot3Application.class, args);
}
}
@@ -0,0 +1,24 @@
package com.reajason.javaweb.vul.springboot3.controller;
import com.reajason.javaweb.vul.springboot3.ClassDefiner;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Base64;
/**
* @author ReaJason
* @since 2024/12/22
*/
@RestController
@RequestMapping("/b64")
public class Base64ClassLoaderController {
@PostMapping
public String base64ClassLoader(String data) throws InstantiationException, IllegalAccessException {
byte[] bytes = Base64.getDecoder().decode(data);
Object o = ClassDefiner.defineClass(bytes).newInstance();
return o.toString();
}
}
@@ -0,0 +1,123 @@
package com.reajason.javaweb.vul.springboot3.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.zip.GZIPInputStream;
/**
* @author ReaJason
* @since 2024/12/22
*/
@RestController
public class IndexController {
@RequestMapping("/test")
public String test() throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
return "";
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName) throws
Exception {
return invokeMethod(obj, methodName, new Class[0], new Object[0]);
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static byte[] decodeBase64(String base64Str) throws Exception {
Class<?> decoderClass;
try {
decoderClass = Class.forName("java.util.Base64");
Object decoder = decoderClass.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
} catch (Exception ignored) {
decoderClass = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
}
}
@SuppressWarnings("all")
public static byte[] gzipDecompress(byte[] compressedData) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPInputStream gzipInputStream = null;
try {
gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedData));
byte[] buffer = new byte[4096];
int n;
while ((n = gzipInputStream.read(buffer)) > 0) {
out.write(buffer, 0, n);
}
} finally {
if (gzipInputStream != null) {
try {
gzipInputStream.close();
} catch (IOException ignored) {
}
}
out.close();
}
return out.toByteArray();
}
@SuppressWarnings("all")
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
for (Class<?> clazz = obj.getClass();
clazz != Object.class;
clazz = clazz.getSuperclass()) {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException ignored) {
}
}
throw new NoSuchFieldException(name);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
try {
Field field = getField(obj, name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException ignored) {
}
return null;
}
@GetMapping("/")
public String index() {
return "hello";
}
}
@@ -0,0 +1,25 @@
package com.reajason.javaweb.vul.springboot3.controller;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author ReaJason
* @since 2024/12/22
*/
@RestController
@RequestMapping("/spel")
public class SpELController {
/**
* 10000 长度限制,无法使用
*/
@PostMapping
public ResponseEntity<?> spel(String data) {
return ResponseEntity.ok().body(String.valueOf(new SpelExpressionParser().parseExpression(data).getValue(new StandardEvaluationContext())));
}
}
@@ -0,0 +1 @@
spring.application.name=vul-springboot3
@@ -0,0 +1,13 @@
package com.reajason.javaweb.vul.springboot3;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class VulSpringboot3ApplicationTests {
@Test
void contextLoads() {
}
}