干货 | HW中盛行的Java内存马,如何全面检测?
字数 2850 2025-08-20 18:17:59

Java内存马全面检测技术指南

1. Java内存马概述

1.1 内存马定义

  • 仅在内存中运行、没有文件落地的恶意程序
  • 利用Java语言的动态特性(类加载机制、动态代理和反射技术)注入恶意代码
  • 具有强隐蔽性,能避开基于文件系统的常规检测

1.2 Java类加载机制特性

  • JVM在运行时根据需要动态加载类
  • 类可从多种来源加载:本地文件系统、远程网络或自定义位置
  • 攻击者可利用此特性在运行时加载恶意类

1.3 检测必要性

  • 内存马具有持久性、隐蔽性和兼容性强的特点
  • 传统杀毒软件和入侵检测系统难以发现内存驻留的恶意代码
  • 需要专门的内存马检测技术保障系统安全

2. 检测方法论

Java程序内存检测以Class字节码为维度,分为两个主要步骤:

  1. 读取内存中的Class信息
  2. 对Class信息进行分析检测

3. Class信息获取技术

3.1 获取方式

3.1.1 Serviceability Agent (SA)

  • JDK提供的强大调试工具集
  • 支持调试运行中的Java进程、core文件和虚拟机dump文件
  • 运行在独立进程中,目标进程会被挂起但不执行任何代码
  • 使用sa-jdi.jar中的sun.jvm.hotspot.tools.jcore.ClassDump类读取进程所有已加载类

3.1.2 Java Agent

  • 基于Java Instrumentation API的机制
  • 两种主要方法:
    • premain:Java进程启动前加载
    • agentmain:Java进程启动后加载
  • 通过VirtualMachine.attach(pid)附加到目标JVM实例
  • 注意:冰蝎工具会删除/tmp/.java_pid文件阻止attach注入

3.2 获取内容

  • 类名(className)
  • 类加载器(classLoader)
  • 包名(packageName)
  • 父类(parentClass)
  • 类路径(classPath)
  • 接口(interfaces)
  • 注解(annotations)
  • 类字节码(classBytes)

4. Class信息检测技术

4.1 Class风险类检测

4.1.1 Web风险类检测

内存马分类:

  1. 组件型内存马:针对Servlet、Filter、Listener等组件
  2. JSP内存马:针对实现HttpServlet的类
  3. agent型内存马:hook点分布在Web调用关键链路

Web调用链分析(以Spring Boot为例):

  1. Tomcat建立HTTP连接并添加读写事件监听
  2. Tomcat收到请求数据包并放入线程池处理
  3. Tomcat实际处理请求数据包
    • 经过Tomcat的Valve组件
    • Servlet的FilterChain及Filter组件
    • Servlet组件
    • Spring MVC相关处理
    • 最终执行Controller方法

Web容器注册分析:

  1. Tomcat容器:

    • 通过StandardContext获取:
      • filterConfigs, filterDefs → Filter
      • servletMappings, children → Servlet
      • applicationListeners, listeners → Listener
  2. Spring MVC容器:

    • 获取ApplicationContextDispatcherServlet → 注册信息
    • 关键注册信息:
      • HandlerMethod对象(Controller方法)
      • HandlerInterceptor对象(拦截器)

4.1.2 Class基础信息检测

  1. classPath为空检测

    • getProtectionDomain().getCodeSource()为空
    • getClassLoader().getResource(className.replace(".", "/")+".class")为空
    • 可能指示动态生成的恶意类
  2. 关键字特征匹配

    • 常见工具特征:
      • 冰蝎:net.rebeyond.Behinder
      • 哥斯拉:core.shell.Godzilla
      • MSF:com.metasploit.
      • 蚁剑:AntSword

4.2 Class字节码检测

4.2.1 内存与磁盘字节码比对

  • 使用ASM工具解析Class内容为属性和方法
  • 逐项比对内存与磁盘中的字节码差异

4.2.2 敏感代码调用检测

  • 高敏感代码调用

    • 命令执行:
      • java.lang.Runtime#exec
      • java.lang.ProcessBuilder#start
      • java.lang.UNIXProcess#forkAndExec
    • JNI加载动态库:
      • java.lang.System#load
      • java.lang.Runtime#load
    • 类加载:
      • java.lang.ClassLoader#defineClass
      • java.lang.reflect.Proxy#defineClass0
      • sun.misc.Unsafe#defineAnonymousClass
      • java.lang.invoke.MethodHandles.Lookup#defineHiddenClass
  • 其他敏感调用

    • 获取系统信息
    • 字节码生成类库
    • 文件操作
    • 编码加密

4.2.3 反射调用检测

  • 常见反射调用方式

    • java.lang.reflect.Method#invoke
    • sun.reflect.NativeMethodAccessorImpl#invoke
    • jdk.internal.reflect.NativeMethodAccessorImpl#invoke0
    • java.lang.invoke.LambdaMetafactory#metafactory
    • java.lang.invoke.MethodHandle#invoke
    • java.lang.invoke.MethodHandle#invokeExact
    • java.lang.invoke.MethodHandle#invokeWithArguments
  • 检测方法

    • 运行时检测,修改字节码在反射代码前插桩
    • 判断反射参数是否命中敏感代码调用

4.2.4 Webshell引擎检测

  • 将Class字节码反编译为Java文件
  • 使用成熟的Webshell检测引擎扫描
  • 将反编译后的Class文件视作普通源代码检测

