网络安全是数字时代的基石,但学习过程中必须严守法律红线。‌
根据《中华人民共和国网络安全法》《数据安全法》等法律法规,任何未经授权的网络测试、数据访问或攻击行为均属违法。本文所有技术讨论与实例均基于‌合法授权的靶场环境‌(如Metasploitable、DVWA、Hack The Box等),严禁将文中方法应用于真实系统或非授权场景
网络安全学习应以提升防御能力为目标,而非成为攻击工具。

写在前边:此文章现在看不懂没关系,后边的内容是重点,最后再回头看这个文章,会用茅塞顿开来形容。

一、相关名词解释

1、JVM

JVM 是 ‌Java Virtual Machine‌(Java 虚拟机)的缩写,它是一种‌抽象化的计算机‌,也是 Java 实现“一次编写,到处运行”的核心基石。

简单来说,JVM 就像是一个“翻译官”或“中间层”。我们写的 Java 源代码(.java 文件)会被编译成一种特殊的中间代码——字节码(.class 文件)。JVM 的工作就是读取并“翻译”这些字节码,把它们变成特定操作系统(Windows、Linux、macOS 等)能够理解和执行的机器指令。

JVM 的核心价值
  1. 跨平台性‌
    这是 JVM 最广为人知的特点。只要在不同的操作系统上安装了对应版本的 JVM,同一份 Java 字节码就可以不加修改地在任何平台上运行。开发者不需要为每个操作系统单独编译一份程序。

  2. 自动内存管理(垃圾回收)‌
    JVM 会自动管理内存的分配和回收,程序员不再需要手动释放内存,大大降低了内存泄漏和程序崩溃的风险。JVM 提供了多种垃圾回收算法(如 Serial GC、Parallel GC、G1 GC、ZGC 等),可以根据不同场景灵活选择。

  3. 安全沙箱‌
    JVM 为 Java 程序提供了一个受控的运行环境,能够有效隔离恶意代码,防止其损害底层操作系统。
    JVM 的核心组成部分

JVM 的内部结构

JVM 的内部结构主要包含以下几个关键模块:

组件 作用
类加载器(Class Loader)‌ 负责查找并加载 .class 字节码文件到 JVM 内存中
运行时数据区‌ JVM 的内存管理区域,包含堆(存放对象)、方法区(存放类元数据)、虚拟机栈、程序计数器、本地方法栈
执行引擎‌ 负责解释或编译执行字节码,包含解释器和 JIT 即时编译器(将热点代码编译成本地机器码以提升性能)
本地方法接口(JNI)‌ 允许 Java 调用 C/C++ 等语言编写的本地方法库
JVM、JRE、JDK 的关系

这三者经常被放在一起提及,它们的包含关系如下:

‌JVM‌:Java 虚拟机本身,负责执行字节码。
‌JRE‌(Java Runtime Environment):Java 运行环境,包含 ‌JVM‌ + Java 核心类库,是运行 Java 程序的必备条件。
‌JDK‌(Java Development Kit):Java 开发工具包,包含 ‌JRE‌ + 开发工具(如编译工具 javac、调试工具等),是开发 Java 程序的必备条件。

可以这样理解:‌JDK 是工具箱,JRE 是运行平台,JVM 则是这个平台最核心的发动机。

2、 ‌Attach

Java 的 Attach 机制,是 JDK 提供的一套允许外部进程动态连接到正在运行的 JVM 并注入代理程序的技术方案。它解决了 Java Agent 只能在 JVM 启动时通过 -javaagent 参数加载的限制,让开发者可以在程序运行期间随时进行诊断、监控和调试。

核心 API

Attach API 不是 Java 的标准 API,而是 Sun 公司提供的一套扩展 API,位于 com.sun.tools.attach 包中,主要包含两个类:

类名 作用
VirtualMachine 代表一个目标 JVM,提供 JVM 枚举、Attach 动作(连接)、加载代理、Detach 动作(断开连接)等核心操作
VirtualMachineDescriptor 描述虚拟机的容器类,配合 VirtualMachine 完成各种功能,如列出所有正在运行的 JVM 进程
工作流程

