干货 | HW中盛行的Java内存马,如何全面检测?
字数 2850 2025-08-20 18:17:59
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→ FilterservletMappings,children→ ServletapplicationListeners,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#execjava.lang.ProcessBuilder#startjava.lang.UNIXProcess#forkAndExec
- JNI加载动态库:
java.lang.System#loadjava.lang.Runtime#load
- 类加载:
java.lang.ClassLoader#defineClassjava.lang.reflect.Proxy#defineClass0sun.misc.Unsafe#defineAnonymousClassjava.lang.invoke.MethodHandles.Lookup#defineHiddenClass
- 命令执行:
-
其他敏感调用:
- 获取系统信息
- 字节码生成类库
- 文件操作
- 编码加密
4.2.3 反射调用检测
-
常见反射调用方式:
java.lang.reflect.Method#invokesun.reflect.NativeMethodAccessorImpl#invokejdk.internal.reflect.NativeMethodAccessorImpl#invoke0java.lang.invoke.LambdaMetafactory#metafactoryjava.lang.invoke.MethodHandle#invokejava.lang.invoke.MethodHandle#invokeExactjava.lang.invoke.MethodHandle#invokeWithArguments
-
检测方法:
- 运行时检测,修改字节码在反射代码前插桩
- 判断反射参数是否命中敏感代码调用
4.2.4 Webshell引擎检测
- 将Class字节码反编译为Java文件
- 使用成熟的Webshell检测引擎扫描
- 将反编译后的Class文件视作普通源代码检测
5. 总结与建议
-
检测策略选择:
- 根据场景需求在检测率与性能开销间平衡
- 组合使用多种检测方法提高准确性
-
持续更新:
- 内存马技术不断发展,需持续更新检测特征
- 跟踪最新攻击趋势和技术进展
-
防御建议:
- 定期进行内存检测
- 监控异常类加载行为
- 限制不必要的反射和动态类加载能力
- 实施最小权限原则
本指南提供了全面的Java内存马检测技术框架,安全团队可根据实际环境需求选择和组合适当的检测方法,构建有效的防御体系。