内存马常见堆栈排查法

前置:Dump堆栈/线程快照

工具:jps

获取到现有的Java进程PID和进程名
使用 -l 展示PID和包名

工具:jstack

先获取到Java进程PID,使用jstack Dpid | grep -A Num Hpid(nid)

Dpid->十进制pid
Num->输出行
Hpid(nid)->十六进制pid,这里作为nid使用,nid为占用最大的线程号

工具:Memshell-scanner

https://github.com/c0ny1/java-memshell-scanner

获取Tomcat下的所有的存在的Servlet/Filter/Listener

可dump对应的class文件,可kill对应的Servlet/Filter/Listener

Servlet马

Servlet马的创建流程

  • 创建恶意Servlet
  • 用Wrapper对其进行封装
  • 添加封装后的恶意Wrapper到StandardContext的children当中
  • 添加ServletMapping将访问的URL和Servlet进行绑定

检测思路

获取servletPath / servletName / standardWrapper这些信息之后

  1. 通过Class.forName进行类的加载
  2. 获取对应servlet类的classloader
  3. 通过对应的classloader调用getResource方法获取源文件

如果没有获取到文件就认为其可能为内存马

Filter马

Filter马的创建流程

只需要设置filterMaps、filterConfigs、filterDefs就可以注入恶意的filter

  • filterMaps:一个HashMap对象,包含过滤器名字和URL映射
  • filterDefs:一个HashMap对象,过滤器名字和过滤器实例的映射
  • filterConfigs变量:一个ApplicationFilterConfig对象,里面存放了filterDefs

检测思路

思路大致相同,

  1. 遍历所有的filter
  2. 分别获取每一个filterfilterName / filterClass / filterClassLoaderName等等信息
  3. 最后在结果输出中,调用了classFileIsExists方法根据filterClass来判断是否存在有对应的filterClass的文件资源,有,则输出对应的path路径,没有,则说明可能为内存马

Listener马

Listener马的创建流程

  1. 首先获取到StardardContext对象
  2. 之后创建一个实现了ServletRequestListener 接口的监听器类
  3. 再然后通过调用StardardContext类的addApplicationEventListener方法进行Listener的添加

检测思路

与Fileter一致,获取信息,输出path

一个仍在爬山的人