专栏首页黑白安全fastjson 1.2.68 反序列化漏洞 gadget 的一种挖掘思路
原创

fastjson 1.2.68 反序列化漏洞 gadget 的一种挖掘思路

关于漏洞

fastjson 的这个新漏洞在 1.2.68 及之前版本的 autotype 关闭的情况下仍然可以绕过限制反序列化,相比 1.2.47 版本的漏洞来讲这个版本的漏洞还是有一些限制的(关于 1.2.47 漏洞可以参考我的另一篇文章《Java 反序列化漏洞始末(3)— fastjson》[1]),例如 1.2.47 是可以绕过黑名单的限制的,而这个漏洞则无法绕过黑名单,并且需要类实现 AutoCloseable 接口。目前主要的 JNDI gadget 已经进了黑名单,还不允许反序列化类实现了 ClassLoader、DataSource、RowSet 接口,这就导致了绝大部分的 JNDI gadget 无法利用,所以本篇文章主要分享一下 gadget 的挖掘思路和漏洞的原理分析。

漏洞分析

这个漏洞的的成因和我的另一篇文章《fastjson 1.2.68 最新版本有限制 autotype bypass》[2]一致,都是由于期望类(expectClass)导致的,这个漏洞的期望类范围更大,更容易找到具有危害的 gadget。

首先看 DefaultJSONParser#parseObject 这里将 @type 指定的类作为条件去获取 Deserialzer 对象。

ParserConfig#getDeserializer 方法中不满足条件所以到了最后一步通过ParserConfig#createJavaBeanDeserializer 方法来构造 JavaBeanDeserializer

在这一步创建了 JavaBeanDeserializer 对象,而漏洞也就发生在 JavaBeanDeserializer 类中。

现在回到 DefaultJSONParser#parseObject 应该走下一步 JavaBeanDeserializer#deserialze 方法。

用期望类的思路,可以找到此处有两个方法使用了 ParserConfig#checkAutoType 且指定了期望类。

一个是 deserialzeArrayMapping() 另一个是 deserialze()

在 deserialze() 方法中又做了一次 checkAutoType 检测,此处直接将第二个 @type 的类名,和前面构造 JavaBeanDeserializer 对象时指定的期望类直接传了进来。

我在 《fastjson 1.2.68 最新版本有限制 autotype bypass》[2] 这篇文章提到过,当 checkAutoType(String typeName, Class<?> expectClass, int features) 方法的 typeName 实现或继承自 expectClass,就会通过检验。

但还有三个问题,会阻碍 gadget 的触发。

ActionScript

boolean expectClassFlag;
if (expectClass == null) {
    expectClassFlag = false;
} else if (expectClass != Object.class && expectClass != Serializable.class && expectClass != Cloneable.class && expectClass != Closeable.class && expectClass != EventListener.class && expectClass != Iterable.class && expectClass != Collection.class) {
    expectClassFlag = true;
} else {
    expectClassFlag = false;
}

第一个问题是期望类的黑名单,里面包括了大部分常用的父接口和父类,却唯独少了一个 java.lang.AutoCloseable。这也就是为什么 AutoCloseable 为什么可以通过校验的第一个原因,第二个原因是TypeUtils#mappings里有 AutoCloseable 类。

第二个问题是黑名单类,fastjson 在 denyHashCodes 里几乎把常见的容易造成漏洞的类都加进了黑名单,这就造成了攻击成本变高,如果要利用漏洞,只能花费更多的时间去寻未被发现的常用库 gadget。

第三个问题是父类、父接口黑名单,fastjson 在判断期望类之前将继承自 ClassLoader、DataSource、RowSet 的类直接抛出异常。

ActionScript

if (ClassLoader.class.isAssignableFrom(clazz) || DataSource.class.isAssignableFrom(clazz) || RowSet.class.isAssignableFrom(clazz)) {
    throw new JSONException("autoType is not support. " + typeName);
}

而常用的 JNDI RCE 类基本上都继承自 DataSource 和 RowSet,所以能找到的 JNDI gadget 基本都无法在这个漏洞中使用。

以上三点足够让大部分常见的 gadget 无法使用,所以需要换一种 gadget 挖掘思路。

gadget