Attach 机制的运行流程大致分为以下几个步骤:

  1. 发现目标 JVM‌:Attach 进程首先需要找到目标 JVM。这通常通过操作系统的进程列表来实现,jps 命令就是基于这个原理工作的。
  2. 建立连接‌:Attach 进程使用 Attach API 向目标 JVM 发送 Attach 请求。这个请求实际上是一个‌本地 Socket 连接‌,目标 JVM 会监听特定的 Socket 地址来接收请求。
  3. 加载 Agent‌:目标 JVM 接收到 Attach 请求后,会加载一个特殊的 Agent,这个 Agent 负责处理 Attach 进程发送的各种命令。在 Linux/Unix 系统上通常是 sun.tools.attach.BsdVirtualMachine,在 Windows 系统上则是 sun.tools.attach.WindowsVirtualMachine
  4. 执行命令‌:Attach 进程通过 Agent 向目标 JVM 发送各种命令,例如加载 JDWP Agent、获取 JVM 信息、执行线程转储等。
  5. 触发 agentmain‌:如果 Attach 进程请求加载自定义的 Agent JAR 包,目标 JVM 会执行该 JAR 包中指定的 agentmain 方法,从而完成字节码增强、类重定义等操作。
底层原理

Attach 机制的实现依赖于底层的操作系统 API。例如在 Linux 上,它使用 ptrace 系统调用来访问目标进程的内存空间。当外部进程发起 Attach 请求时,操作系统层面的信号机制会通知目标 JVM,目标 JVM 内部的 ‌Attach Listener‌ 线程会被唤醒并处理后续命令。

与 premain 的对比

Java Agent 有两种加载方式,Attach 机制对应的是动态加载模式:

对比维度 premain(静态加载) agentmain(动态加载)
加载时机 JVM 启动时,在应用程序 main 方法执行之前 JVM 运行期间,随时可以触发
启动方式 通过 -javaagent 参数指定 通过 Attach API 动态附着
典型场景 APM 监控探针、代码覆盖率工具 远程调试、线上诊断(Arthas)、热部署
是否需要重启 需要重启应用 不需要重启应用
主要应用场景

Attach 机制凭借“无需重启”的优势,被广泛应用于以下场景:

  • 远程调试‌:通过动态加载 JDWP Agent,实现本地 IDE 对远端服务器程序的断点调试。
  • 性能诊断‌:Arthas、VisualVM 等工具通过 Attach 连接到目标 JVM,实时采集线程状态、内存使用等性能数据。
  • 热更新与热部署‌:在不重启服务的情况下,动态修改类定义或替换字节码。
  • 安全测试‌:在授权环境中,通过 Attach 注入 Agent 型内存马进行渗透测试。

Attach 机制让 JVM 从一个封闭的运行环境变成了一个可被动态观测和干预的开放平台,极大地扩展了 Java 应用的可维护性和可调试性

3、Java Agent

Java Agent 是一种在 JVM 启动或运行时,对 Java 程序进行字节码修改和监控的探针技术‌。它可以在不改变原有代码的情况下,实现对程序行为的增强、监控或调试,常用于性能监控、日志埋点、热部署等场景。

核心原理

Java Agent 通过 JVM 提供的 Instrumentation API,在类加载或运行时动态修改字节码,实现类似 AOP(面向切面编程)的效果。它有两种加载方式:

  • 静态加载‌:通过 -javaagent:jar路径 参数在 JVM 启动前加载,执行 premain 方法。
  • 动态加载‌:在 JVM 运行中通过 Attach API 动态注入,执行 agentmain 方法。
典型应用场景
  1. 开发工具支持‌:如 IDEA、Eclipse 的调试功能。
  2. 热部署工具‌:如 JRebel,实现代码修改后无需重启应用。
  3. 线上诊断工具‌:如阿里开源的 Arthas、Skywalking 等。
  4. 性能监控与追踪‌:如 APm 探针、Prometheus 监控集成。
如何使用
  1. 编写一个包含 premainagentmain 方法的类。
  2. MANIFEST.MF 文件中指定 Premain-ClassAgent-Class
  3. 将其打包为 JAR 文件,并通过 -javaagent 参数启动目标程序。

二、Java内存马的表象

