ServletListenerFilter内存马查杀手段一
字数 2310 2025-08-10 20:35:59

Tomcat内存马查杀技术详解

前言

本文详细分析基于Servlet、Filter和Listener类型内存马的查杀技术,重点讲解c0ny1开发的java-memshell-scanner工具的实现原理。该工具主要通过检测Tomcat容器中动态注册的组件是否存在于classpath来判断是否为内存马。

内存马查杀核心原理

总体思路

  1. 获取Tomcat容器中所有存在的Servlet、Filter和Listener
  2. 检查这些组件对应的类文件是否存在于服务器classpath中
  3. 如果类文件不存在,则判定为潜在的内存马
  4. 提供dump和kill功能对可疑组件进行处理

Servlet内存马查杀

关键检测方法

  1. getChildren方法

    • 从HttpServletRequest对象获取StandardContext类对象
    • 获取StandardContext的children属性(ContainerBase类属性)
    • 这些子容器是Servlet到StandardWrapper的映射
  2. getServletMaps方法

    • 从StandardContext对象获取servletMappings属性
    • 这些是路由(router)到servletName的映射

检测流程

  1. 遍历所有存在的路由
  2. 获取每个路由对应的:
    • servletPath
    • servletName
    • standardWrapper
  3. 通过Class.forName加载类
  4. 获取servlet类的classloader
  5. 通过classloader.getResource获取源文件
  6. 如果无法获取源文件,判定为潜在内存马

内存马注入流程对比

  1. 创建恶意Servlet
  2. 用Wrapper封装
  3. 将Wrapper添加到StandardContext的children中
  4. 添加ServletMapping绑定URL和Servlet
  5. 结果:
    • 恶意Wrapper进入children属性
    • 路由映射进入servletMappings属性

Filter内存马查杀

关键检测方法

  1. getFilterConfig方法

    • 获取StandardContext的filterConfigs属性
    • 这是filterName到ApplicationFilterConfig的映射
    • ApplicationFilterConfig包含filterName、filterClass等配置信息
  2. getFilterMaps方法

    • 获取StandardContext的filterMaps属性
    • 包含应用程序的过滤器映射集

检测流程

  1. 遍历所有filter
  2. 获取每个filter的:
    • filterName
    • filterClass
    • filterClassLoaderName
  3. 调用classFileIsExists方法检查filterClass对应的资源文件
  4. 无对应文件则判定为潜在内存马

内存马注入流程对比

  1. 需要设置三个关键结构:
    • filterMaps:过滤器名字和URL映射
    • filterDefs:过滤器名字和过滤器实例的映射
    • filterConfigs:ApplicationFilterConfig对象,包含filterDefs

Listener内存马查杀

关键检测方法

getListenerList方法

  • 获取StandardContext的applicationEventListenersList属性
  • 包含application event listener列表

检测流程

  1. 获取所有listener
  2. 筛选ServletRequestListener实现类作为检测目标
  3. 检查这些listener类是否存在对应的资源文件

局限性

  1. 仅检测ServletRequestListener实现类
  2. 其他类型监听器(如ServletContextListener)可能被绕过
  3. 存在检测不全的风险

内存马注入流程对比

  1. 获取StandardContext对象
  2. 创建ServletRequestListener接口实现类
  3. 调用StandardContext.addApplicationEventListener方法添加Listener

查杀功能实现

dump功能

  • 通过Repository.lookupClass方法获取指定类
  • 将类内存写入response body返回

kill功能

Servlet型内存马删除

  1. 通过反射调用StandardContext.removeServletMapping删除路由映射
  2. 通过反射调用StandardContext.removeChild删除Wrapper对象

Filter型内存马删除

  1. 获取FilterDef对象后,反射调用removeFilterDef方法
    • 删除过滤器名字和过滤器实例的映射
  2. 获取FilterMap对象后,反射调用removeFilterMap方法
    • 删除过滤器名字和URL映射

技术局限性

  1. 检测方法局限

    • 仅通过类文件存在性判断
    • 无法判断类文件的实际危害性
    • 存在漏报和误报风险
  2. Listener检测不全

    • 仅检测ServletRequestListener实现类
    • 其他类型监听器可能被绕过
  3. 绕过可能性

    • 攻击者可能将恶意类伪装成合法类
    • 通过其他类型组件注入内存马

总结

