
phpMyAdmin 5.2.3 - عالي - عن بُعد - XSS - Designer Visual Query Builder
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-vqb-xss
الفئة: XSS مخزّن الوصول: عن بُعد
phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin
js/src/designer/history.js يبني سجل الاستعلام المرئي باستخدام innerHTML. أسماء الأعمدة تمر عبر $('<div/>').text(...).html(). أسماء الجداول لا تمر. لا يزال TableName يسمح بـ < و >. حساب منخفض الصلاحيات يملك CREATE TABLE على قاعدة بيانات مشتركة يزرع معرّف HTML. عندما يفتح مستخدم ذو صلاحيات أعلى Designer، يكون getTableName() موجودًا في الصفحة ويكتبه DesignerHistory.display() داخل #ab.
XSS مخزّن في أصل phpMyAdmin. نفس فئة PMASA-2025-1، ميزة مختلفة. تم تهريب عناوين Check-tables. هذا المسار لم يُهرَّب.
| المعرّف | لا يوجد CVE بعد |
| الفئة | XSS مخزّن |
| الوصول | عن بُعد (مصادَق CREATE TABLE؛ الضحية يفتح Designer) |
| CWE | CWE-79 |
| CVSS | مرتفع: 8.0 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N |
| المنتج | phpMyAdmin |
| المتأثر | 5.2.3 وسم RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| المصادقة | مصادَق. يحتاج المهاجم إلى CREATE TABLE على قاعدة بيانات يفتحها الضحية في Designer |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1 فقط |
يزرع اسم جدول HTML، ثم ينتظر مستخدمًا ذا صلاحيات أعلى لفتح Designer على تلك القاعدة وعرض سجل الاستعلام المرئي.
| الصلاحية | الطريقة / نقطة الوصول | الاستطلاع / السلامة / التوافر | مُثبت مختبريًا أو مُستنتج |
|---|---|---|---|
| حقن وسوم في أصل phpMyAdmin | DesignerHistory.display() يدمج getTab() داخل #ab innerHTML | سلامة أصل الضحية | مُثبت مختبريًا. history.js الحيّ على phpmyadmin:5.2.3. <h3> احتوى على <i id="pma-vqb"> |
الخروج من سمة table_name في designer | database_tables.twig small_tab_pref_1 يستخدم designerTable.getTableName() | استطلاع اسم MySQL الخام في DOM الخاص بـ Designer | مُثبت مختبريًا وقابل للقراءة كمعرّف خام |
قراءة كوكي جلسة الضحية و token الخاص بـ CSRF | سكربت من نفس الأصل بمجرد عرض السجل | استطلاع جلسة PMA الخاصة بالضحية | مُستنتج من XSS مخزّن في أصل PMA. يستخدم هذا المختبر علامة <i>، وليس سكربتًا |
| تنفيذ SQL، إدارة المستخدمين، التصدير، بصفة حساب MySQL الخاص بالضحية | POST مدعوم بالـ token إلى /sql، /server/privileges، التصدير | سلامة كل ما يمكن لذلك الحساب لمسه | مُستنتج. نفس فئة التأثير كـ PMASA-2025-1 |
| تغيير 2FA / userconfig | POST /config/set بصفة الضحية | سلامة مخزن تفضيلات الضحية | مُستنتج. بقايا شقيقة، وليس هذا المختبر |
مغلق على هذه البقايا: الوصول غير المصادَق، OS RCE، ومسار زر OK في VQB. .small_tab_pref_click_opt يُهرّب table_name مسبقًا و Twig يهرّبه تلقائيًا مرة أخرى، لذا يغذّي ذلك النقر حاليًا كيانات داخل getTab(). هذا ليس إصلاحًا لـ history.js. تبقى خلايا الأعمدة مُهرَّبة نصيًا (c<b id=pma-col>y، لا عقدة <b id="pma-col">).
نفس التثبيت: WebAuthn CustomServer leftover.
ثبّتُ phpMyAdmin RELEASE_5_2_3. PMASA-2025-1/2/3 موجودة بالفعل في 5.2.2. لا يزال Designer يبني HTML سجل VQB يدويًا.
js/src/designer/history.js (يُشحن كـ js/dist/designer/history.js):
temp = historyArray[i].getTab();
str += '<h3 class="tiger"><a href="#">' + temp + '</a></h3>';
// ...
'<td width="175" style="padding-left: 5px">' + $('<div/>').text(historyArray[i].getColumnName()).html() + '<td>';
libraries/classes/Dbal/TableName.php يتحقق فقط من عدم الفراغ، بحد أقصى 64، وبدون مسافة لاحقة. < و > قانونيان. يقبلهما MySQL في معرّف بين علامتي اقتباس.
templates/database/designer/database_tables.twig ينسخ designerTable.getTableName() إلى table_name على .small_tab_pref_1. تستخدم خلية خيار VQB نسخة مُهرَّبة مسبقًا من نفس الاسم.
منعطفات خاطئة مسجّلة بالفعل: اعتبار سمة زر الخيار المزدوجة التهريب هي الإصلاح (ليست كذلك - لا يزال small_tab_pref_1 يكشف الاسم الخام، و history.js هو نقطة الوصول)؛ اعتبار مساعد الأعمدة يغطي أسماء الجداول؛ الادعاء بـ XSS غير مصادَق؛ reverse shell. مسرح.
python3 phpmyadmin-vqb-xss-Abraxas-Labs.py
# or: cd lab && ./run.sh
الهدف فقط http://127.0.0.1:19250. الصورتان phpmyadmin:5.2.3 و mysql:8.0. مشروع Compose باسم phpmyadmin-vqb-xss. Playwright Chromium في خدمة poc. تُفكَّك الحزمة بعد التشغيل.
مستخدمان، shareddb مشتركة. منخفض الصلاحيات creator ينفّذ CREATE TABLE \tx` (`cy` INT). مرتفع الصلاحيات victimيسجّل الدخول إلى phpMyAdmin ويفتح Designer معquery=1. history.js الحيّ هو النسخة من الحاوية (h3-unescaped=yes، مساعد الأعمدة موجود). يستدعي Chromium DesignerHistory.display()باسم الجدول منgetTableName()` في الصفحة.
النتيجة: #ab h3.tiger innerHTML هو <a href="#">t<i id="pma-vqb">x</i></a>. نص td الخاص بالعمود هو c<b id=pma-col>y بدون عقدة b#pma-col.
SUCCESS phpmyadmin-vqb-xss h3-markup=yes col-escaped=yes how=live PMA-VQB-XSS-WITNESS
هرّب getTab() باستخدام $('<div/>').text(temp).html() أو Functions.escapeHtml قبل الدمج داخل <h3>. لا تعتمد على الترميز المزدوج من Twig لسمة واحدة. أبقِ مساعد اسم العمود كنموذج.
962857e4f63d42e38f11ff4d63f5e722018add76)js/src/designer/history.jslibraries/classes/Dbal/TableName.phpGNU Affero GPL v3.0. انظر LICENSE. مختبر loopback فقط. لا ضمان.