首页 > 系统相关 >【蓝队】HW中盛行的Java内存马,如何全面检测?

【蓝队】HW中盛行的Java内存马,如何全面检测?

时间:2024-12-16 17:09:14浏览次数:7  
标签:Web Java 检测 蓝队 HW 内存 Class 加载

一、背景

1.1 Java内存马是什么?

内存马是一种仅在内存中运行、没有文件落地的恶意程序,因此具有较强的隐蔽性,能够避开常规的基于文件系统的检测。Java内存马是针对Java语言的内存马,它利用Java语言的动态特性,如类加载机制、动态代理和反射技术等,在Java应用的内存中注入恶意代码,从而实现远程控制。

1.2 Java类加载机制

Java虚拟机(JVM)的类加载机制在程序运行时根据需要动态地加载类,而不是在启动时一次性加载所有类。而类可以在运行时从不同的来源,如本地文件系统、远程网络或者其他自定义位置加载。攻击者可以利用这一特性,在运行时加载恶意类,从而向内存中引入不受信任的代码。

1.3 内存马检测的必要性

近年来,内存马因其持久性、隐蔽性、兼容性强等特性,已被攻击者广泛应用于各种复杂的攻击场景。内存马通过驻留在内存中,规避文件系统的监控,使得传统的杀毒软件和入侵检测系统难以发现其踪迹。因此,需要研究专门的内存马检测技术,以便及时发现并消除内存马带来的安全威胁,从而保障系统的安全性。

二、检测

Java程序的内存检测一般以Class字节码为维度进行,简单分为两个步骤:

1、读取内存中的Class信息

2、对Class信息进行分析检测

检测大纲:

2.1 Class信息获取

2.1.1 获取方式

1、Serviceability Agent (SA)

SA是JDK提供的一个强大的调试工具集,适用于语言层和虚拟机层,支持调试运行着的Java进程、core文件和虚拟机crash之后的dump文件。SA运行在单独的进程中,和目标Java进程是隔离的,在使用SA工具时,不会在目标Java进程中执行任何代码,但是,在SA读取数据的过程中,目标Java进程会被挂起。

通过sa-jdi.jar中sun.jvm.hotspot.tools.jcore.ClassDump类的方法接收进程id,能够把对应进程已加载的类全部读取出来。

代码示例:

2、Java Agent

Java Agent 是一种基于 Java Instrumentation API 的机制,可用于在 Java 应用程序运行时动态地修改其字节码。
Java Agent 提供了两个主要方法:

premain:在 Java 进程启动前加载。这个方法可以在实际类加载之前插入自定义的字节码操作逻辑。

agentmain:在 Java 进程启动后加载。这个方法可以在进程运行时对已加载的类进行操作,如读取、修改类字节码等操作。

通过VirtualMachine.attach(pid)方法,可以将当前进程附加到目标 JVM 实例,实现动态代码注入。

PS:冰蝎工具的防检测功能会删除/tmp/.java_pid文件,导致无法使用attach进行注入,可用SA方式替代。

正常进行attach以后,可使用agentmain方法注入到另一个进程中来实现内存信息获取。
代码示例:

2.1.2 获取内容

获取Java类的详细信息,主要关注以下几个字段:

类名(className):获取内存中加载的类的完整名称,有助于识别和追踪潜在的恶意类。
类加载器(classLoader):获取负责加载该类的类加载器,以了解其加载来源,并识别异常或不寻常的加载行为。
包名(packageName):获取类所属的包,以帮助判断类的组织结构和潜在的风险区域。
父类(parentClass):获取该类的父类,分析其继承关系,以发现可能隐藏的恶意代码。
类路径(classPath):获取类在文件系统中的位置,用于验证类的合法来源和检查潜在的篡改迹象。
接口(interfaces):获取该类实现的所有接口,了解其功能和行为契约,检测异常接口实现或恶意接口。
注解(annotations):获取类上的注解,识别可能影响类行为的元数据。
类字节码(classBytes):获取类的字节码内容,深入分析其实际实现,识别可能的恶意代码或不符合预期的行为。

2.2. Class信息检测

对获取到的Class信息进行检测,可以分为两个方面:
1、首先对Class进行筛选,识别风险类。