5. 总结与建议

  1. 检测策略选择

    • 根据场景需求在检测率与性能开销间平衡
    • 组合使用多种检测方法提高准确性
  2. 持续更新

    • 内存马技术不断发展,需持续更新检测特征
    • 跟踪最新攻击趋势和技术进展
  3. 防御建议

    • 定期进行内存检测
    • 监控异常类加载行为
    • 限制不必要的反射和动态类加载能力
    • 实施最小权限原则

本指南提供了全面的Java内存马检测技术框架,安全团队可根据实际环境需求选择和组合适当的检测方法,构建有效的防御体系。

Java内存马全面检测技术指南 1. Java内存马概述 1.1 内存马定义 仅在内存中运行、没有文件落地的恶意程序 利用Java语言的动态特性(类加载机制、动态代理和反射技术)注入恶意代码 具有强隐蔽性,能避开基于文件系统的常规检测 1.2 Java类加载机制特性 JVM在运行时根据需要动态加载类 类可从多种来源加载:本地文件系统、远程网络或自定义位置 攻击者可利用此特性在运行时加载恶意类 1.3 检测必要性 内存马具有持久性、隐蔽性和兼容性强的特点 传统杀毒软件和入侵检测系统难以发现内存驻留的恶意代码 需要专门的内存马检测技术保障系统安全 2. 检测方法论 Java程序内存检测以Class字节码为维度,分为两个主要步骤: 读取内存中的Class信息 对Class信息进行分析检测 3. Class信息获取技术 3.1 获取方式 3.1.1 Serviceability Agent (SA) JDK提供的强大调试工具集 支持调试运行中的Java进程、core文件和虚拟机dump文件 运行在独立进程中,目标进程会被挂起但不执行任何代码 使用 sa-jdi.jar 中的 sun.jvm.hotspot.tools.jcore.ClassDump 类读取进程所有已加载类 3.1.2 Java Agent 基于Java Instrumentation API的机制 两种主要方法: premain :Java进程启动前加载 agentmain :Java进程启动后加载 通过 VirtualMachine.attach(pid) 附加到目标JVM实例 注意:冰蝎工具会删除 /tmp/.java_pid 文件阻止attach注入 3.2 获取内容 类名(className) 类加载器(classLoader) 包名(packageName) 父类(parentClass) 类路径(classPath) 接口(interfaces) 注解(annotations) 类字节码(classBytes) 4. Class信息检测技术 4.1 Class风险类检测 4.1.1 Web风险类检测 内存马分类: 组件型内存马:针对Servlet、Filter、Listener等组件 JSP内存马:针对实现HttpServlet的类 agent型内存马:hook点分布在Web调用关键链路 Web调用链分析(以Spring Boot为例): Tomcat建立HTTP连接并添加读写事件监听 Tomcat收到请求数据包并放入线程池处理 Tomcat实际处理请求数据包 经过Tomcat的Valve组件 Servlet的FilterChain及Filter组件 Servlet组件 Spring MVC相关处理 最终执行Controller方法 Web容器注册分析: Tomcat容器: 通过 StandardContext 获取: filterConfigs , filterDefs → Filter servletMappings , children → Servlet applicationListeners , listeners → Listener Spring MVC容器: 获取 ApplicationContext → DispatcherServlet → 注册信息 关键注册信息: HandlerMethod 对象(Controller方法) HandlerInterceptor 对象(拦截器) 4.1.2 Class基础信息检测 classPath为空检测 : getProtectionDomain().getCodeSource() 为空 getClassLoader().getResource(className.replace(".", "/")+".class") 为空 可能指示动态生成的恶意类 关键字特征匹配 : 常见工具特征: 冰蝎: net.rebeyond. 或 Behinder 哥斯拉: core.shell. 或 Godzilla MSF: com.metasploit. 蚁剑: AntSword 4.2 Class字节码检测 4.2.1 内存与磁盘字节码比对 使用ASM工具解析Class内容为属性和方法 逐项比对内存与磁盘中的字节码差异 4.2.2 敏感代码调用检测 高敏感代码调用 : 命令执行: java.lang.Runtime#exec java.lang.ProcessBuilder#start java.lang.UNIXProcess#forkAndExec JNI加载动态库: java.lang.System#load java.lang.Runtime#load 类加载: java.lang.ClassLoader#defineClass java.lang.reflect.Proxy#defineClass0 sun.misc.Unsafe#defineAnonymousClass java.lang.invoke.MethodHandles.Lookup#defineHiddenClass 其他敏感调用 : 获取系统信息 字节码生成类库 文件操作 编码加密 4.2.3 反射调用检测 常见反射调用方式 : java.lang.reflect.Method#invoke sun.reflect.NativeMethodAccessorImpl#invoke jdk.internal.reflect.NativeMethodAccessorImpl#invoke0 java.lang.invoke.LambdaMetafactory#metafactory java.lang.invoke.MethodHandle#invoke java.lang.invoke.MethodHandle#invokeExact java.lang.invoke.MethodHandle#invokeWithArguments 检测方法 : 运行时检测,修改字节码在反射代码前插桩 判断反射参数是否命中敏感代码调用 4.2.4 Webshell引擎检测 将Class字节码反编译为Java文件 使用成熟的Webshell检测引擎扫描 将反编译后的Class文件视作普通源代码检测 5. 总结与建议 检测策略选择 : 根据场景需求在检测率与性能开销间平衡 组合使用多种检测方法提高准确性 持续更新 : 内存马技术不断发展,需持续更新检测特征 跟踪最新攻击趋势和技术进展 防御建议 : 定期进行内存检测 监控异常类加载行为 限制不必要的反射和动态类加载能力 实施最小权限原则 本指南提供了全面的Java内存马检测技术框架,安全团队可根据实际环境需求选择和组合适当的检测方法,构建有效的防御体系。