Giới Thiệu
Bài viết này nhằm cung cấp cái nhìn tổng quan về lỗ hổng RCE (Remote Code Execution) khi sử dụng .NET deserialization, đặc biệt là thông qua lớp XmlSerializer. Mặc dù đã có nhiều nghiên cứu trước đây, nhưng mình nhận thấy rằng cần có một bài viết hệ thống, giúp dễ dàng tham khảo về tất cả các tình huống liên quan đến vấn đề này.
XmlSerializer Là Gì?
XmlSerializer là một lớp do Microsoft cung cấp, được thiết kế để chuyển đổi giữa các đối tượng trong .NET và định dạng XML. Nó thuộc namespace System.Xml.Serialization
và có khả năng serialize và deserialize các thuộc tính và trường công khai của đối tượng.
Ví Dụ Về XmlSerializer
Mã ví dụ sau sẽ minh họa cách sử dụng XmlSerializer:
csharp
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace XmlDeserialization
{
[XmlRoot]
public class Person
{
[XmlElement]
public int Age { get; set; }
[XmlElement]
public string Name { get; set; }
[XmlArray("Items")]
public Order[] OrderedItems;
[XmlAttribute]
public string ClassName { get; set; }
}
public class Order
{
public int OrderID;
}
class Program
{
static void Main(string[] args)
{
Person p = new Person { Name = "jack", Age = 12, ClassName = "classname" };
p.OrderedItems = new Order[] { new Order { OrderID = 123 }, new Order { OrderID = 456 } };
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));
using (MemoryStream memoryStream = new MemoryStream())
{
using (TextWriter writer = new StreamWriter(memoryStream))
{
xmlSerializer.Serialize(writer, p);
}
memoryStream.Position = 0;
Person p1 = (Person)xmlSerializer.Deserialize(memoryStream);
Console.WriteLine(p1.Name);
}
}
}
}
Kết Quả Đầu Ra
Khi chạy đoạn mã trên, ta nhận được kết quả là:
<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ClassName="classname">
<Items>
<Order>
<OrderID>123</OrderID>
</Order>
<Order>
<OrderID>456</OrderID>
</Order>
</Items>
<Age>12</Age>
<Name>jack</Name>
</Person>
Điều Kiện Gây Ra Lỗ Hổng RCE
Để có thể thực hiện tấn công RCE thông qua XmlSerializer, kẻ tấn công cần phải có quyền điều khiển kiểu dữ liệu được truyền vào constructor của XmlSerializer. Như vậy, chỉ cần điều chỉnh kiểu dữ liệu dẫn đến gadget chính xác, lỗ hổng RCE sẽ được kích hoạt.
Giải Thích Về Gadget Tấn Công
Một gadget phổ biến có thể giúp thực hiện tấn công RCE là ObjectDataProvider
, sử dụng công cụ ysoserial .net
. Gadget này cho phép kẻ tấn công gọi đến bất kỳ phương thức nào của bất kỳ lớp nào trong ứng dụng, do đó tạo ra khả năng thực thi mã tùy ý.
Cách Tạo Payload
Bằng cách sử dụng ObjectDataProvider
, ta có thể thực hiện các lệnh như sau:
csharp
ObjectDataProvider o = new ObjectDataProvider();
o.MethodParameters.Add("cmd.exe");
o.MethodParameters.Add("/c calc");
o.MethodName = "Start";
o.ObjectInstance = new Process();
Truyền ObjectDataProvider
vào XmlSerializer giúp kích hoạt phương thức tập lệnh chạy ẩn.
Điều Kiện Thành Công của Payload
Điều quan trọng là phải cung cấp các loại đối tượng để XmlSerializer nhận biết, nếu không sẽ dẫn đến lỗi khi thực thi. Giao tiếp cho các loại đối tượng này là vô cùng quan trọng để đảm bảo khả năng thực hiện lệnh.
Kết Luận
Quá trình tìm kiếm lỗ hổng RCE thông qua XmlSerializer bao gồm việc kiểm tra khả năng điều khiển kiểu dữ liệu truyền vào. Đặc biệt, nếu có thể chi phối XML truyền vào XamlReader.Parse
, thì khả năng thực thi lệnh tùy ý là hoàn toàn khả thi. Bài viết tiếp theo sẽ đi sâu hơn vào các tình huống và kiểu dữ liệu khác trong .NET deserialization.
Tham Khảo
Để tìm hiểu thêm, bạn có thể truy cập vào GitHub của Y4er.
source: viblo