2、根据需求对全部类或者风险类的Class字节码内容进行检测。

2.2.1. Class风险类检测

1、 Web风险类检测

首先,根据不同内存马的分类来分析潜在的Web风险类

组件型内存马:仅需要针对内存中对应的Servlet、filter、Listener等组件进行分析即可。

JSP内存马:仅针对内存中实现HttpServlet的类进行分析即可。

agent型内存马:由于agent机制几乎可以改写内存中的任何类,可以hook的位置非常多,具体特征需跟着技术发展不断迭代更新。hook点一般都在Web调用的关键链路上。

虽然有各种各样的内存马,但他们通常都作用在Web调用的关键链路上,通过Web请求触发内存马,通过请求参数执行逻辑。

  1. Web调用链分析:

哪些调用链是Web调用的关键链路?

以springboot 的Web项目为例,处理Web请求的调用堆栈大概如下:

1、tomcat建立HTTP连接并添加读写事件的监听:

2、tomcat 收到请求数据包并放到线程池中处理数据包:

3、tomcat实际处理请求数据包:

实际应用场景中,hook点大概率会发生在tomcat实际处理请求数据包转http请求request之后。

从堆栈信息可以看出来,调用链路会经过tomcat的Valve组件,servlet的FilterChain及Filter组件,Servlet组件,以及springmvc的相关处理,进而执行到Controller的helloworld方法。

那是不是只要关注上述调用链路就可以了?

当然不是,每个方法里都会有其他代码逻辑,实际Web调用过程中会涉及的调用类远比上述调用链更多。

故光靠分析调用链,无法圈定需要内存分析的所有类,只能找出比较高危的类做重点分析。

  1. Web容器注册分析

为什么要做Web容器注册分析?

Web框架在进行Web调用处理时,一般分成两步:

1、程序启动时注册组件,即Web程序启动时定义好当收到请求时该交给哪个组件如何进行处理。

2、实际发生Web调用时,Web容器根据调用信息,找到对应的组件进行处理。

所以,我们可以通过读取Web容器的注册组件对应类进行内存分析,目标性更强,更精准。

此处介绍两种最常见的Web容器:tomcat和springmvc。

a) tomcat容器:

在使用tomcat作为Web容器时,可通过其核心对象StandardContext中获得filter、servlet、listener的注册信息。

获取的过程如下:

StandardContext --> filterConfigs,filterDefs --> filter

StandardContext --> servletMappings,children --> servlet

StandardContext --> applicationListeners,listeners --> listener

Valve也是tomcat中非常重要的组件,但valve是tomcat中内置的组件,正常情况下并不会进行自定义,只需要通过判断类实现Valve接口过滤即可。

而filter、servlet、listener是servlet规范中提供给开发者自定义的开放性组件,则更具有进一步通过容器注册分析的意义。

b) springmvc容器:

springmvc作为最常见的Web框架,其注册信息同样具备针对性分析的价值。

需要获取的注册信息:

springmvc中主要获取的是HandlerMethod对象和HandlerInterceptor对象信息。

  • 容器中注册的HandlerMethod对象表示请求的实际处理方法,表示springmvc中的controller对象和对应处理方法。
    
  • 容器中的HandlerInterceptor是开放的拦截器,springmvc提供了在请求处理前后进行自定义处理的机制。
    

如何获取注册信息:

先获取spring的容器组件ApplicationContext,再从中获取springmvc的核心组件DispatcherServlet,进而获取注册信息。
获取过程如下:

  • ApplicationContext --> DispatcherServlet --> List<HandlerMapping> handlerMappings --> AbstractHandlerMethodMapping.getHandlerMethods()
    
  • ApplicationContext --> DispatcherServlet --> List<HandlerMapping> handlerMappings --> AbstractHandlerMapping.adaptedInterceptors
    

在实际按照上述方式获取springmvc的注册信息时,可能会用到反射获取信息,且可能会不知道从哪获取最源头的ApplicationContext对象,进而无从下手。

最源头的ApplicationContext对象,一般需要从类的静态变量中获取。可通过内存分析ApplicationContext对象的引用关系,找到获取的链路。

获取方式举例如下:

2、Class基础信息检测

  1. classPath为空

通过分析classPath为空的类,排除已知的正常情况,剩下的类大概率为风险类

