| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> 代码审计-Fastjson各版本漏洞分析(上) -> 正文阅读 |
|
[网络协议]代码审计-Fastjson各版本漏洞分析(上) |
- 前言 -最先出现问题的Fastjson 1.2.24反序列化漏洞已经分析过了,产生漏洞的原理也差不多理解了 ?在1.2.25之后的版本,以及所有的.sec01后缀版本中,autotype功能默认是受限的(黑白名单机制) ?在1.2.68之后的版本,fastjson增加了safeMode的支持。配置safeMode后,无论白名单和黑名单,都不支持autoType - 概念 -可能出现一些新的概念,给一些参考链接吧 ?FastJSON为什么要有autoType功能 ?enable_autotype ?fastjson_safemode - 演示代码 -后面的分析代码都以此为基础修改 package?org.example; - fastjson 1.2.24 -?之前已经分析过了,就不在写了 fastjson 1.2.41利用的前提是必须要手动开启autoTypeSupport,不然还是不能利用,所以说还是有一点鸡肋吧 从代码中开启autoTypeSupport ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 在1.2.25之后的版本,以及所有的.sec01后缀版本中,增加了checkAutotype函数,autotype功能默认是受限的(黑白名单机制) 但在1.2.25到1.2.41之间,发生过一次checkAutotype的绕过。 Payload如下 {"@type":"Lorg.example.User;","age":66,"username":"test"} 我们用这个payload来分析一下如何绕过的(fastjson 1.2.41) 进入checkAutoType后,首先会对typeName的长度进行判断,很明显这个条件满足不了,所以不会抛出异常 继续向下,开启autoTypeSupport时,会先通过黑白名单来判断,先白名单后黑名单 很明显我们传入的typeName Lorg.example.User;肯定是不在黑名单内的,这是一个绕过的点 继续向下,如果clazz==null,就会调用TypeUtils.getClassFromMapping(typeName);,跟一下其实就是从一个ConcurrentHashMap中看看存不存在这个类,很明显我们传入的L开头的类是不会存在的 继续向下,和上面类似,我们这个类还是找不到的,所以clazz还是null 没开启autoTypeSupport的情况下,依然会进行黑白名单检测,先黑名单后白名单,我们这里手动开启了所以这里不管,因为会跳过 前面黑名单检测都没问题,就会开始加载这个类了 跟进loadClass,如果第一个字符是[,就会去掉[再去解析,我们这里不满足就先不看,继续向下 这个条件就是这次绕过的核心条件了 elseif(className.startsWith("L")&&?className.endsWith(";")){ 如果开头是L而且结尾是;,那么就会给前后这俩字符去掉,所以可以看到我们的newClassName就是我们想要的org.example.User 后续就会加载我们的类实例化,达到我们绕过的目的 debug过程中,可能大家注意到一个点,loadClass函数中,有一个条件,如果第一个字符是[,就会去掉[再去实例化,那这个地方是不是也能用来绕过呢? 答案是当然可以,这个绕过点就体现在1.2.43版本中 - fastjson 1.2.42 -1.2.41问题出现后,1.2.42中尝试了修复,修复方式 ?https://github.com/alibaba/fastjson/commit/e701faa2da7cff6d94394061bbff06a166c2aaaf 寻找历史commit技巧: 1.release里面找对应的版本的commit 2.直接搜索commit 3.直接搜索issue 可以明显的看到,给原来的denyList变成了denyHashCodes,让安全研究更难了,但是hashcode的方法是公开的,只要jar包够多还是可以碰撞出来的,感觉治标不治本。。。 同时可以看到针对漏洞绕过的修复方式,很简单粗暴,如果发现开头是L而且结尾是;,就直接去掉 所以绕过方式也很简单,直接用2个L和2个;就可以了,Payload如下 {"@type":"LLorg.example.User;;","age":66,"username":"test"} - fastjson 1.2.43 -对LL;;可以绕过的情况做了过滤,如果只有一个L;,就去除了后再走黑名单去过滤看看是否允许反序列化,着实太恶心了看着 所以2个LL;;是行不通了,但是别忘了我们在分析1.2.41的时候,发现还会去掉[然后实例化,这就是绕过点 初始payload {"@type":"[org.example.User","age":66,"username":"test"} 报错exepct '[', but ,, pos 29, json : {"@type":"[org.example.User","age":66,"username":"test"},29那个位置,期望一个[,但是是,,所以我们加一个[ {"@type":"[org.example.User"[,"age":66,"username":"test"} 报错syntax error, expect {, actual string, pos 30, fastjson-version 1.2.43,期望30的位置是一个{,加上 最终POC {"@type":"[org.example.User"[{,"age":66,"username":"test"} 看着有点迷,为啥加上[{就可以了? 分析一下,通过checkAutoType后,返回class?[Lorg.example.User; 一直跟,发现调用了deserializer.deserialze,跟进去,发现使用了clazz.getComponentType(),是不是很眼熟?就是前面去掉[的那个地方 这个函数是native的,所以看不到代码。。。不过根据结果来看,就是去掉[L和;拿到类 再继续往下,跟进parseArray 发现如果token != 14就会抛出错误,而没有[的时候,token是16,所以会报错,{也类似,可以下个异常断点来分析 最后看下到setXXX的运行堆栈信息,结合堆栈来分析可以节约很多时间 setUsername:20, User (org.example) |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 4:52:23- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |