0
0
Lập trình
Harry Tran
Harry Tran106580903228332612117

Khám Phá Lỗ Hổng .NET Deserialization: Phần 3 - Tấn Công với DataContractSerializer và DataContractJsonSerializer

Đăng vào 3 tuần trước

• 6 phút đọc

Giới Thiệu Về Lỗ Hổng .NET Deserialization

Bài viết này là phần thứ ba trong seri các bài viết về lỗ hổng .NET deserialization. Ở phần này, chúng ta sẽ tìm hiểu về tấn công .NET deserialization thông qua hai thành phần quan trọng: DataContractSerializerDataContractJsonSerializer.

DataContractSerializer

DataContractSerializer là một công cụ mạnh mẽ trong .NET, cho phép chuyển đổi các đối tượng thành dạng stream hoặc tài liệu XML dựa trên một DataContract đã được xác định trước. Công cụ này thường được sử dụng trong các ứng dụng WCF (Windows Communication Foundation) để xử lý dữ liệu

Ví Dụ Về DataContractSerializer

Để sử dụng DataContractSerializer, trước tiên, bạn cần phải chỉ định kiểu dữ liệu bằng cách sử dụng thuộc tính DataContract trên lớp chính, và thuộc tính DataMember trên các thuộc tính mà bạn muốn serialize.

csharp Copy
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace DataContractDeserialize
{
    [DataContract(Name = "Customer", Namespace = "http://www.contoso.com")]
    class Person
    {
        [DataMember()]
        public string FirstName;
        [DataMember]
        public string LastName;
        [DataMember()]
        public int Age;

        public Person(string newfName, string newLName, int age)
        {
            FirstName = newfName;
            LastName = newLName;
            Age = age;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WriteObject("DataContractSerializerExample.xml");
                ReadObject("DataContractSerializerExample.xml");
            }

            catch (SerializationException serExc)
            {
                Console.WriteLine("Serialization Failed");
                Console.WriteLine(serExc.Message);
            }
            catch (Exception exc)
            {
                Console.WriteLine("The serialization operation failed: {0} StackTrace: {1}," , exc.Message, exc.StackTrace);
            }
            finally
            {
                Console.WriteLine("Press <Enter> to exit....");
                Console.ReadLine();
            }
        }

        public static void WriteObject(string fileName)
        {
            Console.WriteLine("Creating a Person object and serializing it.");
            Person p1 = new Person("bill", "gates", 100);
            FileStream writer = new FileStream(fileName, FileMode.Create);
            DataContractSerializer ser = new DataContractSerializer(typeof(Person));
            ser.WriteObject(writer, p1);
            writer.Close();
        }

        public static void ReadObject(string fileName)
        {
            Console.WriteLine("Deserializing an instance of the object.");
            FileStream fs = new FileStream(fileName, FileMode.Open);
            XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
            DataContractSerializer ser = new DataContractSerializer(typeof(Person));

            Person deserializedPerson = (Person)ser.ReadObject(reader, true);
            reader.Close();
            fs.Close();
            Console.WriteLine(String.Format("{0} {1}, Age: {2}", deserializedPerson.FirstName, deserializedPerson.LastName, deserializedPerson.Age));
        }
    }
}

Khi chạy đoạn mã trên, file XML tạo ra có nội dung như sau:

xml Copy
<Customer xmlns="http://www.contoso.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Age>100</Age>
    <FirstName>bill</FirstName>
    <LastName>gates</LastName>
</Customer>

Điều Kiện Để Trigger RCE (Remote Code Execution)

  1. Kiểu dữ liệu object phải được truyền vào constructor của DataContractSerializer.
  2. Object cần deserialized phải chứa property kiểu object (để chèn gadget).
  3. Các kiểu dữ liệu gadget phải nằm trong KnownType hoặc DataContractResolver có phương thức ResolveName.

Thực Hiện Áp Dụng RCE với Gadget

Ví dụ về gadget được sử dụng cho việc khai thác RCE:

csharp Copy
using System;
using System.IO;
using System.Runtime.Serialization;

namespace DataContractDeserialize
{
    [Serializable]
    public class RCE
    {
        private string _cmd;

        public string cmd
        {
            get { return _cmd; }
            set { _cmd = value; Run(); }
        }

        private void Run()
        {
            if (!string.IsNullOrEmpty(_cmd))
            {
                System.Diagnostics.Process.Start(_cmd);
            }
        }
    }
}

DataContractJsonSerializer

Ngoài DataContractSerializer, DataContractJsonSerializer cũng cho phép chúng ta chuyển đổi giữa các đối tượng và định dạng JSON. Tương tự như cách mà DataContractSerializer thực hiện, DataContractJsonSerializer yêu cầu các lớp được serializable phải có thuộc tính DataContract và các thuộc tính cần serializable phải có thuộc tính DataMember.

csharp Copy
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

namespace DataContractJsonDeserializer
{
    [DataContract]
    class Person
    {
        [DataMember]
        internal string name;
        [DataMember]
        internal int age;
    }
}

Điều Kiện Để Trigger RCE Với DataContractJsonSerializer

  1. Kiểu dữ liệu phải được biết trong knownTypes.
  2. Có thể sử dụng IDataContractSurrogate để kiểm soát việc serialization cho các lớp không được đánh dấu với DataContract.

Kết Luận

Lỗ hổng .NET deserialization cung cấp một cơ hội cho kẻ tấn công thực hiện Remote Code Execution nếu các ứng dụng không được cấu hình an toàn. Việc hiểu rõ về DataContractSerializer và DataContractJsonSerializer là rất quan trọng trong việc bảo vệ ứng dụng của bạn.

Hãy theo dõi các bài viết tiếp theo trong seri này để tìm hiểu thêm về các kỹ thuật khai thác lỗ hổng trong .NET.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào