이 게시물은 ObjectDataProvider 가젯이 어떻게 악용되어 RCE를 얻는지와 Serialization 라이브러리 Json.Net 및 xmlSerializer가 그 가젯과 함께 악용될 수 있는 방법을 이해하는 데 전념되어 있습니다.
ObjectDataProvider 가젯
문서에서: ObjectDataProvider 클래스는 바인딩 소스로 사용할 수 있는 객체를 래핑하고 생성합니다.
그래, 이상한 설명이죠. 그래서 이 클래스가 흥미로운 이유는 무엇인지 살펴봅시다: 이 클래스는 임의의 객체를 래핑하고, _MethodParameters_를 사용하여 임의의 매개변수를 설정하고, 그런 다음 MethodName을 사용하여 임의의 함수를 호출할 수 있습니다.
따라서, 임의의 객체는 역직렬화될 때매개변수와 함께 함수를 실행할 것입니다.
이것이 어떻게 가능한가요
System.Windows.Data 네임스페이스는 PresentationFramework.dll에 있으며 C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF에서 ObjectDataProvider가 정의되고 구현됩니다.
dnSpy를 사용하여 관심 있는 클래스의 코드를 검사할 수 있습니다. 아래 이미지에서 우리는 PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name의 코드를 보고 있습니다.
MethodName이 설정되면 base.Refresh()가 호출되는 것을 확인할 수 있습니다. 이것이 무엇을 하는지 살펴봅시다:
좋아요, this.BeginQuery()가 무엇을 하는지 계속 살펴봅시다. BeginQuery는 ObjectDataProvider에 의해 재정의되며 다음을 수행합니다:
코드 끝에서 this.QueryWorke(null)를 호출하는 것을 주목하세요. 이것이 무엇을 실행하는지 살펴봅시다:
이것이 QueryWorker 함수의 전체 코드는 아니지만, 그 중요한 부분을 보여줍니다: 코드는 this.InvokeMethodOnInstance(out ex);를 호출하는데, 이것이 설정된 메소드가 호출되는 라인입니다.
_MethodName_만 설정하면 실행된다는 것을 확인하고 싶다면, 다음 코드를 실행할 수 있습니다:
using System.Windows.Data;using System.Diagnostics;namespace ODPCustomSerialExample{classProgram{staticvoidMain(string[] args){ObjectDataProvider myODP =newObjectDataProvider();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
이전 exploit을 사용하면 object가 ObjectDataProvider 인스턴스로 역직렬화될 경우가 있습니다 (예: DotNetDuke 취약점에서는 XmlSerializer를 사용하여 GetType을 사용하여 object가 역직렬화되었습니다). 그런 다음, ObjectDataProvider 인스턴스에 감싸인 object type에 대한 지식이 없을 것입니다 (Process 예를 들어). DotNetDuke 취약점에 대한 자세한 정보는 여기에서 확인할 수 있습니다.
이 클래스는 주어진 인스턴스에 캡슐화된 object types를 지정할 수 있습니다. 따라서, 이 클래스는 소스 object (ObjectDataProvider)를 새로운 object type으로 캡슐화하고 필요한 속성들을 제공할 수 있습니다 (ObjectDataProvider.MethodName 및 ObjectDataProvider.MethodParameters).
이전에 제시된 경우와 같이 매우 유용합니다. 왜냐하면 우리는 _ObjectDataProvider**를 **ExpandedWrapper _ 인스턴스 내부에 감쌀 수 있기 때문에 이 클래스가 역직렬화될 때 _MethodName_에 지정된 함수를 실행할 OjectDataProvider object를 생성할 수 있습니다.
다음 코드로 이 wrapper를 확인할 수 있습니다:
using System.Windows.Data;using System.Diagnostics;using System.Data.Services.Internal;namespace ODPCustomSerialExample{classProgram{staticvoidMain(string[] args){ExpandedWrapper<Process,ObjectDataProvider> myExpWrap =newExpandedWrapper<Process,ObjectDataProvider>();myExpWrap.ProjectedProperty0=newObjectDataProvider();myExpWrap.ProjectedProperty0.ObjectInstance=newProcess();myExpWrap.ProjectedProperty0.MethodParameters.Add("cmd.exe");myExpWrap.ProjectedProperty0.MethodParameters.Add("/c calc.exe");myExpWrap.ProjectedProperty0.MethodName="Start";}}}
Json.Net
공식 웹 페이지에는 이 라이브러리가 Json.NET의 강력한 JSON 직렬화기를 사용하여 .NET 객체를 직렬화 및 역직렬화할 수 있다고 나와 있습니다. 따라서, 만약 우리가 ObjectDataProvider 가젯을 역직렬화할 수 있다면, 객체를 역직렬화함으로써 RCE를 유발할 수 있습니다.