Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
spark-connect-archive-fragment — Apache Spark 4.2.0 - 高 - リモート - ファイル書き込み - Connect アーカイブのハッシュフラグメント先 | Kitploit
ツール/GitHubGitHub/abraxas/spark-connect-archive-fragment
脆弱性分析エクスプロイトウェブアプリケーション悪用セキュリティ仮想化ペネトレーションテストレッドチーミングラボと実践
GitHubabraxas/spark-connect-archive-fragment

spark-connect-archive-fragment

Apache Spark 4.2.0 - 高 - リモート - ファイル書き込み - Connect アーカイブのハッシュフラグメント先

リポジトリを見る
2日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Abraxas Labs - spark-connect-archive-fragment

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-connect-archive-fragment

spark-connect-archive-fragment

クラス: ファイル書き込み 到達範囲: リモート

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

Spark Connect の AddArtifacts 名は archives/<file>#<fragment> の形式で、ハッシュ / 番号記号文字で分割されます。zip バイト列は concatenatePaths を通過します。フラグメントは通過しません。その後 SparkContext.addFile(..., isArchive=true) がドライバ上で new File(root, uri.getFragment)、deleteRecursively(dest)、unpack を実行します。エグゼキュータも同じ dest を構築します。SPARK-33530 は #name を SparkFiles 配下のディレクトリ名として文書化しました。../<outside> というフラグメントが dest になります。

Connect の archives/<file>#../<path> は、Spark UID としてセッションの SparkFiles ディレクトリ外で展開し deleteRecursively します。

IDCVE 未割当
クラスファイル書き込み
到達範囲リモート (Spark Connect クライアント; archive=True を指定した AddArtifacts)
CWECWE-22
CVSSHigh: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
製品Apache Spark
影響を受けるバージョン4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) Connect archives/ ハッシュフラグメント dest
認証Connect クライアント。デフォルトの Connect には PSK がありません (spark.connect.authenticate.token 未設定)。PSK / ネットワーク ACL がある場合は PR:L、デフォルトのオープンな Connect では PR:N。
ライセンスGNU Affero GPL v3.0
ラボ127.0.0.1 のみ

タグ v4.2.0 のピール 32f72996 (2026-07-11, v4.2.0-rc6) を固定しました。ラボは、固定した StagedArtifact のハッシュ分割、ArtifactUtils.concatenatePaths、new File(root, fragment)、deleteRecursively、および dest 内に収まる zip 展開の Java ガジェットです。127.0.0.1:18930 でのループバック HTTP。公式 PySpark はすでに URI フラグメントをアーカイブ名にコピーしています。

これは RCE ではありません。dest から外に出る zip メンバーは拒否されます (Hadoop FileUtil.unZip / HADOOP-13649 クラス)。残るのは dest 自体です。

攻撃者ができること

手法シンク権限
Connect AddArtifacts 名 archives/<file>#../<outside>SparkContext.addFile の dest new File(root, uri.getFragment) の後 Utils.unpack (SparkContext.scala:1891-1900)完全性 (ラボで実証): セッションの SparkFiles 外に Spark UID としてアーカイブメンバーを書き込みます。ラボの dest 正規パス /lab/oracle/SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS、uid 1000、dest-outside=yes。
同じ dest、展開前Utils.deleteRecursively(dest) (SparkContext.scala:1899)可用性 (ラボで実証): dest のカナリアが消えました。ラボ deleteRecursively=yes; dest 配下の canary.txt は残りませんでした。兄弟の /lab/oracle/canary-keep.txt は保持されました。
アーカイブを取得する各エグゼキュータ上の同じプリミティブExecutor の dest new File(root, sourceURI.getFragment) の後 deleteRecursively + unpack (Executor.scala:1468-1477)完全性 / 可用性 (推測): エグゼキュータ上でも同じ dest 構築。ラボはドライバ側のガジェットです。
アーティファクト 名 files/../../... または archives/../../...ArtifactUtils.concatenatePaths (ArtifactUtils.scala:26-39)クローズ (ラボで実証): INVALID_ARTIFACT_PATH。
Unix 絶対フラグメント /absnew File(root, "/abs")Unix ではクローズ (ラボで実証): 親は無視されず、dest は root 配下に結合されます。ラボの dest /lab/root/lab/oracle/abs-...、outside=false、abs カナリアは保持。
自セッションの jars/ / classes/ 追加セッション URLClassLoader残存物としてはクローズ: 自セッションの JAR ロードは設計上の動作。本件の脆弱性ではありません。
クロスセッションの jar ロードConnect 分離 spark.sql.artifact.isolation.enabled=trueクローズ: 分離されたセッションは addedJars(sessionUUID) を読み取ります。

