From 6b670ffec42a4b5265d5df08faca4b3f081db686 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Fri, 23 May 2025 01:54:15 +0800 Subject: [PATCH] feat: add diff tips for attacher --- web/src/components/results/agent.tsx | 46 +++++++++++-------- web/src/components/results/jar-result.tsx | 2 +- .../components/results/result-component.tsx | 38 ++++++++------- web/src/i18n/en.json | 6 ++- web/src/i18n/zh-CN.json | 6 ++- web/src/lib/utils.ts | 22 +++++++++ 6 files changed, 77 insertions(+), 43 deletions(-) diff --git a/web/src/components/results/agent.tsx b/web/src/components/results/agent.tsx index 6a43fd40..8199e522 100644 --- a/web/src/components/results/agent.tsx +++ b/web/src/components/results/agent.tsx @@ -1,4 +1,4 @@ -import { downloadBytes } from "@/lib/utils"; +import { downloadBytes, formatBytes } from "@/lib/utils"; import { GenerateResult } from "@/types/shell"; import { ScrollTextIcon } from "lucide-react"; import { useTranslation } from "react-i18next"; @@ -6,8 +6,14 @@ import { Button } from "../ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "../ui/card"; import { Separator } from "../ui/separator"; -export function AgentResult({ packResult, generateResult }: { packResult: string; generateResult?: GenerateResult }) { +export function AgentResult({ + packMethod, + packResult, + generateResult, +}: Readonly<{ packMethod: string; packResult: string; generateResult?: GenerateResult }>) { const { t } = useTranslation(); + console.log(packMethod); + const isPureAgent = packMethod === "AgentJar"; return ( @@ -19,7 +25,9 @@ export function AgentResult({ packResult, generateResult }: { packResult: string
  1. - {t("download")} MemShellAgent.jar + + {t("download")} MemShellAgent.jar ({formatBytes(atob(packResult).length)}) + -
  2. -
  3. - {t("tips.download-jattach")} -
  4. + {isPureAgent && ( +
  5. + {t("tips.download-jattach")} + +
  6. + )} -
  7. {t("tips.move-to-container")}
  8. +
  9. {isPureAgent ? t("tips.agent-move-to-target") : t("tips.agent-move-to-target1")}
  10. {t("tips.get-pid")}
  11. -
  12. {t("tips.execute-command")}
  13. +
  14. {isPureAgent ? t("tips.execute-command") : t("tips.execute-command1")}
  15. {t("tips.try-to-use-shell")}