关于 gadget 的挖掘思路我主要是寻找关于输入输出流的类来写文件,IntputStream 和 OutputStream 都是实现自 AutoCloseable 接口的,而且也没有被列入黑名单,所以只要找到合适的类,还是可以进行文件读写等高危操作的。

JNDI

前面说到,这个漏洞基本无法使用 JNDI,实际上并不完全是,当 fastjson 小于 1.2.51 时,还是可以通过实现了 RowSet 接口的类进行 JNDI 反序列化,但实际上已经没有什么危害,大多数都更新到了 1.2.60+ 版本。

文件读写

我寻找 gadget 时的条件是这样的。

•需要一个通过 set 方法或构造方法指定文件路径的 OutputStream•需要一个通过 set 方法或构造方法传入字节数据的 OutputStream,并且可以通过 set 方法或构造方法传入一个 OutputStream,最后可以通过 write 方法将传入的字节码 write 到传入的 OutputStream•需要一个通过 set 方法或构造方法传入一个 OutputStream,并且可以通过调用 toString、hashCode、get、set、构造方法调用传入的 OutputStream 的 flush 方法

以上三个组合在一起就能构造成一个写文件的利用链,最终我挑选出了三个符合条件的类作为演示。

漏洞复现

漏洞的原理摸清了,接下来我将用本地的模拟环境复现一遍漏洞。

写文件

复制文件

总结

本文旨在给安全研究者提供一种反序列化漏洞 gadget 挖掘思路,文中 POC 代码暂不公开。

修复方案

•更新到 1.2.69 或更高版本•未能更新到 1.2.69 版本的请将 AutoCloseable、OutputStram、InputStream、RowSet 列入反序列化黑名单

References

[1] 《Java 反序列化漏洞始末(3)— fastjson》: https://b1ue.cn/archives/184.html [2] 《fastjson 1.2.68 最新版本有限制 autotype bypass》: https://b1ue.cn/archives/348.html

文由微信公众号安全档案

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 「聚焦」发现漏洞未及时修复要追究单位和责任人责任

    随着制造业的转型升级,万物互联已经成为工业信息系统中不可逆转的趋势,在工业信息系统逐步与互联网进行融合的过程中,安全问题也逐渐凸显出来。

    周俊辉
  • 俄政府拨款 5200 万美元发展数字经济

    俄罗斯政府网站 31 日发布公告称,总理梅德韦杰夫日前签署一项命令,要求从政府储备基金中拨款约 30 亿卢布(约合 5200 万美元)用于发展本国数字经济。公告...

    周俊辉
  • 木马伪装-后门木马变形记

    在做安全测试时,种个后门养个马在所难免,常见的后门有exe、bat、scr、vb等格式,可是凡是有点安全意识的都不会去下载、双击打开,那给后门穿件衣裳可好。me...

    周俊辉
  • 关于 public.resource.org

    版权制度中有一个原则,那就是政府文件是没有版权的,属于公共领域,任何人都可以自由使用。这是因为政府文件来自于纳税人的税款,理应属于全社会所有。 可是,虽然没有版...

    ruanyf
  • 2020-01-23 TCP 建立和断开,言简意赅

    https://juejin.im/post/5e26b199f265da3df245e5ed?utm_source=gold_browser_extensio...

    Albert陈凯
  • cannot be cast to javax.servlet.Servlet

    报错:cannot be cast to javax.servlet.Servlet 原因以及解决办法:public class WageTaxServlet ...

    闵开慧
  • 打造Window Server 2008 R2的工作站

    Thinkpad X200 7458 CTO上安装Windows Server 2008 R2,windows Server 2008 R2安装过程非常简单,只...

    张善友
  • SQL Server安全(2/11):身份验证(Authentication)

    在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切。但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念。这篇...

    逸鹏
  • js和jQuery获取img标签的src属性获取不到的解决方法

    很多朋友可能遇到过,用 jQuery 获取 img 标签的 src 属性却获取不到的问题:

    德顺
  • 0-1背包-分支限界

    算法描述:   活结点优先队列中结点元素N的优先级由该结点的上界函数Bound计算出的值uprofit给出。   子集树中以结点N为根的子树中任一结点的价值不超...

    用户1154259

扫码关注云+社区

领取腾讯云代金券