Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
spark-history-store-path — Apache Spark 4.2.0 - عالي - عن بُعد - كتابة ملف - تطبيق History appStorePath معرّف التطبيق غير المعقّم | Kitploit
أدوات/GitHubGitHub/abraxas/spark-history-store-path
التحليل الثابتتحليل الثغرات الأمنيةتحليل الكودالاستغلالاستغلال تطبيقات الويباختبار الاختراقمختبرات وتدريب عملي
GitHubabraxas/spark-history-store-path

spark-history-store-path

Apache Spark 4.2.0 - عالي - عن بُعد - كتابة ملف - تطبيق History appStorePath معرّف التطبيق غير المعقّم

عرض المستودع
16منذ 10 أياملم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

Abraxas Labs - spark-history-store-path

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-history-store-path

المقال: https://abraxaslabs.tech/research/spark-history-store-path

spark-history-store-path

الفئة: كتابة ملف (مشروطة بالإعدادات) الوصول: عن بُعد

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

تقوم HistoryServerDiskManager.appStorePath بتنفيذ new File(appStoreDir, appId + extension) دون أي تنقية. إن Utils.sanitizeDirName مخصصة فقط لأسماء ملفات سجل الأحداث. حقل JSON App ID يُقرأ عبر asText(). أما السرد فيخزّن event.appId.orNull. وتستخدم Lease.commit تلك السلسلة. معرّف التطبيق ../ يكتب ملف .rdb خارج spark.history.store.path. القيمة الافتراضية غير المضبوطة لـ store.path تكون في الذاكرة (دون كتابة). المحتويات هي ملف مخزن، وليست تنفيذًا عن بُعد (RCE).

المعرّفلا يوجد CVE بعد
الفئةكتابة ملف (مخزن History على القرص مشروط بالإعدادات)
الوصولعن بُعد (كاتب سجل الأحداث بالإضافة إلى History مع ضبط spark.history.store.path؛ قوائم التحكم بالوصول في الواجهة معطّلة افتراضيًا)
CWECWE-22
CVSSعالٍ: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N عند ضبط spark.history.store.path
المنتجApache Spark History Server
المتأثر4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
المصادقةكاتب spark.history.fs.logDirectory (الافتراضي file:/tmp/spark-events)؛ يجب أن يكون spark.history.store.path مضبوطًا في History
الترخيصGNU Affero GPL v3.0
المختبر127.0.0.1:18990 فقط. أداة استغلال الربط المذكور. إثبات وجود ملف .rdb خارج store.path.

ما يمكن للمهاجم فعله

نموذج الضحية نفسه كما في CVE-2025-54920: خادم History موجّه إلى دليل سجلات يستطيع المهاجم الكتابة فيه. لم يعد Jackson ينشئ أدوات من فئة HiveConnection. لا يزال مسار المخزن على القرص يثق بمعرّف التطبيق (App ID) القادم من JSON الأحداث.

الطريقةالمصبّالصلاحيةالمختبر مقابل المستنتج
زرع سجل أحداث يكون فيه App ID بصيغة JSON هو ../<name> (أو ../../oracle/...). انتظر حتى تتم عملية الفحص. GET الذي يحمّل واجهة التطبيق / getAppUI / loadDiskStore / createDiskStoreHistoryServerDiskManager.appStorePath ثم Lease.commit renameToالسلامة: إنشاء مسار .rdb (RocksDB الافتراضي) أو .ldb (LevelDB) خارج {store.path}/apps بصفته History UID. مُثبت مختبريًا على الـ gadget: escaped=yes، والملف /work/oracle/SPARK-HISTORY-STORE-PATH-WITNESS.rdb يحتوي على الشاهد. المحتويات هي ملف مخزن، وليست بايت كود مضيف يختاره المهاجم، وليست صدفة.مُثبت مختبريًا (كتابة الـ gadget لبايتات الشاهد عند المسار المُهرَّب). إن renameTo الكامل لـ History على مجلد RocksDB هو نفس عملية الضم.
نفس App ID عندما يكون الوجهة المُهرَّبة مجلدًا موجودًا بالفعلLease.commit if (dst.isDirectory()) deleteStore(dst) ثم Utils.deleteRecursivelyالتوافر: حذف مجلد موجود ينتهي اسمه بالفعل بلاحقة الـ backend، ثم استبداله بالمخزن المؤجَّر.مستنتج (تثبيت HistoryServerDiskManager.scala commit). كتب الـ gadget ملفًا، ولم يستدعِ deleteRecursively.
spark.history.store.path الافتراضي غير المضبوطLOCAL_STORE_DIR createOptional؛ diskManager = storePath.mapمغلق. سرد في الذاكرة. لا يوجد HistoryServerDiskManager. مُثبت مختبريًا gated=yes written=no.مُثبت مختبريًا
تطبيق Utils.sanitizeDirName على App ID أولًامساعد اسم ملف سجل الأحداثيبقى داخل apps/. يتحول / و : إلى -. مُثبت مختبريًا سلبيًا.مُثبت مختبريًا
التحكم في App ID local-control مع ضبط store.pathنفس عملية الضميكتب {store.path}/apps/local-control.rdb. يبقى داخل apps/.مُثبت مختبريًا

