在.net中经常能够看到使用JavaScriptSerializer进行反序列化的操作,有些甚至序列化的内容都可控。
相比JAVA反序列化漏洞很少听说.NET反序列化相关的漏洞,这是因为.NET反序列化相关的漏洞需要一定的前提条件。
这里研究JavaScriptSerializer 这个反序列化漏洞。
下面是一个存在漏洞的示例:
using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Script.Serialization;
using System.Net;
using System.Text;
using Newtonsoft.Json;
namespace deserial
{
public class Class1
{
public static void Main()
{
string json = "{\"__type\":\"sss\"}";
Dictionary<string, object> dictionary = new Dictionary<string, object>();
try
{
Dictionary<string, object> dictionary2 = new JavaScriptSerializer(new SimpleTypeResolver()).Deserialize<Dictionary<string, object>>(json);
foreach (var kvp in dictionary2)
{
Console.WriteLine("Key: {0}, Value: {1}", kvp.Key, kvp.Value);
}
}
catch (Exception ex)
{
Console.WriteLine("反序列化异常信息:\r\n {0}", ex.ToString());
Console.WriteLine(ex.Message);
}
}
}
}
当执行上述代码时,会报错(对象当前状态操作无效)。
而当去掉代码中的
new SimpleTypeResolver() 属性,则会产生下面的报错:类型不能为空
这里不得不说
new SimpleTypeResolver() 的作用了:
- SimpleTypeResolver属性作用
- 该属性的作用是,允许 JavaScriptSerializer 反序列化 JSON 字符串中包含的 CLR 类型。如果不设置该属性,则 JSON 字符串中的
__type属性将被忽略,而 JavaScriptSerializer 将根据 JSON 字符串中的属性名和值类型推断出 CLR 类型。这种推断机制可能会被攻击者利用来注入恶意代码,从而造成安全风险。 - 通过设置
new SimpleTypeResolver()属性,可以强制 JavaScriptSerializer 反序列化 JSON 字符串中指定的 CLR 类型。这样,就可以避免攻击者利用属性名和值类型进行类型注入攻击。同时,建议在反序列化之前,使用一个白名单机制来过滤可以反序列化的类型,从而进一步提高安全性。
通过上述可以得知,在JavaScriptSerializer反序列化中,如果没有设置SimpleTypeResolver() 属性,则认为该反序列化过程是安全的。否则就要自己严格的设置类型过滤了。
仅如下代码才会出发漏洞,所以目前.net中很少存在JavaScriptSerializer反序列化漏洞。
参考
https://github.com/pwntester/ysoserial.net/issues/73
https://xz.aliyun.com/t/4872