Skip to content

.Net XML Serializer / Deserializer

  • Problem
    • type of object that will be desirelized is provided in xml
    • user can change that type
    • compere dot-net-example.xml (intended file) and dot-net-example-cmd.xml (malicious file)
./DotNetXMLSerializer2 MichalSzalkowski "/home/kali/workspace/code/dot-net-example.xml"
./DotNetXMLDeserializer2 ~/workspace/code/dot-net-example.xml
./DotNetXMLDeserializer2 ~/workspace/code/dot-net-example-cmd.xml
dotnet build

DotNetXMLSerializer2 - Program.cs

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace DotNetXMLSerializer2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyText myText = new MyText();
            myText.text = args[0];
            String xmlLocationPath = args[1];

            MySerializer(myText, xmlLocationPath);
        }

        static void MySerializer(Object obj, String xmlLocationPath)
        {
            XmlDocument xmlDocument = new XmlDocument();
            XmlElement xmlElement = xmlDocument.CreateElement("wrapper");
            xmlElement.SetAttribute("type", obj.GetType().AssemblyQualifiedName);
            xmlDocument.AppendChild(xmlElement);
            xmlElement.AppendChild(XMLNote(obj, xmlDocument));
            File.WriteAllText(xmlLocationPath, xmlDocument.OuterXml);

        }

        private static XmlNode XMLNote(object obj, XmlDocument xmlDocument)
        {
            XmlDocument xmlDocument2 = new XmlDocument();
            XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
            StringWriter writer = new StringWriter();
            xmlSerializer.Serialize(writer, obj);
            xmlDocument2.LoadXml(writer.ToString());
            XmlNode xmlNode = xmlDocument.ImportNode(xmlDocument2.DocumentElement, true);
            return xmlNode;
        }
    }
}
namespace DotNetXMLSerializer2
{
    public class MyText
    {
        private String _text = "Default";

        public String text
        {
            get { return _text; }
            set { _text = value; Console.WriteLine("Console text = " + _text); }
        }
    }
}

cat dot-net-example.xml
<wrapper type="DotNetXMLSerializer2.MyText, DotNetXMLSerializer2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <MyText xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <text>MichalSzalkowski2</text>
    </MyText>
</wrapper>

cat dot-net-example-cmd.xml
<wrapper type="DotNetXMLDeserializer2.ExecCMD, DotNetXMLDeserializer2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <ExecCMD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <cmd>mousepad</cmd>
    </ExecCMD>
</wrapper>

DotNetXMLDeserializer2 - Program

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using DotNetXMLSerializer2;

namespace DotNetXMLDeserializer2
{
    class Program
    {
        static void Main(string[] args)
        {
            String xml = File.ReadAllText(args[0]);
            MyDeserializer(xml);   
        }

        static void MyDeserializer(String myXMLString)
        {
            var xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(myXMLString);

            var type = Type.GetType(xmlDocument!.DocumentElement!.GetAttribute("type"));
            var xmlSerializer = new XmlSerializer(type!);

            var reader = new XmlTextReader(new StringReader(xmlDocument!.FirstChild!.InnerXml));
            xmlSerializer.Deserialize(reader);

        }

    }
}

DotNetXMLDeserializer2 - ExecCMD

using System.Diagnostics;

namespace DotNetXMLDeserializer2
{
    public class ExecCMD
    {
        private String _cmd;
        public String cmd
        {
            get { return _cmd; }
            set
            {
                _cmd = value;
                ExecCommand();
            }
        }

        private void ExecCommand()
        {
            Process process = new Process();
            process.StartInfo.FileName = _cmd;
            // process.StartInfo.Arguments = "";
            process.Start();
            process.Dispose();
        }
    }
}