[备份] Java中DoS to RCE失败的探索

写一篇水文,没有什么技术,记录一次失败的探索

前言

拒绝服务漏洞本身是鸡肋洞,但研究如何通过DoS到RCE是有意义的,我进行了一些尝试,虽然最终失败,但我认为有必要记录一下过程,算是学习的笔记

Java理论上不存在通过拒绝服务到RCE的可能性,因为无法操作底层,不能通过栈溢出写shellcode

但我找到了鸡肋的办法,确实能够从DoS到RCE,虽说鸡肋,但也可以拿来写一下

 

定位JVM的危险函数

hotspotos模块的C++代码,找到system()函数的调用

全局搜索fork_and_exec函数,在vmError.cpp找到一处有意思的地方

发现命令字符串来自于OnOutOfMemoryError变量,在globals.hpp中找到:

在程序出现OOM的时候,执行用户自定义的某些脚本或命令

 

通过DoS触发RCE

阅读Oracle相关文档后发现了触发的方式

简单写一个OOME的类(模拟实际中可能出现的DoS漏洞)

成功通过DoS触发RCE

img

 

寻找修改参数方式

以上内容是启动JVM时修改参数,我想找到一种在运行时修改参数的方式

昨天橙子酱师傅分享了一篇文章:如何在运行时修改JVM参数

我尝试阅读JVM源码找到其中的说明(在globals.hpp中)

其中提到com.sun.management.HotSpotDiagnosticMXBean类可以修改参数

发现这是一个接口,提供了dumpHeapget/set参数的方法

使用该接口的实现类修改参数

报错如下

 

失败的绕过

跟踪上文的报错信息,发现某处判断了修改参数类型不能是String

通过反射直接操作Flag类(该类的私有的)

尝试通过反射修改

报错如下

错误来自于native方法

 

报错的底层原理

找到JNI相关的代码

flagJVM中已经固定,无法修改,所以在Java层面无论如何也是无法修改的