在.net中经常能够看到使用JavaScriptSerializer进行反序列化的操作,有些甚至序列化的内容都可控。

Pasted_image_20240802214319.png

相比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);
            }
        }
    }
}

当执行上述代码时,会报错(对象当前状态操作无效)。

Pasted_image_20240802214445.png

而当去掉代码中的 new SimpleTypeResolver() 属性,则会产生下面的报错:类型不能为空
Pasted_image_20240802214518.png

这里不得不说 new SimpleTypeResolver() 的作用了:
  • SimpleTypeResolver属性作用
  • 该属性的作用是,允许 JavaScriptSerializer 反序列化 JSON 字符串中包含的 CLR 类型。如果不设置该属性,则 JSON 字符串中的 __type 属性将被忽略,而 JavaScriptSerializer 将根据 JSON 字符串中的属性名和值类型推断出 CLR 类型。这种推断机制可能会被攻击者利用来注入恶意代码,从而造成安全风险。
  • 通过设置 new SimpleTypeResolver() 属性,可以强制 JavaScriptSerializer 反序列化 JSON 字符串中指定的 CLR 类型。这样,就可以避免攻击者利用属性名和值类型进行类型注入攻击。同时,建议在反序列化之前,使用一个白名单机制来过滤可以反序列化的类型,从而进一步提高安全性。

通过上述可以得知,在JavaScriptSerializer反序列化中,如果没有设置SimpleTypeResolver() 属性,则认为该反序列化过程是安全的。否则就要自己严格的设置类型过滤了。

仅如下代码才会出发漏洞,所以目前.net中很少存在JavaScriptSerializer反序列化漏洞。

Pasted_image_20240802214707.png

参考

https://github.com/pwntester/ysoserial.net/issues/73
https://xz.aliyun.com/t/4872