مغلق مجاور: المخزن الافتراضي غير المضبوط (في الذاكرة). لا يزال Jackson sparkEventFromJson يتطلب SparkListenerEvent (CVE-2025-54920). احتياطي URL getAppUI eventlog_v2_ + nameForAppAndAttempt مُنقّى. مفتاح KV للسرد ليس مسار نظام ملفات. HybridStore / kvstore mapper لا يحتوي على Id.CLASS. لا يقبل History HTTP مسار رفع. الضغط الافتراضي معطّل. المنظّف الافتراضي معطّل. إرسال المهام على عنقود مفتوح (SECURITY.md FAQ). تحميل نموذج ML (docs/ml-security.md). هذه البقايا ليست RCE على المضيف.

كيف وجدته

ثبّتُ Spark 4.2.0، وليس master، وليس 4.3 RC. ثمانية وعشرون عملية بحث. إن RCE العام لـ History Jackson مغلق على هذه الطبقة. كتّاب سجل الأحداث يستدعون بالفعل Utils.sanitizeDirName لذا لا يمكن أن يحتوي ملف السجل على /. اسم ملف ذاكرة التخزين المؤقت على القرص يستخدم App ID الخام.

private[history] def appStorePath(appId: String, attemptId: Option[String]): File = {
  val fileName = appId + attemptId.map("_" + _).getOrElse("") + extension
  new File(appStoreDir, fileName)
}

appStoreDir هو {spark.history.store.path}/apps. في Unix، new File(parent, "../../oracle/name.rdb") يُحل خارج المجلد الأب. تأخذ JsonProtocol.applicationStartFromJson القيمة json.get("App ID").asText(). تُخزّن AppListingListener.onApplicationStart القيمة event.appId.orNull. تُغذّي lease.commit(appId, attempt.info.attemptId) تلك السلسلة النصية إلى appStorePath.

المنعطفات الخاطئة المسجّلة مسبقًا: التعامل مع store.path الافتراضي غير المضبوط على أنه كتابة (فهو في الذاكرة)؛ توقّع أن يتجاهل new File(dir, "/abs") في Unix المجلد الأب (وهو لا يفعل ذلك؛ فالباقي هو ..)؛ الادعاء بوجود RCE لأن اللاحقة هي .rdb؛ إقلاع History Server كامل بينما الربط هو الـ oracle؛ التعامل مع sanitizeDirName على أنها تغطي هذا المسار.

المختبر

python3 spark-history-store-path-Abraxas-Labs.py

أو

cd lab
./run.sh

Gadget الخاص بـ HistoryServerDiskManager.appStorePath على 127.0.0.1:18990. ثبّت المقتطفات تحت lab/pin/. لا يتم إقلاع History Server الكامل. اربطه بواجهة loopback.

SUCCESS SPARK-HISTORY-STORE-PATH how=gadget escaped=yes gated=yes outside=/work/oracle/SPARK-HISTORY-STORE-PATH-WITNESS.rdb SPARK-HISTORY-STORE-PATH-WITNESS

الإصلاح

شغّل Utils.sanitizeDirName (أو ارفض .. / / / NUL) على appId وattemptId داخل appStorePath قبل new File. بعد الدمج، اشترط أن يبقى dst.getCanonicalFile() تحت appStoreDir.getCanonicalFile(). يبقى spark.history.store.path غير المضبوط هو الافتراضي الآمن.

المراجع

تنزيل الأداة