Java安全——Tomcat 之 Filter 型内存马
字数 1720 2025-11-02 00:39:25
Tomcat Filter型内存马分析与实现教学文档
一、前言
Filter功能回顾
Filter(过滤器)是Java Web中的核心组件,用于在请求到达Servlet之前或响应返回客户端之前进行拦截处理。通过自定义过滤器可以实现请求修改、权限验证、日志记录等功能。
内存马基本思路
内存Webshell的核心思想:动态创建恶意Filter并将其置于Filter链最前端,从而在请求处理的最早阶段执行恶意代码。
攻击流程:
- 请求首先经过恶意Filter
- 恶意代码执行命令操作
- 请求继续正常处理流程
- 攻击者获得远程命令执行能力
二、Tomcat Filter流程分析
环境搭建
技术栈:
- Tomcat 8.5.81
- Maven项目
依赖配置:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket</artifactId>
<version>8.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>8.5.0</version>
</dependency>
示例Filter实现
import javax.servlet.*;
import java.io.IOException;
public class filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter start");
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {
System.out.println("Performed a filtering operation");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
// 清理资源
}
}
web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
version="4.0">
<filter>
<filter-name>filter</filter-name>
<filter-class>filter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/filter</url-pattern>
</filter-mapping>
</web-app>
三、Filter调用链深度分析
3.1 请求处理后的流程分析(/filter访问后)
调用栈关键节点:
-
ApplicationFilterChain#doFilter()
- 安全检查:
Globals.IS_SECURITY_ENABLED - 核心方法:
internalDoFilter(request, response)
- 安全检查:
-
Filter链处理机制:
// Filter链存储结构 private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0]; // Filter逐个调用逻辑 ApplicationFilterConfig filterConfig = filters[pos++]; Filter filter = filterConfig.getFilter(); filter.doFilter(request, response, this); -
链式调用特点:
- 每个Filter的
doFilter()中调用FilterChain.doFilter()将触发下一个Filter - 最后一个Filter调用
Servlet.service()方法 - 任意Filter未调用
FilterChain.doFilter()将终止流程
- 每个Filter的
3.2 请求处理前的流程分析(/filter访问前)
Valve管道调用序列:
- StandardEngineValve → 引擎级请求处理
- AbstractAccessLogValve → 访问日志记录
- StandardHostValve → 虚拟主机路由
- ErrorReportValve → 错误报告生成
- AuthenticatorBase → 身份验证处理
- StandardContextValve → Web应用上下文处理
- StandardWrapperValve → Servlet包装器处理
关键类说明:
- StandardWrapperValve:负责Servlet生命周期管理和请求分配
- StandardContextValve:Web应用上下文验证和请求过滤
- AuthenticatorBase:提供基础身份认证机制
四、Filter内存马实现原理
4.1 核心技术要点
-
动态Filter注册
- 绕过web.xml静态配置
- 运行时动态添加恶意Filter
-
Filter链位置控制
- 将恶意Filter置于链首
- 确保最先执行恶意代码
-
恶意代码注入
- 在doFilter()中嵌入命令执行逻辑
- 保持Filter链正常传递
4.2 实现步骤
步骤1:获取StandardContext
// 通过Request对象获取Context
ServletRequest request = ...;
StandardContext context = (StandardContext) request.getServletContext();
步骤2:创建Filter配置
// 定义恶意Filter
Filter evilFilter = new EvilFilter();
// 创建Filter配置
FilterDef filterDef = new FilterDef();
filterDef.setFilterName("evilFilter");
filterDef.setFilterClass(evilFilter.getClass().getName());
步骤3:配置Filter映射
FilterMap filterMap = new FilterMap();
filterMap.setFilterName("evilFilter");
filterMap.addURLPattern("/*"); // 拦截所有请求
filterMap.setDispatcher(DispatcherType.REQUEST.name());
步骤4:调整Filter顺序
// 将恶意Filter置于链首
context.addFilterDef(filterDef);
context.addFilterMapBefore(filterMap);
五、防御措施
5.1 检测方案
-
静态检测
- 监控web.xml异常修改
- 检查Filter类加载行为
-
动态检测
- 监控运行时Filter链变化
- 检测异常URL模式注册
-
行为监控
- 命令执行行为检测
- 异常网络连接监控
5.2 防护建议
-
权限控制
- 最小权限原则部署Tomcat
- 严格限制管理接口访问
-
安全加固
- 定期更新Tomcat版本
- 启用安全审计日志
-
运行时防护
- 使用RASP进行运行时保护
- 部署WAF进行请求过滤
六、总结
Tomcat Filter型内存马利用动态注册Filter的机制,通过精心构造的恶意Filter实现在内存中持久化驻留。理解Filter调用链的完整流程对于防御此类攻击至关重要。安全团队应重点关注运行时环境监控和异常行为检测,建立多层次防御体系。
关键记忆点:
- Filter链采用责任链模式,逐个调用
- 内存马成功的关键是控制Filter在链中的位置
- 防御需要结合静态检测和动态监控
- 最小权限原则是基础安全保障
本教学文档仅用于安全研究和技术学习,请遵守相关法律法规,勿用于非法用途。