+
-
-
- {value} {size != null && `(${size} bytes)`}
-
+
+
{text}
-
-
-
+ {value && (
+
+
+
+ )}
);
}
diff --git a/web/src/components/main-config-card.tsx b/web/src/components/main-config-card.tsx
index 86214079..59ef91ed 100644
--- a/web/src/components/main-config-card.tsx
+++ b/web/src/components/main-config-card.tsx
@@ -1,15 +1,17 @@
import { UrlPatternTip } from "@/components/tips/url-pattern-tip.tsx";
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
import { FormControl, FormDescription, FormField, FormItem, FormLabel } from "@/components/ui/form.tsx";
import { Input } from "@/components/ui/input.tsx";
import { Label } from "@/components/ui/label.tsx";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select.tsx";
-import { Separator } from "@/components/ui/separator.tsx";
import { Switch } from "@/components/ui/switch.tsx";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { FormSchema } from "@/types/schema.ts";
import { MainConfig } from "@/types/shell.ts";
-import { ServerIcon } from "lucide-react";
+import { JreTip } from "@/components/tips/jre-tip.tsx";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
+import { cn } from "@/lib/utils.ts";
+import { ArrowUpRightIcon, ServerIcon } from "lucide-react";
import { useState } from "react";
import { FormProvider, UseFormReturn } from "react-hook-form";
@@ -32,14 +34,23 @@ export function MainConfigCard({
servers?: string[];
}) {
const [shellToolMap, setShellToolMap] = useState<{ [toolName: string]: string[] }>();
- const [shellTools, setShellTools] = useState
([]);
+ const [shellTools, setShellTools] = useState(["Behinder", "Godzilla", "Command"]);
const [shellTypes, setShellTypes] = useState([]);
+ const shellTool = form.watch("shellTool");
const handleServerChange = (value: string) => {
if (mainConfig) {
- setShellToolMap(mainConfig[value]);
- setShellTools(Object.keys(mainConfig[value]));
- setShellTypes([]);
+ const newShellToolMap = mainConfig[value];
+ setShellToolMap(newShellToolMap);
+ const newShellTools = Object.keys(newShellToolMap);
+ setShellTools(newShellTools);
+ if (newShellTools.length > 0) {
+ const firstTool = newShellTools[0];
+ setShellTypes(newShellToolMap[firstTool]);
+ form.setValue("shellTool", firstTool);
+ } else {
+ setShellTypes([]);
+ }
form.resetField("shellTool");
form.resetField("shellType");
}
@@ -66,6 +77,9 @@ export function MainConfigCard({
if (shellToolMap) {
setShellTypes(shellToolMap[value]);
form.resetField("urlPattern");
+ form.resetField("shellType");
+ form.resetField("shellClassName");
+ form.resetField("injectorClassName");
if (value === "Godzilla") {
resetGodzilla();
} else if (value === "Behinder") {
@@ -74,17 +88,18 @@ export function MainConfigCard({
resetCommand();
}
}
+ form.setValue("shellTool", value);
};
return (
-
-
-
-
- 核心配置
-
-
-
+
+
+
+
+
+ 生成配置
+
+
+
+ 下拉列表找不到目标服务 ?
+
+ 请求适配
+
+
+
)}
/>
@@ -120,8 +147,10 @@ export function MainConfigCard({
control={form.control}
name="targetJdkVersion"
render={({ field }) => (
-
- JRE(可选)
+
+
-
+
-
-
- )}
- />
-
-
-
-
-
-
-
-
-
-
-
(
-
- 内存马类名(可选)
-
-
- )}
- />
-
- (
-
- 内存马工具类型
-
-
- )}
- />
- (
-
- 内存马挂载类型
-
-
- )}
- />
- (
-
-
-
+
)}
/>
-
+
+
+
+
+
+ );
+}
+
+function GodzillaTabContent({ form, shellTypes }: { form: UseFormReturn; shellTypes: Array }) {
+ return (
+
+
+
+
+
+
+
+
+
+ (
+
+ 密码
+
+
+ )}
+ />
+ (
+
+ 密钥
+
+
+ )}
+ />
+ (
+
+ 请求头键
+
+
+ )}
+ />
+ (
+
+ 请求头值
+
+
+ )}
+ />
+
+
+
+
+
+
+ );
+}
+
+function CommandTabContent({ form, shellTypes }: { form: UseFormReturn; shellTypes: Array }) {
+ return (
+
+
+
+
+
+
+
+
+ (
+
+ 请求参数
+
+
+
+ 填写接收命令的请求参数,例如填 cmd 即 `?cmd=whoami` 来执行命令
+
+ )}
+ />
+
+
+
+
+
);
}
diff --git a/web/src/components/package-config-card.tsx b/web/src/components/package-config-card.tsx
index f1db2962..a1afdd80 100644
--- a/web/src/components/package-config-card.tsx
+++ b/web/src/components/package-config-card.tsx
@@ -4,6 +4,7 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group.tsx";
import { FormSchema } from "@/types/schema.ts";
import { PackerConfig } from "@/types/shell.ts";
import { PackageIcon } from "lucide-react";
+import { useEffect, useState } from "react";
import { FormProvider, UseFormReturn } from "react-hook-form";
export function PackageConfigCard({
@@ -13,6 +14,26 @@ export function PackageConfigCard({
packerConfig: PackerConfig | undefined;
form: UseFormReturn;
}) {
+ const [options, setOptions] = useState>>([]);
+
+ const shellType = form.watch("shellType");
+
+ useEffect(() => {
+ const filteredOptions = Object.entries(packerConfig ?? {}).filter(([name, _]) => {
+ if (!shellType || shellType === " ") {
+ return true;
+ }
+ if (shellType.startsWith("Agent")) {
+ return name.startsWith("Agent");
+ }
+ return !name.startsWith("Agent");
+ });
+ setOptions(filteredOptions);
+ if (filteredOptions.length > 0) {
+ form.setValue("packingMethod", filteredOptions[0][0]);
+ }
+ }, [form, packerConfig, shellType]); // Add shellType to the dependency array
+
return (
@@ -30,8 +51,8 @@ export function PackageConfigCard({
打包方式
-
- {Object.entries(packerConfig ?? {}).map(([name, value]) => (
+
+ {options.map(([name, value]) => (
diff --git a/web/src/components/quick-usage.tsx b/web/src/components/quick-usage.tsx
new file mode 100644
index 00000000..8cf06ca9
--- /dev/null
+++ b/web/src/components/quick-usage.tsx
@@ -0,0 +1,20 @@
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
+
+export function QuickUsage() {
+ return (
+
+
+ 快速使用
+
+
+
+ - 选择目标服务
+ - 选择内存马功能,Godzilla、Behinder 或者其他
+ - 选择内存马挂载类型,Filter、Listener 或者其他
+ - 选择打包方式
+ - 点击生成内存马
+
+
+
+ );
+}
diff --git a/web/src/components/shell-result.tsx b/web/src/components/shell-result.tsx
index 5585281b..aeaa14f3 100644
--- a/web/src/components/shell-result.tsx
+++ b/web/src/components/shell-result.tsx
@@ -1,57 +1,194 @@
import { CodeViewer } from "@/components/code-viewer.tsx";
import { CopyableField } from "@/components/copyable-field.tsx";
+import { QuickUsage } from "@/components/quick-usage.tsx";
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@/components/ui/alert-dialog";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert.tsx";
import { Button } from "@/components/ui/button.tsx";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
-import { Label } from "@/components/ui/label.tsx";
import { Separator } from "@/components/ui/separator.tsx";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs.tsx";
import { downloadBytes } from "@/lib/utils.ts";
-import { GenerateResult } from "@/types/shell.ts";
-import { TicketsIcon, TriangleAlertIcon } from "lucide-react";
+import {
+ BehinderShellToolConfig,
+ CommandShellToolConfig,
+ GenerateResult,
+ GodzillaShellToolConfig,
+} from "@/types/shell.ts";
+import { CircleHelpIcon, TriangleAlertIcon } from "lucide-react";
+import { Fragment } from "react";
function AgentResult({ packResult, generateResult }: { packResult: string; generateResult?: GenerateResult }) {
return (
-
-
- -
- 下载 MemShellAgent.jar
-
+ );
+}
+
+function FeedbackAlert() {
+ return (
+
+
+
+ 内存马利用失败 ?
+
+
+
+
+ 内存马利用失败 ?
+
+
+ - 1. 尝试开启调试模式,重新生成内存马并注入,查看控制台或日志
+ - 2. 如果出现异常堆栈信息,或未见异常,请截图当前生成界面以及异常日志,并尽可能描述目标环境进行反馈
+
+
+
+
+ 取消
+
- downloadBytes(
- packResult,
- undefined,
- `${generateResult?.shellConfig.server}${generateResult?.shellConfig.shellTool}MemShellAgent`,
+ window.open(
+ "https://github.com/ReaJason/MemShellParty/issues/new?template=%E5%86%85%E5%AD%98%E9%A9%AC%E7%94%9F%E6%88%90-bug-%E4%B8%8A%E6%8A%A5.md",
)
}
>
- 下载 Jar
-
-
-
- 下载 Jattach 工具(后期考虑直接封装在 Jar 中)
- window.open("https://github.com/jattach/jattach/releases")}
- >
- 下载 Jattach
-
-
-
- 使用方法:
- 将 MemShellAgent.jar 和 jattach 移动到容器中(如果测试环境使用容器部署)
- 获取目标 jvm 的进程 pid (使用 jps 或 ps)
- 执行命令进行注入:/path/to/jattach pid load instrument false /path/to/agent.jar
- 尝试连接测试
-
-
+ 反馈
+
+
+
+
+ );
+}
+
+function BasicInfo({ generateResult }: { generateResult?: GenerateResult }) {
+ return (
+
+
+
+ 基础信息
+
+
+
+
+
+
+
+
+
+
+ {generateResult?.shellConfig.shellTool === "Behinder" && (
+
+
+
+
+
+
+ )}
+ {generateResult?.shellConfig.shellTool === "Godzilla" && (
+
+
+
+
+
+
+
+ )}
+ {generateResult?.shellConfig.shellTool === "Command" && (
+
+
+
+ )}
+
+
+
+
);
}
@@ -63,125 +200,80 @@ export function ShellResult({
const showCode = packMethod === "JSP";
const isAgent = packMethod.startsWith("Agent");
return (
-
-
-
-
- FBI
-
-
-
-
-
- 打包结果
- 内存马类
- 注入器类
-
-
- {generateResult && !isAgent && (
-
-
-
-
- )}
- {!isAgent && (
-
- )}
- {isAgent && }
-
-
-
-
- Warning
- 反编译还在开发中,因此当前仅能看到 base64 编码格式
-
-
- {generateResult && (
-
-
-
-
{generateResult?.shellClassName}
-
-
-
-
{generateResult?.shellSize ?? 0} bytes
-
-
- )}
- {generateResult && (
-
downloadBytes(generateResult?.shellBytesBase64Str, generateResult?.shellClassName)}
- >
- 下载 Class
-
- )}
-
-
-
-
-
-
- Warning
- 反编译还在开发中,因此当前仅能看到 base64 编码格式
-
-
- {generateResult && (
-
-
-
-
{generateResult?.injectorClassName}
-
-
-
-
{generateResult?.injectorSize ?? 0} bytes
-
-
- )}
- {generateResult && (
-
- downloadBytes(generateResult?.injectorBytesBase64Str, generateResult?.injectorClassName)
- }
- >
- 下载 Class
-
- )}
-
-
-
-
-
-
+
+
+ 打包结果
+ 内存马类
+ 注入器类
+
+
+
+ {generateResult && }
+ {!generateResult && }
+
+ {!isAgent && (
+
+ )}
+ {isAgent && }
+
+
+
+
+ Warning
+ 反编译还在开发中,因此当前仅能看到 base64 编码格式
+
+
+ {generateResult && (
+ downloadBytes(generateResult?.shellBytesBase64Str, generateResult?.shellClassName)}
+ >
+ 下载 Class
+
+ )}
+
+
+
+
+
+
+ Warning
+ 反编译还在开发中,因此当前仅能看到 base64 编码格式
+
+
+ {generateResult && (
+ downloadBytes(generateResult?.injectorBytesBase64Str, generateResult?.injectorClassName)}
+ >
+ 下载 Class
+
+ )}
+
+
+
+
);
}
diff --git a/web/src/components/tips/jre-tip.tsx b/web/src/components/tips/jre-tip.tsx
index fedd5cad..2fdad5ed 100644
--- a/web/src/components/tips/jre-tip.tsx
+++ b/web/src/components/tips/jre-tip.tsx
@@ -1,15 +1,15 @@
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip.tsx";
import { InfoIcon } from "lucide-react";
-export function JRETip() {
+export function JreTip() {
return (
-
+
- 目标 JRE 版本,一般而言为了最大的兼容性,默认 Java 6 即可。
+ 目标 JRE 版本,一般而言为了最大的兼容性,默认 Java 6 即可,Java 高版本能加载低版本的字节码。
特定情况下,例如 JDK8 才能使用 lambda 表达式,JDK9 以上存在模块限制时才需要选择特定的版本。
diff --git a/web/src/config.ts b/web/src/config.ts
index 6998524b..729555e3 100644
--- a/web/src/config.ts
+++ b/web/src/config.ts
@@ -2,16 +2,20 @@ import * as z from "zod";
const EnvSchema = z.object({
API_URL: z.optional(z.string()),
+ MODE: z.string(),
});
const createEnv = () => {
// @ts-ignore
const envVars = Object.entries(import.meta.env).reduce>((acc, curr) => {
const [key, value] = curr;
- if (key.startsWith("VITE_APP_")) {
- if (typeof value === "string") {
+ if (typeof value === "string") {
+ if (key.startsWith("VITE_APP_")) {
acc[key.replace("VITE_APP_", "")] = value;
}
+ if (key === "MODE") {
+ acc[key] = value;
+ }
}
return acc;
}, {});
diff --git a/web/src/main.tsx b/web/src/main.tsx
index 84c89347..969f6d6e 100644
--- a/web/src/main.tsx
+++ b/web/src/main.tsx
@@ -4,6 +4,7 @@ import { routeTree } from "./routeTree.gen";
import "./index.css";
import { TailwindIndicator } from "@/components/tailwind-indicator.tsx";
import { Toaster } from "@/components/ui/sonner.tsx";
+import { env } from "@/config.ts";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
@@ -27,7 +28,7 @@ if (!rootElement.innerHTML) {
-
+ {env.MODE !== "production" && }
,
);
}
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index 667aeed1..1a84b809 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -1,7 +1,6 @@
import { MainConfigCard } from "@/components/main-config-card.tsx";
import { PackageConfigCard } from "@/components/package-config-card.tsx";
import { ShellResult } from "@/components/shell-result.tsx";
-import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert.tsx";
import { Button } from "@/components/ui/button";
import { Form } from "@/components/ui/form.tsx";
import { env } from "@/config.ts";
@@ -11,7 +10,7 @@ import { transformToPostData } from "@/utils/transformer.ts";
import { zodResolver } from "@hookform/resolvers/zod";
import { useQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
-import { ActivityIcon, LoaderCircle, ServerOffIcon, WandSparklesIcon } from "lucide-react";
+import { LoaderCircle, WandSparklesIcon } from "lucide-react";
import { useState, useTransition } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
@@ -21,7 +20,7 @@ export const Route = createFileRoute("/")({
});
function IndexComponent() {
- const { isPending, isError, data } = useQuery({
+ const { data } = useQuery({
queryKey: ["config"],
queryFn: async () => {
const response = await fetch(`${env.API_URL}/config`);
@@ -36,7 +35,7 @@ function IndexComponent() {
debug: false,
bypassJavaModule: false,
shellClassName: "",
- shellTool: "",
+ shellTool: "Behinder",
shellType: "",
urlPattern: "/*",
godzillaPass: "pass",
@@ -123,46 +122,20 @@ function IndexComponent() {
}
return (
-
-
- {isPending && (
-
-
- Pending
- 正在全力搜索可用的后端服务~
-
- )}
- {isError && (
-
-
- Not Work!
- 未检测到可用后端服务,生成功能暂不可用.
-
- )}
-
- {!isError && data && (
-
-
- It Work!
- Let's start the party! 🎉
-
- )}
-
-
-
-
+
+
);
}
diff --git a/web/src/types/shell.ts b/web/src/types/shell.ts
index 49afd18a..2146e9ed 100644
--- a/web/src/types/shell.ts
+++ b/web/src/types/shell.ts
@@ -33,8 +33,16 @@ export interface GodzillaShellToolConfig {
headerValue?: string;
}
+export interface BehinderShellToolConfig {
+ shellClassName?: string;
+ pass?: string;
+ headerName?: string;
+ headerValue?: string;
+}
+
export interface InjectorConfig {
className?: string;
+ classInheritance?: string;
urlPattern?: string;
}
@@ -71,6 +79,6 @@ export interface GenerateResult {
injectorSize: number;
injectorBytesBase64Str: string;
shellConfig: ShellConfig;
- shellToolConfig: CommandShellToolConfig | GodzillaShellToolConfig;
+ shellToolConfig: CommandShellToolConfig | GodzillaShellToolConfig | BehinderShellToolConfig;
injectorConfig: InjectorConfig;
}
diff --git a/web/src/utils/transformer.ts b/web/src/utils/transformer.ts
index 03a354e6..ddeb85a8 100644
--- a/web/src/utils/transformer.ts
+++ b/web/src/utils/transformer.ts
@@ -6,6 +6,7 @@ export function transformToPostData(formValue: FormSchema) {
server: formValue.server,
shellTool: formValue.shellTool,
shellType: formValue.shellType,
+ debug: formValue.debug,
targetJreVersion: formValue.targetJdkVersion,
byPassJavaModule: formValue.bypassJavaModule,
};
diff --git a/web/tsconfig.app.tsbuildinfo b/web/tsconfig.app.tsbuildinfo
index 0e95ab56..8bc8a6b8 100644
--- a/web/tsconfig.app.tsbuildinfo
+++ b/web/tsconfig.app.tsbuildinfo
@@ -1 +1 @@
-{"root":["./src/config.ts","./src/main.tsx","./src/routetree.gen.ts","./src/components/code-viewer.tsx","./src/components/main-config-card.tsx","./src/components/mode-toggle.tsx","./src/components/package-config-card.tsx","./src/components/shell-result.tsx","./src/components/tailwind-indicator.tsx","./src/components/theme-provider.tsx","./src/components/tips/jre-tip.tsx","./src/components/tips/url-pattern-tip.tsx","./src/components/ui/alert.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/checkbox.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/form.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/radio-group.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/sonner.tsx","./src/components/ui/switch.tsx","./src/components/ui/tabs.tsx","./src/components/ui/textarea.tsx","./src/components/ui/tooltip.tsx","./src/lib/utils.ts","./src/routes/__root.tsx","./src/routes/index.tsx","./src/types/schema.ts","./src/types/shell.ts","./src/utils/transformer.ts"],"version":"5.7.2"}
\ No newline at end of file
+{"root":["./src/config.ts","./src/main.tsx","./src/routetree.gen.ts","./src/components/code-viewer.tsx","./src/components/copyable-field.tsx","./src/components/main-config-card.tsx","./src/components/mode-toggle.tsx","./src/components/package-config-card.tsx","./src/components/quick-usage.tsx","./src/components/shell-result.tsx","./src/components/tailwind-indicator.tsx","./src/components/theme-provider.tsx","./src/components/tips/jre-tip.tsx","./src/components/tips/url-pattern-tip.tsx","./src/components/ui/alert-dialog.tsx","./src/components/ui/alert.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/checkbox.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/form.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/radio-group.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/sonner.tsx","./src/components/ui/switch.tsx","./src/components/ui/tabs.tsx","./src/components/ui/textarea.tsx","./src/components/ui/tooltip.tsx","./src/lib/utils.ts","./src/routes/__root.tsx","./src/routes/index.tsx","./src/types/schema.ts","./src/types/shell.ts","./src/utils/transformer.ts"],"version":"5.7.3"}
\ No newline at end of file
diff --git a/web/tsconfig.node.tsbuildinfo b/web/tsconfig.node.tsbuildinfo
index 1e7ed279..0440098c 100644
--- a/web/tsconfig.node.tsbuildinfo
+++ b/web/tsconfig.node.tsbuildinfo
@@ -1 +1 @@
-{"root":["./vite.config.ts"],"version":"5.7.2"}
\ No newline at end of file
+{"root":["./vite.config.ts"],"version":"5.7.3"}
\ No newline at end of file