NetDataContractSerializer wird wie DataContractSerializer zum Serialisieren und Deserialisieren von in Windows Communication Foundation (WCF)-Nachrichten gesendeten Daten verwendet. Es gibt einen wichtigen Unterschied zwischen den beiden: NetDataContractSerializer enthält die CLR und unterstützt die Typgenauigkeit durch das Hinzufügen zusätzlicher Informationen und das Speichern von Verweisen auf CLR-Typen, während DataContractSerializer dies nicht tut. Daher kann NetDataContractSerializer nur verwendet werden, wenn auf der Serialisierungs- und Deserialisierungsseite derselbe CLR-Typ verwendet wird. Um ein Objekt zu serialisieren, verwenden Sie die Methode „WriteObject“ oder „Serialize“ und zum Deserialisieren eines XML-Streams verwenden Sie die Methode „ReadObject“ oder „Deserialize“. In einigen Szenarien führt das Lesen eines bösartigen XML-Streams zu einer Deserialisierungsschwachstelle, wodurch ein Remote-RCE-Angriff erreicht wird. Der Autor dieses Artikels hat ihn aus der Perspektive der Prinzipien und Codeprüfung vorgestellt und reproduziert.
Mit WriteObject oder Serialize kann die Verbindung zwischen .NET-Objekten und XML-Datenkonvertierung sehr bequem realisiert werden Beachten Sie, dass NetDataContractSerializer den Namen der Assembly und den Typ des serialisierten Typs enthält. Diese zusätzlichen Informationen können verwendet werden, um XML in spezielle Typen zu deserialisieren, sodass derselbe Typ sowohl auf dem Client als auch auf dem Server verwendet werden kann. Zusätzliche Informationen sind, dass das z:Id-Attribut für verschiedene Elemente unterschiedliche Bedeutungen hat. Dies wird verwendet, um Referenztypen zu verarbeiten und ob die Referenz beim Deserialisieren des XML erhalten bleiben kann. Die endgültige Schlussfolgerung ist, dass diese Ausgabe mehr Informationen enthält als die Ausgabe von DataContractSerializer. Das Folgende ist ein Beispiel, um das Problem zu veranschaulichen. Definieren Sie zunächst das TestClass-Objekt
Das TestClass-Objekt definiert drei Mitglieder und implementiert eine statische Methode ClassMethod zum Starten der Prozess. Durch die Serialisierung werden den Mitgliedern Werte zugewiesen, indem jeweils Objektinstanzen erstellt werden Der XML-Stream wird durch Erstellen eines neuen Objekts in ein Objekt umgewandelt. Das Objekt wird durch Aufrufen mehrerer überladener Methoden von ReadObject oder der Serialize-Methode implementiert. Überprüfen Sie die Definition und stellen Sie fest, dass es von der abstrakten Klasse XmlObjectSerializer und der IFormatter-Schnittstelle erbt,
#🎜 🎜#
NetDataContractSerializer Die Klasse implementiert die Methoden WriteObject und ReadObject in der abstrakten Klasse XmlObjectSerializer sowie die in IFormatter definierten Methoden. Auf den spezifischen Implementierungscode des Autors, der die Deserialize-Methode durch Erstellen eines neuen Objekts aufruft, kann wie folgt verwiesen werden: Wird in der Deserialize-Methode zum Deserialisieren aufgerufen. Im Deserialisierungsprozess wird die ReadObject-Methode verwendet, um die ReadObjectHandleExceptions-Methode aufzurufen, wobei einige nicht zum Kern gehörende Codes weggelassen werden und nach der Deserialisierung der Wert der InternalReadObject-Methode eingegeben wird Mitgliedsname.
3.2 Angriffsvektor – MulticastDelegateMulticast-Delegat (MulticastDelegate) erbt von Delegate und kann in seiner Anrufliste Delegate enthalten sein Bei mehreren Elementen werden tatsächlich alle Delegattypen von MulticastDelegate abgeleitet. Das Feld _invocationList der Klasse MulticastDelegate verweist beim Aufbau der Delegationskette auf das Delegationsarray. Um jedoch mehr Kontrolle über die Delegationskette zu erhalten, müssen Sie die Methode GetInvocationList verwenden. Sie verfügt über eine Delegatenliste mit Links und ruft die Delegateninstanz auf Wenn es soweit ist, werden synchrone Aufrufe in der Reihenfolge der Delegaten in der Liste durchgeführt. Wie fügt man also calc.exe zur GetInvocationList-Listenmethode hinzu? Schauen Sie sich zunächst die Compare使用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>
最后附上动态效果图
Das obige ist der detaillierte Inhalt vonSo führen Sie eine NetDataContractSerializer-Deserialisierungs-Schwachstellenanalyse durch. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!