1、getProtectionDomain().getCodeSource()为空

这意味着该类没有关联的代码源信息。可能的原因包括:

  • 该类是 JVM 自带的类(例如,java.* 中的类),因为这些类是由 JVM 自身加载的,它们没有显式的代码源。
    
  • 该类是通过字节码操作动态生成的,或者是以非标准的方式加载的(如通过某些代理类或字节码工具动态生成)。
    
  • 该类是在 Java 运行时生成的,例如使用 Proxy、ClassLoader.defineClass() 等方法生成的类。
    

2、getClassLoader().getResource(className.replace(".", "/") + ".class")为空

这意味着类加载器无法找到与指定类对应的资源路径。可能的原因包括:

  • 类是由一个特定的类加载器加载的,但该类加载器不使用标准的路径查找机制(如 URLClassLoader 或自定义的 ClassLoader)。
    
  • 该类是通过内存中直接加载的方式(如字节码生成工具)加载的,而不是从文件系统或网络资源中获取的,因此找不到相应的类文件资源。
    
  • 类加载器因为安全限制或者其他原因,无法访问该类的实际存储位置。
    
  1. 关键字特征匹配

可以通过检测包名、类名、父类名、类加载器等类基础信息中是否包含诸如 shell、exploit 等可疑关键字,识别可能由内存马生成工具创建的恶意类。

冰蝎的包名以net.rebeyond.开头或带有Behinder关键字

哥斯拉的包名以core.shell.开头或带有Godzilla关键字

msf的包名以com.metasploit.开头

蚁剑带有AntSword关键字

...

2.2.2. Class字节码检测

通过检测Class基础信息方式识别内存马的方式仅对Class的一些表象特征进行分析,其优势在于消耗低,但容易被绕过。而内存马注入的恶意代码肯定是以Class字节码存在在内存之中,通过检查Class字节码内容是一种更直接的方式。

1、内存与磁盘字节码比对

读取已加载的字节码信息,和磁盘中的字节码信息进行比对。如果不一致,则为可疑类。

如果直接对Class的字节流进行比对,可能经常会误报,可以使用ASM工具将Class内容解析成属性和方法,再对每个属性和方法进行比对。

代码示例:

2、敏感代码调用检测

使用ASM工具解析Class字节码的方法,与敏感代码特征进行比对

高敏感的代码调用:

1、命令执行:

java.lang.Runtime#exec

java.lang.ProcessBuilder#start

java.lang.UNIXProcess#forkAndExec

...

2、JNI加载动态库:

java.lang.System#load

java.lang.Runtime#load

...

3、类加载:

java.lang.ClassLoader#defineClass

java.lang.reflect.Proxy#defineClass0

sun.misc.Unsafe#defineAnonymousClass

java.lang.invoke.MethodHandles.Lookup#defineHiddenClass

...

其他敏感代码调用:

获取系统信息

字节码生成类库

文件操作

编码加密

...

3、反射调用检测

由于Java语言开放和动态的特性,可通过反射等方式动态地调用上述的敏感代码,进而绕过正常的检测规则。

反射调用方式:

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

...

如何有效检测反射调用

有师傅提出用模拟栈帧的方式进行检测,但是模拟栈帧的方式开销大,同时只能将检测范围圈定在单个方法内,而反射调用的入参可能在其他方法中定义,甚至在Web请求参数中定义,故有一定的局限性。

由于反射的运行时确定的特性,可以通过运行时检测,修改字节码,在反射代码前插桩,判断反射的参数是否命中敏感代码调用,进而告警。
4、 Webshell引擎检测

将Class字节码反编译为Java文件后,交由成熟的Webshell检测引擎进行扫描。将反编译后的Class文件视作普通源代码进行检测,其核心依然是识别潜在的Webshell。通过这种方法,充分利用现有的检测技术,识别出隐藏在内存或代码中的恶意行为,进一步提升检测的准确性与效率。

三、总结

本文系统性地列举了Java内存马的检测方法,涵盖了从类的基本信息获取到字节码的深入检测。通过这些方法,能够有效识别内存马攻击。可根据不同场景或需求,在检测率与性能开销之间进行平衡,选择适合的检测方式,以实现最佳的检测效果。

