feat: support ssti and expression packer

This commit is contained in:
ReaJason
2024-12-14 19:28:13 +08:00
parent 13ddea499a
commit 74cb677e98
61 changed files with 564 additions and 135 deletions
+27
View File
@@ -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());
}
}
+28
View File
@@ -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);
}
}
+20
View File
@@ -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);
}
}
+15 -22
View File
@@ -9,10 +9,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.zip.GZIPInputStream;
/**
@@ -169,32 +166,27 @@ public class TestServlet extends HttpServlet {
return false;
}
public List<Object> getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
public List<Object> getContext() {
List<Object> contexts = new ArrayList();
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads");
Set<Object> visited = new HashSet();
try {
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads", new Class[0], new Object[0]);
for (Thread thread : threads) {
if (thread.getName().contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map) this.getFieldValue(this.getFieldValue(this.getFieldValue(thread, "target"), "this$0"), "children");
for (Object key : childrenMap.keySet()) {
Map<?, ?> children = (Map) this.getFieldValue(childrenMap.get(key), "children");
for (Object key1 : children.keySet()) {
Object context = children.get(key1);
if (context != null && context.getClass().getName().contains("StandardContext")) {
contexts.add(context);
}
}
if (thread.getClass().getName().contains("Resin")) {
Class<?> servletInvocationClass = thread.getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation");
Object contextRequest = servletInvocationClass.getMethod("getContextRequest").invoke(null);
Object webApp = invokeMethod(contextRequest, "getWebApp", new Class[0], new Object[0]);
if (webApp != null && visited.add(webApp)) {
contexts.add(webApp);
}
}
}
return contexts;
} catch (Exception e) {
throw new RuntimeException(e);
// Handle exception
}
return contexts;
}
private Object getFilter(Object context) {
@@ -267,7 +259,8 @@ public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Object> context = getContext();
System.out.println(context.size());
}
@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>
</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-class>ErrorListener</listener-class>-->