欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET高级代码审计(第三课)Fastjson反序列化漏洞

程序员文章站 2022-06-28 20:36:55
0X00 前言 Java中的Fastjson曾经爆出了多个反序列化漏洞和Bypass版本,而在.Net领域也有一个Fastjson的库,作者官宣这是一个读写Json效率最高的的.Net 组件,使用内置方法JSON.ToJSON可以快速序列化.Net对象。让你轻松实现.Net中所有类型(对象,基本数据 ......

 

 

0x00 前言

java中的fastjson曾经爆出了多个反序列化漏洞和bypass版本,而在.net领域也有一个fastjson的库,作者官宣这是一个读写json效率最高的的.net 组件,使用内置方法json.tojson可以快速序列化.net对象。让你轻松实现.net中所有类型(对象,基本数据类型等)和json之间的转换,fastjson是一个开源的json.net库,下载地址 http://www.codeproject.com/articles/159450/fastjson,反序列过程中详细的性能对比如下

.NET高级代码审计(第三课)Fastjson反序列化漏洞

从图上得出和老牌json.net、stack等比起来速度和性能优势非常明显,究其原因组件的作者利用反射生成了大量的il代码,而il代码是托管代码,可以直接给运行库编译所以性能就此大大提升。但在某些场景下开发者使用json.toobject方法序列化不安全的数据时候会造成反序列化漏洞从而实现远程rce攻击,本文笔者从原理和代码审计的视角做了相关介绍和复现。

.NET高级代码审计(第三课)Fastjson反序列化漏洞

 

 

0x01 fastjson序列化

使用json.tojson可以非常方便的实现.net对象与json数据之间的转化,tojson首先会得到对象名称所在的程序集全限定名,并且作为$types这个key的值,再将对象的成员属性名转化为json数据中的key,把对象的成员属性值转化为json数据中的value,下面通过一个实例来说明问题,首先定义testclass对象

.NET高级代码审计(第三课)Fastjson反序列化漏洞

定义了三个成员,并实现了一个静态方法classmethod启动进程。 序列化通过创建对象实例分别给成员赋值 

.NET高级代码审计(第三课)Fastjson反序列化漏洞

笔者为了尽量保证序列化过程不抛出异常,所以引入了 json.tojson方法的第二个参数并实例化创建jsonparameters,它的字段中有很多类型是布尔值,

.NET高级代码审计(第三课)Fastjson反序列化漏洞

和反序列化漏洞相关的字段为useextensions ,将它设置为true可得到类的全限定名,如果不需要序列化空值的时可将另一个字段serializenullvalues设为false; 笔者使用json.tojson后得到序列化的json数据

.NET高级代码审计(第三课)Fastjson反序列化漏洞

0x02 fastjson反序列化

2.1、反序列化用法

反序列过程就是将json数据转换为对象,fastjson通过创建一个新对象的方式调用json. toobject方法实现的,toobject有多个重载方法,当传入两个参数,第一个参数需要被序列化的数据、第二个参数设置序列化配置选项来指定jsonparameters按照指定的属性值处理,重载方法参考下图

 .NET高级代码审计(第三课)Fastjson反序列化漏洞

具体代码可参考以下demo

.NET高级代码审计(第三课)Fastjson反序列化漏洞

2.2、打造poc

漏洞的触发点也是在于被序列化的json中的$types是否可控,为此官方文档里也标注了警告。

.NET高级代码审计(第三课)Fastjson反序列化漏洞

笔者继续选择objectdataprovider类方便调用任意被引用类中的方法,具体有关此类的用法可以看一下《.net高级代码审计(第一课) xmlserializer反序列化漏洞》,因为process.start方法启动一个线程需要配置processstartinfo类相关的属性,例如指定文件名、指定启动参数,所以首先得考虑序列化processstartinfo,如下代码demo

.NET高级代码审计(第三课)Fastjson反序列化漏洞

一步步来看,开始从gettype获取当前类的实例,返回type类型变量t3;然后通过type.getproperty方法找到指定为filename的公共属性并赋值给propertyinfo类型的变量propertyname;再使用propertyinfo.setvalue方法设置对象的指定属性值“cmd.exe“,同理为arguments属性指定值。下一步再来序列化process类,并调用startinfo启动程序,demo如下

.NET高级代码审计(第三课)Fastjson反序列化漏洞

然后需要对其做减法,去掉无关的system.runtimetype、system.intptr数据,最终得到反序列化payload

.NET高级代码审计(第三课)Fastjson反序列化漏洞

fastjson定义的json类定义了多个toobject重载方法,对于反序列化漏洞无需关心重载的方法参数是一个还是多个,它们都可以触发漏洞

.NET高级代码审计(第三课)Fastjson反序列化漏洞

笔者通过下面的demo , json.toobject(payload)反序列化成功弹出计算器。

.NET高级代码审计(第三课)Fastjson反序列化漏洞

0x03 代码审计视角

从代码审计的角度很容易找到漏洞的污染点,通过前面几个小节的知识能发现需要满足一个关键条件json.toobject传入string或者object就可以被反序列化,例如以下jsonserializer类

.NET高级代码审计(第三课)Fastjson反序列化漏洞

攻击者控制传入字符串参数json便可轻松实现反序列化漏洞攻击。github上也存在大量的不安全案例代码,如下

.NET高级代码审计(第三课)Fastjson反序列化漏洞

0x04 案例复盘

最后再通过下面案例来复盘整个过程,全程展示在vs里调试里通过反序列化漏洞弹出计算器。

1. 输入http://localhost:5651/default post加载value值

.NET高级代码审计(第三课)Fastjson反序列化漏洞

2. 通过toobject 反序列化 ,并弹出计算器

.NET高级代码审计(第三课)Fastjson反序列化漏洞

最后附个动态图

.NET高级代码审计(第三课)Fastjson反序列化漏洞

 

0x05 总结

fastjson凭借速度和性能上的优势占得一席之地,但随着newtonsoft.json的主流化,性能上已经逐渐赶超了fastjson,也使得fastjson越来越小众化,对于攻击者来说,利用成本很低,在代码审计配合的情况下这种安全问题越发的严重起来,若提交恶意的污染数据,便可水到渠成的反序列化成功拿下目标,最后.net反序列化系列课程笔者会同步到 https://github.com/ivan1ee/ 、 ,后续笔者将陆续推出高质量的.net反序列化漏洞文章,欢迎大伙持续关注,交流,更多的.net安全和技巧可关注实验室公众号。

.NET高级代码审计(第三课)Fastjson反序列化漏洞