JavaScript Serializer反序列化漏洞是怎样的

JavaScript Serializer反序列化漏洞是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

一、前言

在.NET处理 Ajax应用的时候,通常序列化功能由JavaScriptSerializer类提供,它是.NET2.0之后内部实现的序列化功能的类,位于命名空间System.Web.Script.Serialization、通过System.Web.Extensions引用,让开发者轻松实现.Net中所有类型和Json数据之间的转换,但在某些场景下开发者使用Deserialize 或DeserializeObject方法处理不安全的Json数据时会造成反序列化攻击从而实现远程RCE漏洞。笔者从原理和代码审计的视角做了相关介绍和复现。

前文回顾:

.NET高级代码审计之XmlSerializer反序列化漏洞

.NET高级代码审计(第二课) Json.Net反序列化漏洞

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

JavaScript Serializer反序列化漏洞是怎样的

二、JavaScriptSerializer序列化

下面先来看这个系列课程中经典的一段代码:

JavaScript Serializer反序列化漏洞是怎样的

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

JavaScript Serializer反序列化漏洞是怎样的

使用JavaScriptSerializer类中的Serialize方法非常方便的实现.NET对象与Json数据之间的转化,笔者定义TestClass对象,常规下使用Serialize得到序列化后的Json

JavaScript Serializer反序列化漏洞是怎样的

从之前介绍过其它组件反序列化漏洞原理得知需要__type这个Key的值,要得到这个Value就必须得到程序集全标识(包括程序集名称、版本、语言文化和公钥),那么在JavaScriptSerializer中可以通过实例化SimpleTypeResolver类,作用是为托管类型提供类型解析器,可在序列化字符串中自定义类型的元数据程序集限定名称。笔者将代码改写添加类型解析器 

JavaScript Serializer反序列化漏洞是怎样的

这次序列化输出程序集的完整标识,如下

JavaScript Serializer反序列化漏洞是怎样的

三、JavaScriptSerializer反序列化

3.1 反序列化用法

反序列化过程就是将Json数据转换为对象,在JavaScriptSerializer类中创建对象然后调用DeserializeObject或Deserialize方法实现的。

JavaScript Serializer反序列化漏洞是怎样的

JavaScript Serializer反序列化漏洞是怎样的在BasicDeserialize内部又调用了DeserializeInternal方法,当需要转换为对象的时候会判断字典集合中是否包含了ServerTypeFieldName常量的Key,

JavaScript Serializer反序列化漏洞是怎样的ServerTypeFieldName常量在JavaScriptSerializer类中定义的值为“__type”,

JavaScript Serializer反序列化漏洞是怎样的

剥茧抽丝,忽略掉非核心方法块ConvertObjectToType、ConvertObjectToTypeMain 、ConvertObjectToTypeInternal,最后定位到ConvertDictionaryToObject方法内

JavaScript Serializer反序列化漏洞是怎样的

这段代码首先判断ServerTypeFieldName存在值的话就输出赋值给对象s,第二步将对象s强制转换为字符串变量serverTypeName,第三部获取解析器中的实际类型,并且通过System.Activator的CreateInstance构造类型的实例

JavaScript Serializer反序列化漏洞是怎样的

Activator类提供了静态CreateInstance方法的几个重载版本,调用方法的时候既可以传递一个Type对象引用,也可以传递标识了类型的String,方法返回对新对象的引用。下图Demo展示了序列化和反序列化前后的效果:

JavaScript Serializer反序列化漏洞是怎样的

反序列化后得到对象的属性,打印输出当前的成员Name的值

3.2 打造Poc

默认情况下JavaScriptSerializer不会使用类型解析器,所以它是一个安全的序列化处理类,漏洞的触发点也是在于初始化JavaScriptSerializer类的实例的时候是否创建了SimpleTypeResolver类,如果创建了,并且反序列化的Json数据在可控的情况下就可以触发反序列化漏洞,借图来说明调用链过程

JavaScript Serializer反序列化漏洞是怎样的

笔者还是选择ObjectDataProvider类方便调用任意被引用类中的方法,具体有关此类的用法可以看一下《.NET高级代码审计(第一课) XmlSerializer反序列化漏洞》,因为Process.Start方法启动一个线程需要配置ProcessStartInfo类相关的属性,例如指定文件名、指定启动参数,所以首先得考虑序列化ProcessStartInfo,这块可参考《.NET高级代码审计(第三课) Fastjson反序列化漏洞》 ,之后对生成的数据做减法,去掉无关的System.RuntimeType、System.IntPtr数据,最终得到反序列化Poc

JavaScript Serializer反序列化漏洞是怎样的

笔者编写了触发代码,用Deserialize<Object>反序列化Json成功弹出计算器

JavaScript Serializer反序列化漏洞是怎样的

JavaScript Serializer反序列化漏洞是怎样的

四、代码审计视角

4.1 Deserialize

从代码审计的角度其实很容易找到漏洞的污染点,通过前面几个小节的知识能发现需要满足一个关键条件new SimpleTypeResolver() ,再传入Json数据,就可被反序列化,例如下面的JsonHelper类

JavaScript Serializer反序列化漏洞是怎样的攻击者只需要控制传入字符串参数input便可轻松实现反序列化漏洞攻击。Github上也存在大量的不安全案例代码
JavaScript Serializer反序列化漏洞是怎样的

4.2 DeserializeObject

JavaScriptSerializer还有一个反序列化方法DeserializeObject,这个方法同样可以触发漏洞,具体污染代码如下

JavaScript Serializer反序列化漏洞是怎样的

五、案例复盘

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

1.    输入http://localhost:5651/Default Post加载value值

JavaScript Serializer反序列化漏洞是怎样的

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

JavaScript Serializer反序列化漏洞是怎样的

最后附个动态图:

JavaScript Serializer反序列化漏洞是怎样的

六、总结

JavaScriptSerializer凭借微软自身提供的优势,在实际开发中使用率还是比较高的,只要没有使用类型解析器或者将类型解析器配置为白名单中的有效类型就可以防止反序列化攻击(默认就是安全的序列化器),对于攻击者来说实际场景下估计利用概率不算高,毕竟很多开发者不会使用SimpleTypeResolver类去处理数据。

看完上述内容,你们掌握JavaScript Serializer反序列化漏洞是怎样的的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/227385.html

(0)
上一篇 2022年1月10日
下一篇 2022年1月10日

相关推荐

发表回复

登录后才能评论