FastJSON 1.2.251.2.421.2.43版本反序列化漏洞如何审计?

摘要:代码审计 | FastJSON 反序列化分析:1.2.251.2.421.2.43 个人学习记录,记录一下这三个版本的绕过思路和调试过程。 这三个版本有个共同点:都需要 autoTypeSupport=true 才能利用,算是一
代码审计 | FastJSON 反序列化分析:1.2.25 / 1.2.42 / 1.2.43 个人学习记录,记录一下这三个版本的绕过思路和调试过程。 这三个版本有个共同点:都需要 autoTypeSupport=true 才能利用,算是一条贯穿始终的主线。 目录 环境准备 1.2.25 —— checkAutoType 机制引入 源码变化对比 为什么要开启 autoTypeSupport 调试过程 1225 1.2.42 —— 双写绕过 Payload 变化 checkAutoType 内部逻辑解析 loadClass 的递归剥离 1.2.43 —— 数组符号绕过 修复分析:LL; 被阻断 新 Payload 构造:利用左花括号绕过 调试过程 1243 变体写法:L 型数组 核心逻辑:为什么只修了 LL 却没修数组 常见 Payload 汇总 小结 环境准备 首先是配置 pom.xml,切换到对应的 fastjson 版本: 然后用 maven 下载对应依赖: 1.2.25 —— checkAutoType 机制引入 源码变化对比 1.2.24 和 1.2.25 之间是个比较大的变化,把 24 和 25 的源码对比一下: 之前(1.2.24)是直接 loadClass 来加载、实例化,并触发 Setter 方法。但从 1.2.25 开始,引入了 checkAutoType 检测方法,多了一道安全检查。 为什么要开 autoTypeSupport 改 main 代码,payload 里需要把原本的: com.sun.rowset.JdbcRowSetImpl 改成加了 L 和 ; 的写法: Lcom.sun.rowset.JdbcRowSetImpl; 同时还需要添加这行代码: ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 如果不写这行(或者设为 false),解析到 @type 的时候会直接报错: com.alibaba.fastjson.JSONException: autoType is not support 这里有个现实问题:autoTypeSupport 默认是关的,正常情况下这个漏洞利用不了。 但部分开发者为了兼容业务需求,会手动开启 autoTypeSupport,或者通过配置文件开启——这是这三个版本绕过能生效的前提条件。 调试过程 调试到检测 @type 的位置,会进入一个 checkAutoType 函数。 调试发现一个关键判断: 当 autoTypeSupport: false 时,class 不会被 loadClass 函数赋值,class 为 null,直接进入抛出异常的判断语句。 所以需要开启: ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 才能让流程继续往下走。 开启之后再调试,autoTypeSupport 为 true,开始执行: TypeUtils.loadClass(typeName, this.defaultClassLoader); 此时 typeName 的值为: Lcom.sun.rowset.JdbcRowSetImpl; 成功取出我们写的 @type 值: 进入 loadClass 函数后,进入了检测 L 和 ; 的判断,把 L 和 ; 剥离掉,返回了 com.sun.rowset.JdbcRowSetImpl 作为 newClassName: 因为开关是开的,所以返回 class 为 com.sun.rowset.JdbcRowSetImpl: 到此检测函数结束,返回了 class 值: 接下来的流程就和 1.2.24 版本一样了。 1.2.42 —— 双写绕过 payload 变化 maven 切换到 1.2.42 版本,源码下载: https://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.42/ 修改 pom 版本: 对比 1.2.25 和 1.2.42 的 src/main/java/com/alibaba/fastjson/parser/ParserConfig.java,可以发现有了新的检测逻辑。
阅读全文