然而,攻防对抗本质上是动态的,随着内存马技术的不断发展,新的攻击手段和技术也会不断涌现,现有的检测手段也可能会失效。因此,需要持续更新和调整检测策略,跟踪最新的攻击趋势和技术进展,不断搜集和优化检测特征,以提升系统的防御能力,降低安全风险。

来源:【干货 | HW中盛行的Java内存马,如何全面检测?- FreeBuf网络安全行业门户】

标签:Web,Java,检测,蓝队,HW,内存,Class,加载
From: https://www.cnblogs.com/o-O-oO/p/18610617

相关文章

  • 【华为OD-E卷-ai面板识别 100分(python、java、c++、js、c)】
    【华为OD-E卷-ai面板识别100分(python、java、c++、js、c)】题目AI识别到面板上有N(1≤N≤100)个指示灯,灯大小一样,任意两个之间无重叠。由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2,y2),请输出先行后......
  • JavaScript的对象相关概念
    当然可以,以下是将上述对话整理成Markdown格式的内容:JavaScript面向对象编程相关概念原型链(PrototypeChain)原型链是JavaScript中查找对象属性和方法的机制。它从对象的__proto__属性开始,向上逐层搜索直到找到属性或方法或到达Object.prototype。原型(Prototype)每个Java......
  • Java 基础学习路线
    一、环境搭建与入门(1-2周)安装Java开发工具包(JDK),配置环境变量,确保能够在命令行中正常运行Java命令。选择一款集成开发环境(IDE),如Eclipse或IntelliJIDEA,熟悉其基本操作,包括创建项目、编写代码、调试程序等。学习Java的基本语法,包括变量、数据类型(基本数据类型如in......
  • Java -chapter3控制语句
    1.switch语句switch(choice){case1->...case2->...case3->...case4->...default->System.out.println("Badinput");}case的类型charbyteshortint枚举enum字符串多个变量可用,分隔例:Stringinput=...;switch(inpu......
  • Java程序员面试1000问,花点耐心看完offer拿到手软
    前言:本文收集整理了各大厂常见面试题N道,你想要的这里都有内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、SpringBoot、SpringCloud、RabbitMQ、Kafka、Linux等技术栈,希望大家都能找到适合自己的公司,开开心心的撸代码。目录:......
  • 2025春招Java 面试必刷的1200 道Java大厂面试真题(含答案解析)
    2025春招即将来临,很多同学会问Java面试八股文有必要背吗?我的回答是:很有必要。你可以讨厌这种模式,但你一定要去背,因为不背你就进不了大厂。国内的互联网面试,恐怕是现存的、最接近科举考试的制度。而且,我国的八股文确实是独树一帜。以美国为例,北美工程师面试比较重视算法(Cod......
  • java中RSA加密解密的使用
    作为常用的非对称加密算法,本篇文章大致记录一下,在java代码中如何生成RSA的密钥对以及加密解密的使用。1、生成密钥对publicclassRSAUtils{//填充方式publicstaticfinalStringRSA_ALGORITHM_NOPADDING="RSA";publicstaticfinalStringRSA_ALGORITH......
  • 2024年金九银十版 Java 面试八股文教程,涵盖 25 大专题
    内卷可以说是2024年最火的一个词了。LZ在很多程序员网站看到很多Java程序员的2024年度总结都是:Java越来越卷了(手动狗头),2024年是被卷的一年。前有几百万毕业生虎视眈眈,后有在职人员带头“摸鱼”占着坑位,加上现在的行情让很多公司倒闭,市面上根本没那么多就业岗位。自然而......
  • JAVA面经汇总(2024全年整理)
    开始之前,先说一下我非常推荐的一种学习方式:带着问题学习或者准备面试。另外,准备面试的小伙伴,一定要根据自身情况制定好复习计划! 并且,你最好还要时不时自测一下,对着一些面试常见的问题进行自问。最近,我分析了上百份大中小厂的面经,发现了许多Java面试中最最最常问的一些......
  • 免费送源码:Java+springboot+MySQL springboot古诗文学习系统 计算机毕业设计原创定制
    摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,古诗文学习系统当然也不能排除在外。古诗文学习系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用springboot技术构建的一个管理系统。整个开发过......