diff --git a/web/src/components/results/jar-result.tsx b/web/src/components/results/jar-result.tsx index 3951e36a..79a22100 100644 --- a/web/src/components/results/jar-result.tsx +++ b/web/src/components/results/jar-result.tsx @@ -3,7 +3,7 @@ import { GenerateResult } from "@/types/shell"; import { useTranslation } from "react-i18next"; import { Button } from "../ui/button"; -export function JarResult({ packResult, generateResult }: { packResult: string; generateResult?: GenerateResult }) { +export function JarResult({ packResult, generateResult }: Readonly<{ packResult: string; generateResult?: GenerateResult }>) { const { t } = useTranslation(); return (
diff --git a/web/src/components/results/result-component.tsx b/web/src/components/results/result-component.tsx index 383b7daf..b87fde42 100644 --- a/web/src/components/results/result-component.tsx +++ b/web/src/components/results/result-component.tsx @@ -12,13 +12,13 @@ export function ResultComponent({ packMethod, t, generateResult, -}: { +}: Readonly<{ packResult: string | undefined; allPackResults: Map | undefined; packMethod: string; t: TFunction; generateResult?: GenerateResult; -}) { +}>) { const showCode = packMethod === "JSP"; const isAgent = packMethod.startsWith("Agent"); const isJar = packMethod === "Jar"; @@ -27,30 +27,28 @@ export function ResultComponent({ } if (isAgent) { - return ; + return ; } if (isJar) { return ; } if (!isAgent && !isJar) { return ( - - - - {t("packageConfig.title")}:{packMethod} - - ({packResult?.length}) -
- } - wrapLongLines={!showCode} - showLineNumbers={showCode} - language={showCode ? "java" : "text"} - height={350} - /> - + + + {t("packageConfig.title")}:{packMethod} + + ({packResult?.length}) + + } + wrapLongLines={!showCode} + showLineNumbers={showCode} + language={showCode ? "java" : "text"} + height={350} + /> ); } return null; diff --git a/web/src/i18n/en.json b/web/src/i18n/en.json index 33ac2021..b1983eb3 100644 --- a/web/src/i18n/en.json +++ b/web/src/i18n/en.json @@ -119,13 +119,15 @@ "tips": { "controllerUrlPattern": "ControllerHandler type requires a specific URL Pattern, e.g., /hello_controller", "decompileTip": "Decompilation is still under development, so the current only sees the base64 encoding format", - "download-jattach": "Download the Jattach tool (consider it directly encapsulated in Jar later)", + "download-jattach": "Download the Jattach tool", "execute-command": "Execute the command to inject: /path/to/jattach pid load instrument false /path/to/agent.jar", + "execute-command1": "Execute the command to inject: java -jar /path/to/agent.jar pid", "get-pid": "Get the process pid of the target jvm (use jps or ps)", "handlerUrlPattern": "HandlerMethod/HandlerFunction type requires a specific URL Pattern, e.g., /hello_handler", "jreTip": "Target JRE version, generally speaking, Java 6 is the default version for maximum compatibility, and Java high versions can load low version bytecode.", "jreTip2": "In specific cases, such as JDK8 being able to use lambda expressions, and JDK9 and above having module restrictions, a specific version is required.", - "move-to-container": "Move MemShellAgent.jar and jattach to the container (if the test environment uses a container deployment)", + "agent-move-to-target": "Move MemShellAgent.jar and jattach to target host", + "agent-move-to-target1": "Move MemShellAgent.jar to target host", "servletUrlPattern": "Servlet type requires a specific URL Pattern, e.g., /hello_servlet", "shellBytesEmpty": "Shell bytes is empty, please generate shell first", "shellToolNotSelected": "Please select a shell tool type first", diff --git a/web/src/i18n/zh-CN.json b/web/src/i18n/zh-CN.json index d4223291..6666187c 100644 --- a/web/src/i18n/zh-CN.json +++ b/web/src/i18n/zh-CN.json @@ -119,13 +119,15 @@ "tips": { "controllerUrlPattern": "ControllerHandler 类型的需要填写具体的 URL Pattern,例如 /hello_controller", "decompileTip": "反编译还在开发中,因此当前仅能看到 base64 编码格式", - "download-jattach": "下载 Jattach 工具(后期考虑直接封装在 Jar 中)", + "download-jattach": "下载 Jattach 工具", "execute-command": "执行命令进行注入:/path/to/jattach pid load instrument false /path/to/agent.jar", + "execute-command1": "执行命令进行注入:java -jar /path/to/agent.jar pid", "get-pid": "获取目标 jvm 的进程 pid(使用 jps 或 ps)", "handlerUrlPattern": "HandlerMethod/HandlerFunction 类型的需要填写具体的 URL Pattern,例如 /hello_handler", "jreTip": "目标 JRE 版本,一般而言为了最大的兼容性,默认 Java 6 即可,Java 高版本能加载低版本的字节码。", "jreTip2": "特定情况下,例如 JDK8 才能使用 lambda 表达式,JDK9 以上存在模块限制时才需要选择特定的版本。", - "move-to-container": "将 MemShellAgent.jar 和 jattach 移动到容器中(如果测试环境使用容器部署)", + "agent-move-to-target": "将 MemShellAgent.jar 和 jattach 移到到目标服务磁盘上", + "agent-move-to-target1": "将 MemShellAgent.jar 移到到目标服务磁盘上", "servletUrlPattern": "Servlet 类型的需要填写具体的 URL Pattern,例如 /hello_servlet", "shellBytesEmpty": "内存马字节码为空,无法下载,请先生成内存马", "shellToolNotSelected": "请先选择内存马工具类型", diff --git a/web/src/lib/utils.ts b/web/src/lib/utils.ts index 050b799d..f4edfa28 100644 --- a/web/src/lib/utils.ts +++ b/web/src/lib/utils.ts @@ -25,3 +25,25 @@ export function downloadBytes(base64String: string, className?: string, jarName? link.click(); document.body.removeChild(link); } + +export function formatBytes(bytes: number) { + if (bytes === 0) return '0 Bytes'; + if (Number.isNaN(bytes) || !Number.isFinite(bytes)) return 'N/A'; + + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB']; // Add more units like GB, TB if needed + + if (bytes < k) { + return `${bytes.toFixed(0)} ${sizes[0]}`; // Bytes, no decimal + } + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + // Prefer MB if KB value is 1000 or more, or if it's already in MB (i >= 2) + if (i >= 2 || (bytes / k ** 1) >= 1000) { + const mbValue = Number.parseFloat((bytes / k ** 2).toFixed(2)); + return `${mbValue} ${sizes[2]}`; + } + const kbValue = Number.parseFloat((bytes / k ** 1).toFixed(1)); + return `${kbValue} ${sizes[1]}`; +} \ No newline at end of file