ラボで実証 vs 推測: SparkFiles 外へのハッシュフラグメント dest、dest カナリアの削除、兄弟カナリアの保持、files/ と archives/ の名前連結の拒否、Unix 絶対フラグメントが root 配下に結合、uid 1000、dest 内に収まる zip 展開: ラボ。同じ dest のエグゼキュータ取得: 推測 (同じコンストラクタ)。ドライバのクラスパス上で後からロードされるクラスの上書き: 推測される連鎖であり、実証されておらず、RCE に誇張されていません。

必要条件: archive=True で AddArtifacts を実行できる Connect クライアント。公式 PySpark の spark.addArtifact(..., archive=True) はすでに空でない URI フラグメントを名前に含めています (python/pyspark/sql/connect/client/artifact.py:223-236)。デフォルトの Connect には PSK がありません。

クローズのままの隣接する攻撃面

攻撃面ラボ
concatenatePaths を通るアーティファクト名 .. / 絶対パスfiles-concat=rejected INVALID_ARTIFACT_PATH
archives/ 名 の archives/../../... 走査同じ INVALID_ARTIFACT_PATH
Unix new File(root, "/abs")dest は root 配下; abs オラクルカナリアは保持
収まる dest 配下での zip メンバーの zip-slipガジェットは dest から脱出するメンバーを拒否 (HADOOP-13649 クラス)。本件の残存物ではありません。
files/ パス連結 (ハッシュ分割なし)フラグメントは取得されず、名前は依然 concatenatePaths
クロスセッションの jar 分離Connect ではデフォルトで有効
オープンな Connect での未認証 SQL / Python設計上のジョブ投入 (SECURITY.md FAQ)。本件の残存物ではありません。
ジョブ投入 / ML モデルロード設計上

発見の経緯

StagedArtifact は archives とサーバの File.separator で始まる名前のみを分割し、# でのみ分割します:

val splits = name.split("#")
if (splits.length == 2) {
  (splits(0), Some(splits(1)))
}

splits(0) は concatenatePaths を介してステージングされます。splits(1) は fragment として保持されます。ArtifactManager はそのフラグメントをセッションのファイルサーバ URI に付加し、SparkContext.addArchive を呼び出します。dest は new File(root, uri.getFragment) です。SPARK-33530 は sc.addArchive(s"${jarFile.getAbsolutePath}#foo") を SparkFiles 配下のディレクトリ名としてテストしています。

ハントの最初のパスでは、Unix 絶対フラグメントが root を無視すると主張しました (java.io.File は絶対パスの子で親を無視)。Unix では new File(root, "/abs") は先頭のスラッシュを除去し root 配下に結合します。親が無視されるのは Windows のみです。このピンでの High の走査は #../ です。

ラボ

cd lab
./run.sh

ループバック 127.0.0.1:18930。Compose プロジェクト spark-connect-archive-fragment。イメージ eclipse-temurin:21-jdk-jammy、ランタイム uid 1000。ウィットネス SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS。最終行:

SUCCESS SPARK-CONNECT-ARCHIVE-FRAGMENT how=gadget dest-outside=yes deleteRecursively=yes files-concat=rejected uid=1000 SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS

CONTROL: archives/payload.zip は /lab/root 配下に展開されます。ATTACK: archives/payload-frag.zip#../oracle/SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS の dest 正規パス /lab/oracle/...、カナリア削除、pwned.txt が uid 1000 として書き込まれます。Unix 絶対フラグメントは root 配下に結合します。スタックは EXIT で破棄されます。

修正

アーカイブフラグメントを、アーティファクト名と同じ root 配下に留まるチェック (concatenatePaths、または .. / 絶対パスの拒否) に通してください。SPARK-33530 の #name は SparkFiles 配下の単一ディレクトリコンポーネントとして維持してください。そのチェックに失敗した dest を deleteRecursively しないでください。エグゼキュータも同じコンストラクタを使用するため、両方を修正してください。

それまでは、Spark UID のファイルシステムをすでに信頼している相手以外に Spark Connect を公開しないでください。spark.connect.authenticate.token の PSK はトークン保持者までハードルを上げるだけです。フラグメントをサニタイズするものではありません。

参考資料

ツールをダウンロード