内存马排查与处置
内存马排查与处置
概述
内存马(Memory Shell)是一种无文件驻留的高级后门技术,攻击者将恶意代码直接注入到Web容器的内存中,不落地任何恶意文件到磁盘上,从而绕过传统的文件检测机制。由于内存马不依赖磁盘文件,传统的杀毒软件和文件监控工具往往无法检测,给应急响应带来了极大的挑战。
内存马技术最初在Java Web环境中被广泛使用,攻击者通过动态注册Servlet、Filter、Listener等方式在Tomcat等Web容器中植入后门。随着技术的发展,内存马已经扩展到PHP(PHP-FPM)、.NET(IIS)、Node.js等多种Web运行环境中。常见的内存马框架包括 Behinder(冰蝎)、Godzilla(哥斯拉)、AntSword(蚁剑)等WebShell管理工具都支持内存马注入。
在应急响应中,识别和清除内存马需要深入了解Web容器的内部机制,并借助专门的检测工具。本文将系统介绍内存马的原理、检测方法和处置流程。
核心概念
内存马工作原理
Java 内存马的核心机制是利用 Java 的反射(Reflection)和动态类加载能力,在运行时向 Web 容器中注册恶意组件。以 Tomcat 为例,攻击者通过以下步骤植入内存马:首先获取当前 Web 应用的 Context 对象,然后创建恶意的 Filter/Servlet/Listener 实例,最后通过反射调用容器内部 API 将其注册到组件链中。
具体实现方式包括:Filter 型内存马——注册一个恶意 Filter,拦截所有或特定URL的请求,通过特定参数触发后门逻辑;Servlet 型内存马——注册一个映射到特定URL的恶意Servlet;Listener 型内存马——注册一个恶意的 ServletRequestListener,在每个请求到达时执行恶意代码;Valve 型内存马——注册 Tomcat 的 Valve 组件,在请求管道的更底层拦截请求。
PHP 环境下的内存马通常利用 PHP-FPM 的进程模型,通过注入代码到 worker 进程的内存空间中实现持久化。攻击者可能利用 php-fpm 的 auto_prepend_file 或通过 PHP 扩展(extension)的方式注入恶意代码。
内存马检测工具
Arthas(阿里巴巴开源的Java诊断工具)是检测Java内存马最常用的工具。通过 sc *.class 命令可以搜索内存中加载的所有类,与正常的类列表对比发现异常类。使用 sm 命令查看类的方法列表,jad 命令反编译类的字节码进行分析。
针对 Tomcat 的专用检测工具:Java MemShell Scanner 可以通过遍历 Tomcat 内部的 FilterChain、Servlet 映射和 Listener 列表来发现异常注册的组件。类似工具还有 copagent(长亭科技开源的内存马检测工具)和 java-memshell-scanner。
通用检测方法:对比 Web 容器中当前注册的组件列表与应用配置文件(web.xml)中声明的组件列表,多出来的组件即为可疑的内存马。可以编写脚本通过 JMX(Java Management Extensions)接口获取容器的运行时信息。
排查步骤
第一步:使用 Arthas 连接到目标 JVM 进程。下载 arthas-boot.jar,通过 java -jar arthas-boot.jar <PID> 连接到目标 Java 进程。
第二步:排查 Filter 型内存马。使用 mbean Catalina:type=FilterChain,* 查看所有 FilterChain 信息,使用 sc *Filter* 搜索所有 Filter 相关的类。对比 Tomcat 的 web.xml 中定义的 Filter 列表,不在配置文件中的 Filter 即为可疑对象。
第三步:排查 Servlet 型内存马。使用 mbean Catalina:j2eeType=Servlet,* 查看所有注册的 Servlet。对比应用部署描述符中定义的 Servlet,识别未在配置中声明的异常 Servlet。
第四步:排查 Listener 型内存马。使用命令获取 Context 中注册的所有 ServletContextListener、ServletRequestListener 等,对比配置文件识别异常 Listener。
第五步:分析可疑类的代码。使用 jad <classname> 反编译可疑类的字节码,查看其源代码判断是否为恶意代码。关注类中是否包含命令执行(Runtime.exec、ProcessBuilder)、网络通信(Socket、URL)等高危操作。
PHP 内存马排查
PHP 内存马的排查需要关注以下方面:检查 PHP-FPM 的配置文件中是否被添加了 auto_prepend_file 或 auto_append_file 指令;查看 phpinfo() 输出中的 loaded extensions 列表,识别可疑的扩展文件;检查 /proc/<PHP-FPM-PID>/maps 查看进程内存映射中是否有异常的内存区域。
使用 php -m 查看已加载的PHP模块,对比正常环境的模块列表。对于可疑的 .so 扩展文件,使用 readelf 分析其符号表和导入导出信息。
处置与防护
清除内存马:对于通过漏洞注入的内存马,重启Web容器即可清除内存中的恶意代码。但更重要的是修补被利用的漏洞(通常是RCE漏洞),否则攻击者可以重新注入。在紧急情况下,可以通过 Arthas 的 mc(内存编译)和 retransform 命令热卸载恶意类。
长期防护措施:部署 RASP(Runtime Application Self-Protection)实现运行时的内存马检测和阻断;使用 Java Agent 技术在类加载阶段进行安全检查;定期对 Web 容器进行内存马扫描;及时修补 Web 应用和中间件漏洞。
实战要点
- 内存马排查要趁早:内存马在进程重启后会自动消失,如果在排查过程中重启了服务,将丢失取证样本。因此在重启之前,务必使用 Arthas 等工具完成内存马的分析和取证。
- 关注类加载路径:内存马的类通常不是从正常的 JAR 包或 classes 目录加载的,而是通过自定义的 ClassLoader 或字节数组动态加载。在 Arthas 中使用
sc -d <classname>查看类的来源 ClassLoader,可以帮助判断是否为恶意类。 - 结合流量分析:内存马通常通过特定的 HTTP 参数或 Header 触发后门功能。通过流量分析可以发现这些特征请求,例如请求中包含特定的 Cookie 值、自定义 Header 或特定的参数名。
- 检查 Agent 注入:某些内存马通过 Java Agent 机制(
-javaagent参数)在 JVM 启动时注入。检查 Java 进程的启动参数中是否包含可疑的 agent jar 文件,以及/proc/<PID>/maps中是否有可疑的共享库映射。 - 建立内存组件白名单:在正常运行状态下,记录 Web 容器中所有合法的 Filter、Servlet、Listener 组件列表作为白名单,后续排查时与白名单对比可以快速发现异常。
总结
内存马作为一种高级的无文件攻击技术,对传统的安全检测手段提出了新的挑战。应对内存马威胁需要深入理解 Web 容器的内部机制,掌握 Arthas 等专业检测工具的使用方法,并建立常态化的内存组件监控机制。随着内存马技术在多种语言和平台上的扩展,安全人员需要持续跟踪最新的攻击手法和检测技术,才能有效应对这一威胁。