### 内存马查杀思路

在查杀之前，首先要了解内存马的常见类型。它们通常可以分为以下几类：

- **Filter/Servlet 类型：** 攻击者通过向 Web 容器（如 Tomcat）动态注册恶意 Filter 或 Servlet，来实现持久化控制
- **Listener 类型：** 攻击者通过注册恶意 Listener，在特定事件发生时触发恶意代码
- **Java Agent/Instrumentation 类型：** 这种技术可以在不修改字节码的情况下，在 JVM 运行时对已加载的类进行修改，实现更隐蔽的注入

**第一步：何时打进来的？**

1. **流量分析：**监控 Web 服务器的流量。如果发现异常的 HTTP 请求，比如带有很多不寻常参数的请求，或者与正常业务逻辑不符的 URL 访问，都可能是内存马的征兆

   1.1 `http://your-app.com/shell.do?pwd=a1b2c3d4&cmd=whoami`

2. **日志分析：** 检查 Web 服务器（如 Tomcat）的访问日志。如果发现一些不寻常的请求，并且这些请求没有在正常的 Servlet 或 Controller 中找到对应的处理逻辑，那么很可能是内存马在处理这些请求

   2.1 检查 Tomcat 的 `access_log`，发现有对 `/static/12345.css` 的请求，但该文件并不存在于硬盘上。如果这个请求的返回状态码是 200，而不是预期的 404，那么很可能是一个 Filter 内存马在默默处理这个请求

3. **CPU/内存异常：**内存马通常会消耗额外的系统资源。如果 Web 服务器的 CPU 或内存使用率突然升高，并且没有对应的业务高峰，需要警惕

   3.1 在没有业务高峰的情况下，CPU 占用率持续飙升到 90% 以上，同时内存使用量也快速增长

4. **工具扫描：**使用专业的 Java 安全工具或 Agent 进行扫描

**第二步：内存马具体位置？**

1. 使用内存分析工具：jmap、Artha、BTrace/jfr

   1.1 **jmap：**使用 `jmap` 可以生成 Java 堆内存的 dump 文件。通过分析这个文件，可以找到异常的对象实例

   1.2 **Arthas：**Arthas是一款非常强大的 Java 诊断工具。它可以在不重启应用的情况下，定位和排查问题

   - 使用 **`sc`**（`search class`）命令查找可疑的类。例如，`sc -d org.apache.catalina.core.ApplicationContext` 可以查看 Web 容器的上下文
   - 使用 **`jad`**（`decompile`）命令反编译可疑的类，查看其代码逻辑
   - 使用 **`trace`** 和 **`watch`** 命令跟踪特定方法的调用，观察参数和返回值，判断是否有异常行为

   1.3 **BTrace/jfr：** 这些工具可以用于动态地跟踪 JVM 运行时行为，帮助你定位恶意代码的注入点

2. **检查 Web 容器注册表：**对于 Tomcat，可以检查其内部注册的 Filter、Servlet、Listener 等

   2.1 在 Tomcat 8 及更高版本中，可以通过 `org.apache.catalina.core.ApplicationContext` 类的 `filterConfigs`、`servletConfigs` 等字段，或者直接通过反射获取这些注册信息

3. **排查自定义 ClassLoader：**恶意代码可能会使用自定义的 `ClassLoader` 来加载恶意类，以绕过常规的类加载器

   3.1 可以通过 `jmap -clstats` 或者 Arthas 的 `classloader` 命令，查看 JVM 中存在的 `ClassLoader` 实例。如果发现一些不寻常的 `ClassLoader`，需要重点关注

**第三步：西内！！！**

1. **内存中直接删除：**使用 Arthas 等工具，可以通过命令直接移除恶意对象。例如，可以调用 `ApplicationContext` 的 `removeFilterDef`、`removeServletDef` 等方法，或者通过反射将恶意实例从注册表中移除

   1.1 `ognl '#context=@org.apache.catalina.core.ApplicationContext@ApplicationContext, #context.removeFilterDef("filter_12345"), #context.removeFilterMap("filter_12345")'`

2. **重启 Web 应用：**这是最直接也最彻底的清除方法。因为内存马是驻留在内存中的，重启应用会清空内存，所有恶意代码都会被清除

   2.2 找到 Java 进程 ID，使用 `kill -9 <pid>` 或者通过 Tomcat 的 `shutdown.sh` 脚本关闭，然后再通过 `startup.sh` 启动
