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
未完。

浙公网安备 33010602011771号