webshell可以正常访问,并且从log日志中可以看到webshell的访问状态码为200,但是在对应的目录中却找不到文件。如果存在此类情况,可以判断服务器中了内存马。

三、实现禁止Attach JVM的原理

禁止 JVM Attach 机制的核心原理是通过 JVM 启动参数 -XX:+DisableAttachMechanism 控制内部线程的初始化逻辑,从而阻断外部进程与目标 JVM 建立通信通道。

​ JVM 的 Attach 机制依赖于两个关键线程:“Signal Dispatcher”和“Attach Listener”。其中,“Signal Dispatcher”线程在 JVM 启动时始终创建,负责监听操作系统信号;而“Attach Listener”线程负责处理具体的 Attach 请求(如线程 dump、加载 Agent 等),它默认不会在启动时立即创建,而是由“Signal Dispatcher”在接收到特定信号后懒加载创建,或者通过参数 StartAttachListener 强制在启动时创建。

​ 当设置 -XX:+DisableAttachMechanism 参数时,JVM 在初始化阶段会检查该标志位。如果该标志位为 true,JVM 将跳过“Attach Listener”线程的初始化代码,既不会在启动时创建该线程,也不会允许“Signal Dispatcher”在后续运行时创建它。由于缺少了处理 Attach 命令的核心线程,外部工具(如 jstack、jmap、Arthas 等)即使通过文件 Socket 或信号机制尝试连接目标 JVM,也无法得到响应或执行任何操作,从而实现了禁止 Attach 的效果。

​ 此外,从 JDK 9 开始,为了增强安全性,默认配置进一步收紧,不仅可以通过上述参数完全禁用 Attach 机制,还默认禁止了动态加载 Agent(即 Attach API 中的 load 命令),除非显式启用 -XX:+EnableDynamicAgentLoading。这种设计旨在防止恶意代码通过 Attach 机制动态注入 JVM,提升了平台的安全性。

四、禁止Attach JVM情况下如何分析

1、还原被删除的Agent库文件(jar文件)

为防止被监控到,冰蝎 Agent 内存马会删除 /tmp/.java_pid4233 文件,该文件为AttachJVM时产生的socket文件。

可以使用命令恢复文件

ls -la /proc/4233/fd/ | grep deleted | grep /tmp

然后通过日志查看,反向找到 冰蝎 源码

2、内存dump分析-MAT工具

将内存dump文件拖入MAT工具,打开dominator_tree 。搜索相关关键字:rebeyond

内存dump分析-关键词

# 强制导出目标 JAVA 进程 22868 的堆内存转储
jmap -F -dump:format=b,file=heap.hprof 22868 
jcmd 22868 GC.heap_dump /tmp/heap.hprof
# 查看堆栈中可疑类和方法
yum install binutils 

# 1. 关键字简单分析 JAVA Heap 
# "POST /memshell HTTP/1.1" 
strings heap.bin | grep "POST /" 
strings heap.bin | grep -E "/webapps/.*?\!" |sort -u 
# 已知 memshell 特征
# fastjson 反序列化 classloader 
strings heap.bin | grep 'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader' 
# behinder 
strings heap.bin | grep -i 'rebeyond\|behinder\|Agent Injected Successfully\|MemShell' 
# n1ntyfilter 
strings heap.bin | grep -i 'inject n1ntyfilter injected' 
# msf 
strings heap.bin | grep 'com.metasploit.' 

# 查找执行过的可疑 jsp 代码
# 寻找已知的恶意代码模式,如动态执行 Bash 命令、动态注册 /shell 路径、以及反射加载和解密操作。
strings heap.bin | grep -i 'new ProcessBuilder("/bin/bash","-c", req.getParameter("\|Runtime.getRuntime().exec(\|standardCtx.addServletMapping("/shell\|.getClass().getClassLoader()).g(c.doFinal(' 
# 寻找所有与进程执行、加密库和 Spring 映射机制相关的痕迹
strings heap.bin|grep -i 'javax.crypto.\|ProcessBuilder\|getRuntime\|ProcessImpl\|shell\|org.springframework.web.servlet.handler.AbstractHandlerMapping' 

# 查找最近可疑访问记录
strings heap.bin | grep '\b\(whoami\|pwd\|ps\|netstat\)\b'
Logo

更多推荐