mysql jdbc反序列化利用

参考资料https://www.anquanke.com/post/id/203086

按照资料描述搭建环境,注意,如果使用8.0.28版本的mysql,服务端MySQL_Fake_Server会报错(ValueError('45 is not a valid CharacterSet')>),刚开始以为是匹配的python版本不对,把3.x的版本都装了一遍,才怀疑可能是mysql版本问题,花了不少时间。

具体的原因,还没分析出来。

切换到8.0.14版本后,能正常使用,通过allowInLocalInfile读取任意文件成功。

重现反序列化利用后失败,没找到相关资料,只能硬着头自己分析了。记录下过程。

1.使用?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc参考资料的poc,在ServerStatusDiffInterceptor的populateMapWithSessionStatusValues方法打debug断点。堆栈如下:

 

 

 1.mysql的url格式匹配"(?<scheme>[\\w:%]+)\\s*(?://(?<authority>[^/?#]*))?\\s*(?:/(?!\\s*/)(?<path>[^?#]*))?(?:\\?(?!\\s*\\?)(?<query>[^#]*))?(?:\\s*#(?<fragment>.*))?"正则表达式,scheme和path支持url编码,由ConnectionUrlParser类处理。

2.ConnectionImpl的initializeSafeQueryInterceptors方法初始化url中的参数queryInterceptors到类的queryInterceptors属性中。

3.NativeProtocol类sendQueryPacket可见,先执行queryInterceptors的preProcess方法。所以进入ServerStatusDiffInterceptor的populateMapWithSessionStatusValues方法。

4.执行SHOW SESSION STATUS的sql语句。

5.从参考资料看触发点在执行了上述sql后,结果处理部分,即ResultSetUtil.resultSetToMap逻辑。

6.跟进后会执行rs.getObject逻辑,需要保证返回的数据是block才能触发反序列化。如下逻辑,需要为blob,autoDeserialize参数为true和data[0] != -84 || data[1] != -19

根据debug结果看,失败原因是已进入反序列化,但是未触发命令执行。(第二次进入getObject方法)

 

7.继续跟进反序列化方法内部。

 

 需要继续研究jdk的反序列化TransformerFactoryImpl,参考资料https://blog.csdn.net/m0_51632271/article/details/126699334

https://www.sohu.com/a/359904639_257305

https://blog.csdn.net/weixin_39555579/article/details/114175394

未完。

 

posted @ 2022-11-25 22:09  qqhacktest  阅读(743)  评论(1)    收藏  举报