CVE-2020-36180的调试分析
测试过程 https://github.com/Al1ex/CVE-2020-36179 windows可以直接利用 mac会出错,需改写组件类(具体看以下) MAC出错分析 第一点:SQL文件分析 CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException { jav
测试过程
https://github.com/Al1ex/CVE-2020-36179
- windows可以直接利用
- mac会出错,需改写组件类(具体看以下)
MAC出错分析
第一点:SQL文件分析
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('calc.exe')
h2知识
https://www.jianshu.com/p/4a613dcf182c
java SQL database
可作为java的内嵌式数据库
支持r2dbc spi,类似jdbc的规范
三种运行方式:
内存模式(只适合测试环境)
在利用的时候,DBName可为空
jdbc:h2:mem:DBName;DB_CLOSE_DELAY=-1嵌入模式(持久化为文件)
jdbc:h2:file:~/.h2/DBName;AUTO_SERVER=TRUE服务模式
jdbc:h2:tcp://localhost/~/test 使用用户主目录 jdbc:h2:tcp://localhost//data/test 使用绝对路径
SQL语法
RUNSCRIPT FROM:运行sql脚本
SCRIPT:根据数据库创建sql脚本
h2自定义函数
CREATE ALIAS 大写函数名 AS $$ import ***; String 函数名(type args) throw ***{javacode} $$; CALL 大写函数名(args)
java代码
最基本的回显命令
java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
第二点:MAC错误原因
现象
MAC出现以下错误信息

windows偶尔运行成功,偶尔运行失败

猜测原因
- jdk版本
- jdk关于不同系统底层类存在偏差
- idea配置
调试分析
windows与manc的java版本都为1.8.0_221,所以排除情况1。
windows与manc的idea经对比后,基本一致,所以排除情况3。
进行调试,验证情况2。
对mac和windows进行同步调试
windows调用链如下

mac调用链如下

小结
运行成功时
从NativeMethodAccessorImpl类的invoke0方法跳到DriverAdapterCPDS类的getDescription方法
运行失败时
从NativeMethodAccessorImpl类的invoke0方法跳到DriverAdapterCPDS类的getParentLogger方法
NativeMethodAccessorImpl类属于jdk类
结论分析
初步调试中,发现windows和mac最后几步跳转不同。
为了找出具体原因,进行深度对比调试。
发现
BeanSerializerBase类中的serializeFields方法
对props数组进行配置定义,以下为关键代码

props数组包含h2连接的一些参数,如url、description等,利用prop.serializeAsField(bean, gen, provider方法对props数组中的各个参数进行配置

我们可以从报错信息中发现,parentLogger变量在进行配置时会报错,具体原因不赘述
其中,windows系统中parentLogger位置相对靠后,但顺序不定


其中,mac系统中parentLogger位置固定于14
因此我们可知,parentLogger参数位置是造成windows和mac系统错误与否的原因
在mac中,parentLogger参数在前,配置时报错,而后程序中止
同时,我们可推测14后面的四个参数可能是执行连接操作,也就是真正触发漏洞的参数

在windows系统中,调试,将i设置为pooledConnection对应的位置


发现,计算机打开,漏洞触发,因此pooledConnection就是h2连接数据库的漏洞触发参数

结论
- props数组中的pooledConnection参数与parentLogger参数的相对位置是漏洞执行与否的关键
- parentLogger参数在前,则直接报错;pooledConnection参数在前,则漏洞触发
- pooledConnection参数是漏洞触发点