九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

渗透技巧 2年前 (2022) admin
562 0 0
九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

01


Java Agent 简介


在 jdk 1.5 之后引入了 java.lang.instrument 包,通过 java.lang.instrument 实现的工具叫 Java Agent ,Java Agent 能够在不影响正常编译的情况下来修改字节码,即动态修改已加载或者未加载的类,包括类的属性、方法。
Agent 内存马的实现就是利用了这一特性使其动态修改特定类的特定方法,将我们的恶意方法添加进去,很像反射。

Java Agent 支持两种方式进行加载:
1. 实现 premain 方法,在启动时进行加载 (该特性在 jdk 1.5 之后才有)。
2. 实现 agentmain 方法,在启动后进行加载 (该特性在 jdk 1.6 之后才有)。

在了解java agent之前,先看看jar包的文件格式。

我们需要了解MANIFEST.MF 文件。

当我们用 JAR 命令打完包后,会在根目录下面创建 META-INF 目录,该目录下面会有一些对该 JAR 包信息的描述,其中肯定会有一个 MANIFEST.MF 文件,该文件包含了该 JAR 包的版本、创建人和类搜索路径等信息。
Manifest-Version: 1.0 # 用来定义manifest文件的版本Archiver-Version: Plexus Archiver # 详见 http://codehaus-plexus.github.io/plexus-archiver/Built-By: penson # 构建者Created-By: Apache Maven 3.5.0 # # 声明该文件的生成者,一般该属性是由 jar 命令行工具生成的Build-Jdk: 1.8.0_162 # 基于构建的 JDK 版本
*左右滑动查看更多

02


premain方法


premain 方法,会在我们运行 main 方法之前进行调用,即在运行 main 方法之前会先去调用我们 jar 包中 Premain-Class 类中的 premain 方法。

创建一个demo类:
import java.lang.instrument.Instrumentation;

public class Demo { public static void premain(String agentArgs, Instrumentation inst) throws Exception{ System.out.println(agentArgs); for(int i=0;i<5;i++){ System.out.println("premain 方法被调用"); } }}
*左右滑动查看更多

创建mainfest:
agent.mf
Manifest-Version: 1.0Premain-Class: Demo

利用 javac 将 java 文件编译成 class 之后,利用 jar 命令打包,生成jar包 agent.jar。
jar cvfm agent.jar agent.mf Demo.class
*左右滑动查看更多

同样写一个普通类打包成jar,记得不要带包名。
public class Test { public static void main(String[] args) { System.out.println("this is test main"); }}
*左右滑动查看更多

Test.mf
Manifest-Version: 1.0Main-Class: Test

记得加换行:
jar cvfm Test.jar agent.mf Test.class
*左右滑动查看更多

拿到agent.jar 和 Test.jar:
 `java -jar` 中添加 `-javaagent:agent.jar` 即可在启动时优先加载 agent , 而且可利用如下方式获取传入我们的 agentArgs 参数。
java -javaagent:agent.jar[=options] -jar Test.jarjava -javaagent:agent.jar=penson -jar Test.jar
*左右滑动查看更多

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

idea操作。
在使用premain方法时,看到需要的参数。
九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

我们看到这里传的两参数,一个是agentArgs就是传的参数,然后还有Instrumentation。


Instrumentation



Instrumentation 是 JVMTIAgent(JVM Tool Interface Agent)的一部分,Java agent通过这个类和目标 JVM 进行交互,从而达到修改数据的效果。

在 Instrumentation 中增加了名叫 transformer 的 Class 文件转换器,转换器可以改变二进制流的数据。

Transformer 可以对未加载的类进行拦截,同时可对已加载的类进行重新拦截,所以根据这个特性我们能够实现动态修改字节码。

这是一个接口,我们重点关注三个方法。

addTransformer
当类加载的时候,会进入我们自己的 Transformer 中的 transform 函数进行拦截。

在`addTransformer()`方法中,有一个参数`ClassFileTransformer transformer`。这个参数将帮助我们完成字节码的修改工作。

