Java内存马-Instrument

注:

本文还没完成,后面有空再完成吧。
其实吧,关键的东西都在代码实现里了:
https://github.com/fa1c0n1/JavaInstrument

Java Instrument简介

我们只要拥有一个web容器进程执行用户的权限,理论上就可以完全控制该进程的地址空间(更确切的说是地址空间中的非Kernel部分),包括地址空间内的数据和代码。OS层进程注入的方法有很多,不过具体到Java环境,我们不需要使用操作系统层面的进程注入方法。Java为我们提供了更方便的接口,Java Instrumentation。

java.lang.Instrument包是在JDK5引入的,开发者通过修改方法的字节码实现动态修改类代码。利用Instrument,开发者可以开发单独的代理Agent实现对JVM进程的运行时监控,分析JVM进程运行时内存状态,甚至可以很方便地修改内存中类的字节码,修改或者扩展已有的功能

Java Agent 开发

Java agent的使用方式有两种:

  • 实现premain方法,在JVM启动前加载;
  • 实现agentmain方法,在JVM启动后加载。

premain和agentmain函数声明如下,拥有Instrumentation inst参数的方法优先级更高:


public static void agentmain(String agentArgs, Instrumentation inst) {
    ...
}

public static void agentmain(String agentArgs) {
    ...
}

public static void premain(String agentArgs, Instrumentation inst) {
    ...
}

public static void premain(String agentArgs) {
    ...
}

第一个参数String agentArgs就是Java agent的参数。
第二个参数 Instrumentaion inst 相当重要,后面会提到。

由于内存马的使用场景,一般是注入正在运行的JVM进程,所以下面只介绍 agentmain 方式的使用。

agentmain() 方法

VirtualMachine

Agent内存马实现:Tomcat环境

演示:Tomcat环境

演示,SpringMVC 5.2.0 + Tomcat 8.5.39:

启动Tomcat环境后,注入我们的Agent内存马。
在这里插入图片描述
在这里插入图片描述

这里要注意,由于是自己的测试环境,所以刚启动Tomcat,需要自己访问一下Tomcat服务的随便一个url,否则Tomcat里的一些类没有加载进内存,比如注入Agent内存马时要找的目标类org.apache.catalina.core.ApplicationFilterChain。没有加载到内存中,从而找不到这个类,所以注入内存马失败。而线上环境的话由于早就被访问过无数次了,所以Tomcat的这些类肯定都已被加载到内存中了,所以就不存在这个问题,直接注入Agent内存马即可。

然后做以下操作:

  • 访问已存在的路由url

(1) 指定非webshell的参数时,原有业务不受影响:
在这里插入图片描述
(2) 指定webshell参数时,将执行我们注入的webshell代码:
在这里插入图片描述

  • 访问不存在的路由url

(1) 指定非webshell的参数时,显示404页面:
在这里插入图片描述
(2) 指定webshell参数时,将执行我们注入的webshell代码:
在这里插入图片描述

agent内存马持久化:Tomcat重启后被自动注入agent内存马

agent内存马注入Tomcat进程后,原来路径下的两个jar被agent删除了,然后当Tomcat进程关闭前,两个jar会写入到Tomcat的临时目录,并开启AgentTomcatMemShellInject 进程。
在这里插入图片描述
在这里插入图片描述
当Tomcat再次启动后,AgentTomcatMemShellInject检测到Tomcat进程后,将agent内存马注入进去,然后AgentTomcatMemShellInject进程便结束了。
在这里插入图片描述
在这里插入图片描述
此时再次访问agent内存马,发现依旧生效。自此,便实现了agent内存马在Tomcat环境下的持久化,会随着Tomcat进程的重启而自动复活。(如果不想让它自动复活,则在Tomcat关闭后,kill掉AgentTomcatMemShellInject的进程即可)
在这里插入图片描述

演示:Springboot环境

Springboot环境下,目前笔者无法做到自动复活。因为在Agent注入到Springboot的进程后,尝试了各种办法都无法在agentmain()方法中获取到上下文context对象,从而无法进一步获取Tomcat端口号。


Instrument内存马的特点

  • 优点:不会生成新的Servlet,Filter,Listener对象,因此隐蔽性更强。
  • 缺点:需要生成Agent文件落地,有可能会被IDS文件检测检测到Agent。

    针对缺点的改进,参考学习[3][4]


相关代码已传github:

https://github.com/fa1c0n1/JavaInstrument

参考

[1] https://mp.weixin.qq.com/s/cbF2cdV9mnbGZWDwHuUoNA
[2] https://www.cnblogs.com/rebeyond/p/9686213.html
[3] https://mp.weixin.qq.com/s/JIjBjULjFnKDjEhzVAtxhw
[4] https://mp.weixin.qq.com/s/ulINOH4BnwfR7MBc6r5YHQ
[5] https://mp.weixin.qq.com/s/sV_mUnI6GshehMiLgCSn7Q
[6] https://mp.weixin.qq.com/s/YVwqD6SwUq_jkEe_9afBCg
[7] https://mp.weixin.qq.com/s/gmKSmW5SIME8lWKj8bvhWw

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
opentelemetry-javaagent.jar 是一个用于自动化和 Java 应用程序的分布式跟踪的工具。我们可以使用自定义 instrument 来扩展其功能。 自定义 instrument 可以帮助我们实现一些自定义的行为,例如,我们可以在代码中插入额外的标记信息,或者在特定的函数或方法中加入额外的追踪逻辑。 要实现自定义 instrument,我们需要进行以下步骤: 1. 创建一个 Java 类,并继承 `OtelInstrumenter` 类。这是一个由 OpenTelemetry 提供的接口,用于定义自定义 instrument 的行为。 2. 在该类中,我们需要实现 `applyInstrumentation` 方法。该方法会被调用来应用自定义的 instrument 到目标应用程序中。 3. 在 `applyInstrumentation` 方法中,我们可以使用 OpenTelemetry 提供的 API 来修改目标应用程序的代码,例如,在特定的函数或方法调用前后插入追踪代码。 4. 编译并打包自定义 instrument 的代码,并将其作为 `-javaagent` 参数传递给 `opentelemetry-javaagent.jar`。当目标应用程序启动时,这个自定义 instrument 会被加载和应用。 通过使用自定义 instrument,我们可以根据自己的需求对目标应用程序的代码进行修改和增强。这样,我们就能够更好地实现跟踪和监控,并获得更加详细和准确的跟踪数据。 总结起来,opentelemetry-javaagent.jar 提供了一种灵活和可扩展的方式来实现自定义 instrument。我们可以通过创建自定义 instrument 类,并在其中实现特定的逻辑来修改目标应用程序的代码,从而实现更精确和详细的分布式跟踪。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值