快捷搜索:

利用原生库和JNI(Java原生接口)实现H2数据库漏

作者: 计算机  发布:2019-10-26

  在H2数据库引擎中获取代码执行权限的技术早已是众所周知,但有个要求就是H2能够动态编译Java代码。而本文将向大家展示以前没有公开过的利用H2的方法,并且无需使用Java编译器,即通过原生库和JNI(Java原生接口)实现H2数据库漏洞的利用 。

  上周,的博文。它描述了如果和库可用,如何利用中基于setter的漏洞。简而言之,就是利用H2的特性,使用Java代码 ,并使用Java编译器动态编译这些函数。

  但如果Java编译器不可用呢?这是在最近的一次参与中遇到的情况,Windows系统上的H2数据库引擎实例版本1.2.141公开了其Web控制台。我们希望通过使用原生库(.dll或.so)和Java原生接口(JNI),找到一种新的方法来执行任意Java代码,而无需在目标服务器上使用Java编译器。

  当引用一个方法时,类必须已经被编译并包含在运行数据库的类路径中。仅支持静态Java方法;类和方法都必须是公共的。

  当引用一个方法时,类必须已经被编译并包含在运行数据库的类路径中。仅支持静态Java方法;类和方法都必须是公共的。

  因此各个公共静态方法都可以使用。最坏的情况是,只有h2-1.2.141.jar和JRE可用。此外,只有受支持的数据类型可用于嵌套函数调用。

  在Java运行时库rt.jar中浏览candidates时,我们发现System.load(String)方法允许加载原生库。这意味着我们可以通过库的入口点函数来执行代码。

  但如何将库加载到H2服务器上呢?虽然Windows上的Java支持UNC路径并提取文件,但其拒绝实际加载它。而且这在Linux上也不起作用。那么,如何将文件写入H2服务器呢?

  在查看和研究了一些后,我们发现了一个FILE_WRITE文件写入函数。不幸的是,FILE_WRITE是的。而我们需要的是。最终我们找到了一个名为CSVWRITE的函数,这也是唯一一个名称中带“ write”的函数。

  快速测试显示了CSV列标头也被打印了出来。查看CSV选项,可以看到有一个writeColumnHeader选项可用于禁用写入列标头。不幸的是,。

  但是在查看其他受支持的选项fieldSeparator,fieldDelimiter,escape,null和lineSeparator时,我蹦出了一个想法:如果我们将它们全部清空,并使用CSV列标头写入我们的数据,会怎样?如果H2数据库引擎允许列具有任意长度的任意名称,那么我们就能够写入任意数据。

  带引号的名称区分大小写,并且可以包含空格。没有最大名称长度。两个双引号可用于在标识符内创建一个单双引号。

  带引号的名称区分大小写,并且可以包含空格。没有最大名称长度。两个双引号可用于在标识符内创建一个单双引号。

  这听起来很完美。让我们看看我们是否可以在其中放入任意内容,以及CSVWRITE是否具有二进制安全机制。

  现在我们生成一系列CHAR(n)函数调用,它们将在SQL查询中生成我们的二进制数据:

  既然我们可以使用内置函数CSVWRITE,将原生库写入磁盘并通过为System.load(String)创建别名来加载它,我们就可以使用库的入口点来实现代码执行。

  允许原生代码和Java虚拟机(JVM)之间的交互。因此,在这种情况下,它将允许我们与运行H2数据库的JVM进行交互。

  现在,我的想法是使用JNI通过将自定义Java类注入到运行的JVM中。这将允许我们创建一个别名并从SQL调用它。

  自定义Java类JNIEngine只有一个公共静态方法,它使用可用的Engine实例评估传递的脚本:

本文由澳门金沙145.com于2019-10-26日发布