Spring内存马新手实战指南——Interceptor篇
前言:Interceptor-VS-Controller在Spring MVC中,Interceptor和Controller都可以被用来实现内存马,但攻击者通常优先选择Interceptor。其可以 2025-10-28 05:47:12 Author: www.freebuf.com(查看原文) 阅读量:1 收藏

前言:

Interceptor-VS-Controller

在Spring MVC中,Interceptor和Controller都可以被用来实现内存马,但攻击者通常优先选择Interceptor。其可以在请求到达Controller之前和之后执行代码。它能够拦截多个Controller的请求。而Controller是处理特定请求的处理器,它只对映射到其上的请求路径起作用。这跟tomcat的中的内存马filter(过滤器)与servlet的执行过程几乎差不多,而Interceptor是spring中的拦截器。

单在spring中我们一般会优先选用Interceptor作为内存马,而不是controller,其主要原因如下:

隐蔽性对比:

Interceptor:由于Interceptor不直接与特定的URL映射关联,它通常不会在路由表中暴露,因此更难被扫描和检测。 Controller:Controller通常通过注解(如@RequestMapping)与特定URL映射关联,这些映射信息在Spring中是可查询的,因此更容易被安全扫描工具发现。

动态注册技术对比:

Interceptor:通过实现WebMvcConfigurer接口,可以动态添加Interceptor,而且可以全局生效。动态注册一个Interceptor相对简单,且不需要破坏现有的Controller结构。其通常不依赖具体的业务逻辑,可以独立于业务代码存在。 Controller:动态注册Controller需要修改Spring MVC的路由映射,更复杂,需要定义具体的处理逻辑,而且容易与现有路由冲突,引起异常。

触发阶段:

Interceptor:可以在请求处理的前后多个阶段进行控制,类似tomcat的filter,比如在预处理、后处理和完成后的处理,因此可以更灵活地操纵请求和响应。其可在controller之前执行。 Controller:只能在映射的请求到达时执行,并且需要处理具体的业务逻辑。

前言小结:

我们优先选择Interceptor作为内存马主要是因为:

隐蔽性优先 - 不新增路由端点,避免安全扫描

控制范围广 - 单一注入点覆盖所有请求路径

技术实现简洁 - 标准接口实现,注册机制稳定可靠

系统影响小 - 异常情况下对业务影响可控

检测难度高 - 在框架层面运作,传统安全设备难以识别

什么是Interceptor

Interceptor(拦截器) :是 Spring MVC 框架中的一种核心组件,一种用于在请求处理过程中进行拦截和处理的机制,实现对 HTTP 请求的拦截和处理,从而实现对 Web 请求的精细化控制和统一处理。

这句话看起来似曾相识,是的,这个能力与java中的filter非常相像,而spring中的controller与Java servlet也非常相似,再次证明了上一个文章说的spring其实是运行在tomcat之上的框架。Interceptor 与 Filter 高度相似,都专注于对“请求-响应”流程的干预和控制-对比如下:

Interceptor-VS-filter

维度Interceptor (Spring MVC)Filter (Java Servlet)
核心目标干预请求处理过程干预请求处理过程
执行时机在 Controller之前之后执行在 Servlet之前之后执行(包裹了Interceptor)
工作模式“拦截”和“处理”“过滤”和“处理”
控制能可以阻止请求继续传递(preHandle返回false)可以阻止请求继续传递(FilterChain.doFilter)
应用场景权限检查、日志记录、性能监控、通用数据处理字符编码设置、安全过滤、压缩响应、XSS防御

实现一个Interceptor

实现一个有效的 Spring Interceptor 需要满足以下几个关键要求:

1.Interceptor类必须实现 HandlerInterceptor 接口,重写preHandle()方法。

2.需要通过一个配置类显式将Interceptor类注册到拦截器链中

3.配置类需要实现WebMvcConfigurer接口,重写addInterceptor()方法。

现在依次实现:

实现1.首先新建一个TestInterceptor.java类,代码如下:

package com.example.demo.demos.web;

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

public class TestInterceptor implements HandlerInterceptor {
    @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor执行");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}

实现2and3.新建一个配置类InterceptorConf.java,用于注册TestInterceptor。

package com.example.demo.demos.web;

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

@Configuration
@EnableWebMvc
public class InterceptorConf implements WebMvcConfigurer {
    @Override
public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");//设置所有页面经过过滤器
    }
}

完成,启动看以下效果:因为设置所有页面addPathPatterns("/*")均通过过滤器,启动之后访问http://127.0.0.1:8080/a 任意页面即可看到过滤器执行了!

1761620053_690030555d4fee4e117b2.png!small?1761620055274

Interceptor实现过滤

回到TestInterceptor.java类文件,看看其重写的方法各个参数:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 有requet,response,handler,都是熟悉的味道!

既然有requet,response那么首先想到的就是直接可以在这里通过requet的参数执行命令,通过response返回命令结果。那么Interceptor就可以通过该方法达到对用户的数据进行校验,过滤的目的了---高度相似filter。

实验下,修改以下TestInterceptor代码如下:做一个简单的XSS拦截器

package com.example.demo.demos.web;

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

public class TestInterceptor implements HandlerInterceptor {//实现接口
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String cmd = request.getParameter("cmd");//请求参数cmd
        if (cmd.contains("script")){//过滤条件
            res

文章来源: https://www.freebuf.com/articles/web/454498.html
如有侵权请联系:admin#unsafe.sh