测试一下。
import java.lang.instrument.Instrumentation;import DefineTransformer;public class Demo2 { public static void premain(String agentArgs, Instrumentation inst) throws Exception{ System.out.println(agentArgs); for(int i=0;i<5;i++){ System.out.println("premain 方法被调用了"); } // 注册 DefineTransformer inst.addTransformer(new DefineTransformer(),true); }}
*左右滑动查看更多
import java.lang.instrument.ClassFileTransformer;import java.lang.instrument.IllegalClassFormatException;import java.security.ProtectionDomain;
// 每当类被加载,就会调用 transform 函数public class DefineTransformer implements ClassFileTransformer { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { System.out.println(className); return new byte[0]; }}
*左右滑动查看更多

如果需要修改已经被JVM加载过的类的字节码,那么还需要设置在 MANIFEST.MF 中添加 Can-Retransform-Classes: true 或 Can-Redefine-Classes: true。
Manifest-Version: 1.0Can-Redefine-Classes: trueCan-Retransform-Classes: truePremain-Class: Demo2

jar cvfm agent.jar agent.mf Demo2.class DefineTransformer.class
*左右滑动查看更多

java -javaagent:agent.jar=penson -jar Test.jar
*左右滑动查看更多

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

03


agentmain 方法


  1. 必须要实现 agentmain 方法。
2. Jar 文件清单中必须要含有 Premain-Class 属性。
3. 我们主要关注这两个类,分别是 VirtualMachine 和 VirtualMachineDescriptor。


VirtualMachine



VirtualMachine 可以来实现获取系统信息,内存dump、现成dump、类信息统计(例如JVM加载的类)。

该类允许通过给attach方法传入一个jvm的pid(进程id),远程连接到jvm上。

attach:从 JVM 上面解除一个代理(agent)。
loadAgent向jvm注册一个代理程序agent,在该agent的代理程序中会得到一个Instrumentation实例,该实例可以 在class加载前改变class的字节码,也可以在class加载后重新加载。在调用Instrumentation实例的方法时,这些方法会使用ClassFileTransformer接口中提供的方法进行处理。
Detach从 JVM 上面解除一个代理(agent)。


VirtualMachineDescriptor



VirtualMachineDescriptor是一个描述虚拟机的容器类,配合 VirtualMachine 类完成各种功能。

这两个类都在tools.jar里 ,tools.jar 即你的java安装路径的lib里面。

看到demo:
import java.lang.instrument.Instrumentation;
public class Demo3 { public static void agentmain(String agentArgs, Instrumentation ins) { ins.addTransformer(new DefineTransformer(),true); }}
*左右滑动查看更多

import java.lang.instrument.ClassFileTransformer;import java.lang.instrument.IllegalClassFormatException;import java.security.ProtectionDomain;
// 每当类被加载,就会调用 transform 函数public class DefineTransformer implements ClassFileTransformer { public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { System.out.println(className); return classfileBuffer; }}
*左右滑动查看更多

agent.mf:
Manifest-Version: 1.0Can-Redefine-Classes: trueCan-Retransform-Classes: trueAgent-Class: Demo3

jar cvfm agent.jar agent.mf Demo2.class DefineTransformer.class
*左右滑动查看更多

测试:
package com.test.agentlearn_agentmain;
import com.sun.tools.attach.VirtualMachine;import com.sun.tools.attach.VirtualMachineDescriptor;
import java.util.List;

public class TestDemo { public static void main(String[] args) throws Exception{ String path = "/Users/penson/Desktop/网安/网络安全学习/java安全/java-agent内存马/src/main/java/com/test/agentlearn_agentmain/agent.jar"; Listlist = VirtualMachine.list(); for (VirtualMachineDescriptor v:list){ System.out.println(v.displayName()); if (v.displayName().contains("TestDemo")){ // 将 jvm 虚拟机的 pid 号传入 attach 来进行远程连接 System.out.println(v.id()); VirtualMachine vm = VirtualMachine.attach(v.id()); // 将我们的 agent.jar 发送给 vm.loadAgent(path); vm.detach(); } } }}
*左右滑动查看更多

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

(未完待续)


—  往期回顾  —


九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)



关于安恒信息安全服务团队
安恒信息安全服务团队由九维安全能力专家构成,其职责分别为:红队持续突破、橙队擅于赋能、黄队致力建设、绿队跟踪改进、青队快速处置、蓝队实时防御,紫队不断优化、暗队专注情报和研究、白队运营管理,以体系化的安全人才及技术为客户赋能。

九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)


九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)
九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

原文始发于微信公众号(安恒信息安全服务):九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一)

版权声明:admin 发表于 2022年10月19日 下午4:28。
转载请注明:九维团队-红队(突破)| 关于文件落地型java-agent内存马探讨(一) | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...