Java内存攻击技术漫谈
字数 1644 2025-08-05 00:15:28

Java内存攻击技术深入解析

前言

Java技术栈漏洞已成为Web安全领域的主流战场。随着防御系统的升级,Java攻防阵地已从磁盘转移到内存层面。本文将全面解析Java内存攻击技术,包括绕过安全限制、内存马防检测、远程进程注入等高级技术。

allowAttachSelf绕过技术

背景

Java 9+默认禁止SelfAttach,通过jdk.attach.allowAttachSelf参数控制,默认为false。

绕过原理

  1. HotSpotVirtualMachine类初始化时会读取VM启动参数并保存到静态属性ALLOW_ATTACH_SELF
  2. 该属性为静态,可通过反射修改

POC实现

Class cls = Class.forName("sun.tools.attach.HotSpotVirtualMachine");
Field field = cls.getDeclaredField("ALLOW_ATTACH_SELF");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.setBoolean(null, true);

内存马防检测技术

内存马分类

  1. Agent型:利用instrument机制修改现有类执行逻辑,JVM层注入,通用性强
  2. 非Agent型:新增Web组件(Servlet/Filter等),依赖容器环境,通用性弱

检测方法

  1. 反射检测:检测新增类和对象,无法检测Agent型
  2. instrument检测:通过attach注入检测逻辑,可检测所有类型

防检测原理

破坏instrument机制使检测工具无法attach:

Windows平台

  1. Hook jvm.dll中的JVM_EnqueueOperation_JVM_EnqueueOperation@20函数
  2. 使用JNI修改函数入口为直接返回
unsigned char buf[] = "\xc2\x14\x00"; // 32位直接返回
HINSTANCE hModule = LoadLibrary(L"jvm.dll");
LPVOID dst = GetProcAddress(hModule, "_JVM_EnqueueOperation@20");
DWORD old;
VirtualProtectEx(GetCurrentProcess(), dst, 3, PAGE_EXECUTE_READWRITE, &old);
WriteProcessMemory(GetCurrentProcess(), dst, buf, 3, NULL);

Linux平台

删除UNIX Domain Socket文件破坏IPC通信

Java原生远程进程注入

Windows平台实现

  1. Java的instrument在Windows平台会使用CreateRemoteThread启动stub线程
  2. 该线程执行体在客户端生成,作为字节数组传递

POC示例

Class cls = Class.forName("sun.tools.attach.WindowsVirtualMachine");
Method m = cls.getDeclaredMethod("enqueue", long.class, byte[].class, String.class, String.class, Object[].class);
byte[] shellcode = {...}; // 弹计算器的shellcode
m.invoke(null, -1L, shellcode, "test", "test", new Object[]{});

特点:利用合法签名的Java.exe进程注入,天然免杀

自定义类调用系统Native库函数

技术要点

  1. 自定义sun.tools.attach.VirtualMachineImpl
  2. 绕过类加载双亲委托机制,直接defineClass
  3. Native函数调用时只检查类限定名,不检查ClassLoader

实现示例

public class WindowsVirtualMachine {
    static native void enqueue(long hProcess, byte[] stub, String cmd, String pipename, Object... args);
    // ...
}

无文件落地Agent型内存马植入

可行性分析

传统Agent型内存马需要agent文件落地,新方法通过伪造JPLISAgent对象实现无文件注入

技术实现

  1. Native内存操作:使用Unsafe类分配和操作堆外内存
  2. JPLISAgent结构分析
    • 包含mNormalEnvironment成员指向JVMTIEnv
    • mRedefineAvailable必须设为true
  3. 定位JVMTIEnv
    • 通过内存搜索找到jvm模块基址
    • 计算固定偏移量获取JVMTIEnv地址

完整POC关键步骤

  1. 使用Unsafe分配内存伪造JPLISAgent
  2. 构造InstrumentationImpl实例
  3. 调用redefineClasses修改目标类

Java跨平台任意Native代码执行

技术原理

  1. 伪造jvmtienv对象,覆盖函数指针
  2. allocate函数指针位于jvmtienv+0x168偏移处
  3. 覆盖该指针指向shellcode