该内存马查杀工具主要通过以下方式工作:

  1. 获取Tomcat容器中动态注册的组件
  2. 检查这些组件对应的类文件是否存在
  3. 对可疑组件提供dump和kill功能

虽然该方法能有效检测常见内存马,但仍存在检测不全和可能被绕过的风险。在实际应用中,应结合行为分析、流量监控等多种手段进行综合防御。

Tomcat内存马查杀技术详解 前言 本文详细分析基于Servlet、Filter和Listener类型内存马的查杀技术,重点讲解c0ny1开发的java-memshell-scanner工具的实现原理。该工具主要通过检测Tomcat容器中动态注册的组件是否存在于classpath来判断是否为内存马。 内存马查杀核心原理 总体思路 获取Tomcat容器中所有存在的Servlet、Filter和Listener 检查这些组件对应的类文件是否存在于服务器classpath中 如果类文件不存在,则判定为潜在的内存马 提供dump和kill功能对可疑组件进行处理 Servlet内存马查杀 关键检测方法 getChildren方法 : 从HttpServletRequest对象获取StandardContext类对象 获取StandardContext的children属性(ContainerBase类属性) 这些子容器是Servlet到StandardWrapper的映射 getServletMaps方法 : 从StandardContext对象获取servletMappings属性 这些是路由(router)到servletName的映射 检测流程 遍历所有存在的路由 获取每个路由对应的: servletPath servletName standardWrapper 通过Class.forName加载类 获取servlet类的classloader 通过classloader.getResource获取源文件 如果无法获取源文件,判定为潜在内存马 内存马注入流程对比 创建恶意Servlet 用Wrapper封装 将Wrapper添加到StandardContext的children中 添加ServletMapping绑定URL和Servlet 结果: 恶意Wrapper进入children属性 路由映射进入servletMappings属性 Filter内存马查杀 关键检测方法 getFilterConfig方法 : 获取StandardContext的filterConfigs属性 这是filterName到ApplicationFilterConfig的映射 ApplicationFilterConfig包含filterName、filterClass等配置信息 getFilterMaps方法 : 获取StandardContext的filterMaps属性 包含应用程序的过滤器映射集 检测流程 遍历所有filter 获取每个filter的: filterName filterClass filterClassLoaderName 调用classFileIsExists方法检查filterClass对应的资源文件 无对应文件则判定为潜在内存马 内存马注入流程对比 需要设置三个关键结构: filterMaps:过滤器名字和URL映射 filterDefs:过滤器名字和过滤器实例的映射 filterConfigs:ApplicationFilterConfig对象,包含filterDefs Listener内存马查杀 关键检测方法 getListenerList方法 : 获取StandardContext的applicationEventListenersList属性 包含application event listener列表 检测流程 获取所有listener 筛选ServletRequestListener实现类作为检测目标 检查这些listener类是否存在对应的资源文件 局限性 仅检测ServletRequestListener实现类 其他类型监听器(如ServletContextListener)可能被绕过 存在检测不全的风险 内存马注入流程对比 获取StandardContext对象 创建ServletRequestListener接口实现类 调用StandardContext.addApplicationEventListener方法添加Listener 查杀功能实现 dump功能 通过Repository.lookupClass方法获取指定类 将类内存写入response body返回 kill功能 Servlet型内存马删除 : 通过反射调用StandardContext.removeServletMapping删除路由映射 通过反射调用StandardContext.removeChild删除Wrapper对象 Filter型内存马删除 : 获取FilterDef对象后,反射调用removeFilterDef方法 删除过滤器名字和过滤器实例的映射 获取FilterMap对象后,反射调用removeFilterMap方法 删除过滤器名字和URL映射 技术局限性 检测方法局限 : 仅通过类文件存在性判断 无法判断类文件的实际危害性 存在漏报和误报风险 Listener检测不全 : 仅检测ServletRequestListener实现类 其他类型监听器可能被绕过 绕过可能性 : 攻击者可能将恶意类伪装成合法类 通过其他类型组件注入内存马 总结 该内存马查杀工具主要通过以下方式工作: 获取Tomcat容器中动态注册的组件 检查这些组件对应的类文件是否存在 对可疑组件提供dump和kill功能 虽然该方法能有效检测常见内存马,但仍存在检测不全和可能被绕过的风险。在实际应用中,应结合行为分析、流量监控等多种手段进行综合防御。