绕过防护

  1. 绕过DEP:将shellcode写入JIT区域(RWX)
  2. 绕过ASLR
    • 方法1:指针指纹匹配
    • 方法2:内存搜索定位JIT区域

完整流程

  1. 搜索内存定位可执行区域
  2. 布置伪造的jvmtienv对象
  3. 覆盖allocate函数指针
  4. 触发redefineClasses执行shellcode

小结

本文详细介绍了多种Java内存攻击技术:

  1. allowAttachSelf绕过技术
  2. 内存马防检测的跨平台实现
  3. 原生远程进程注入技术
  4. 无文件Agent型内存马植入
  5. 跨平台任意Native代码执行

这些技术可用于高级攻防场景,同时也提醒防御方需要加强内存层面的防护。测试环境为Win10/Ubuntu+Java 1.8.0_301/271_x64。

Java内存攻击技术深入解析 前言 Java技术栈漏洞已成为Web安全领域的主流战场。随着防御系统的升级,Java攻防阵地已从磁盘转移到内存层面。本文将全面解析Java内存攻击技术,包括绕过安全限制、内存马防检测、远程进程注入等高级技术。 allowAttachSelf绕过技术 背景 Java 9+默认禁止SelfAttach,通过 jdk.attach.allowAttachSelf 参数控制,默认为false。 绕过原理 HotSpotVirtualMachine 类初始化时会读取VM启动参数并保存到静态属性 ALLOW_ATTACH_SELF 该属性为静态,可通过反射修改 POC实现 内存马防检测技术 内存马分类 Agent型 :利用instrument机制修改现有类执行逻辑,JVM层注入,通用性强 非Agent型 :新增Web组件(Servlet/Filter等),依赖容器环境,通用性弱 检测方法 反射检测 :检测新增类和对象,无法检测Agent型 instrument检测 :通过attach注入检测逻辑,可检测所有类型 防检测原理 破坏instrument机制使检测工具无法attach: Windows平台 Hook jvm.dll 中的 JVM_EnqueueOperation 和 _JVM_EnqueueOperation@20 函数 使用JNI修改函数入口为直接返回 Linux平台 删除UNIX Domain Socket文件破坏IPC通信 Java原生远程进程注入 Windows平台实现 Java的instrument在Windows平台会使用 CreateRemoteThread 启动stub线程 该线程执行体在客户端生成,作为字节数组传递 POC示例 特点:利用合法签名的Java.exe进程注入,天然免杀 自定义类调用系统Native库函数 技术要点 自定义 sun.tools.attach.VirtualMachineImpl 类 绕过类加载双亲委托机制,直接defineClass Native函数调用时只检查类限定名,不检查ClassLoader 实现示例 无文件落地Agent型内存马植入 可行性分析 传统Agent型内存马需要agent文件落地,新方法通过伪造JPLISAgent对象实现无文件注入 技术实现 Native内存操作 :使用Unsafe类分配和操作堆外内存 JPLISAgent结构分析 : 包含mNormalEnvironment成员指向JVMTIEnv mRedefineAvailable必须设为true 定位JVMTIEnv : 通过内存搜索找到jvm模块基址 计算固定偏移量获取JVMTIEnv地址 完整POC关键步骤 使用Unsafe分配内存伪造JPLISAgent 构造InstrumentationImpl实例 调用redefineClasses修改目标类 Java跨平台任意Native代码执行 技术原理 伪造jvmtienv对象,覆盖函数指针 allocate函数指针位于jvmtienv+0x168偏移处 覆盖该指针指向shellcode 绕过防护 绕过DEP :将shellcode写入JIT区域(RWX) 绕过ASLR : 方法1:指针指纹匹配 方法2:内存搜索定位JIT区域 完整流程 搜索内存定位可执行区域 布置伪造的jvmtienv对象 覆盖allocate函数指针 触发redefineClasses执行shellcode 小结 本文详细介绍了多种Java内存攻击技术: allowAttachSelf绕过技术 内存马防检测的跨平台实现 原生远程进程注入技术 无文件Agent型内存马植入 跨平台任意Native代码执行 这些技术可用于高级攻防场景,同时也提醒防御方需要加强内存层面的防护。测试环境为Win10/Ubuntu+Java 1.8.0_ 301/271_ x64。