
phpMyAdmin 5.2.3 - उच्च - रिमोट - XSS - Designer Visual Query Builder
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-vqb-xss
राइट-अप: https://abraxaslabs.tech/research/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 में लिख देता है।
phpMyAdmin ओरिजिन में एक स्टोर्ड XSS। PMASA-2025-1 के समान वर्ग, भिन्न फ़ीचर। check-tables हेडिंग्स को एस्केप किया गया था। इस पथ को नहीं।
| ID | अभी तक कोई 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 में जोड़ता है | पीड़ित ओरिजिन की अखंडता | लैब-प्रमाणित। phpmyadmin:5.2.3 पर लाइव history.js। <h3> में <i id="pma-vqb"> था |
designer table_name एट्रिब्यूट से बाहर निकलें | database_tables.twig small_tab_pref_1 designerTable.getTableName() का उपयोग करता है | Designer DOM में कच्चे MySQL नाम का रेकॉन | लैब-प्रमाणित, कच्चे पहचानकर्ता के रूप में पठनीय |
पीड़ित का सत्र कुकी और CSRF token पढ़ें | इतिहास रेंडर होने पर समान-ओरिजिन स्क्रिप्ट | पीड़ित PMA सत्र का रेकॉन | PMA ओरिजिन में स्टोर्ड XSS से अनुमानित। यह लैब एक <i> मार्कर का उपयोग करती है, स्क्रिप्ट का नहीं |
| पीड़ित MySQL खाते के रूप में SQL चलाएँ, उपयोगकर्ताओं को प्रबंधित करें, निर्यात करें | टोकन-समर्थित POST /sql, /server/privileges, निर्यात | उस MySQL खाते की अखंडता जो भी छू सकता है | अनुमानित। PMASA-2025-1 के समान प्रभाव वर्ग |
| 2FA / userconfig बदलें | पीड़ित के रूप में POST /config/set | पीड़ित प्राथमिकता स्टोर की अखंडता | अनुमानित। सहोदर अवशेष, यह लैब नहीं |
इस अवशेष पर बंद: अप्रमाणित पहुँच, OS RCE, और VQB OK बटन पथ। .small_tab_pref_click_opt table_name को पहले से एस्केप करता है और Twig इसे फिर से ऑटोएस्केप करता है, इसलिए वह क्लिक वर्तमान में getTab() में एंटिटीज़ फ़ीड करता है। यह history.js का समाधान नहीं है। कॉलम सेल टेक्स्ट-एस्केप्ड रहते हैं (c<b id=pma-col>y, कोई <b id="pma-col"> नोड नहीं)।
समान पिन: WebAuthn CustomServer अवशेष।
मैंने phpMyAdmin RELEASE_5_2_3 को पिन किया। PMASA-2025-1/2/3 पहले से ही 5.2.2 में हैं। Designer अभी भी VQB इतिहास HTML को हाथ से बनाता है।
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() को .small_tab_pref_1 पर table_name में कॉपी करता है। VQB विकल्प सेल उसी नाम की पहले से एस्केप की गई प्रति का उपयोग करता है।
पहले से दर्ज की गई गलत दिशाएँ: दोहरे-एस्केप किए गए विकल्प-बटन एट्रिब्यूट को समाधान मानना (ऐसा नहीं है - small_tab_pref_1 अभी भी कच्चा नाम उजागर करता है, और history.js सिंक है); कॉलम हेल्पर को टेबल नामों को कवर करने वाला मानना; अनधिकृत XSS का दावा करना; एक रिवर्स शेल। नाटक।
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। poc सेवा में Playwright Chromium। रन के बाद स्टैक टियर डाउन हो जाता है।
दो उपयोगकर्ता, साझा shareddb। लो-प्रिव creator CREATE TABLE \tx` (`cy` INT)चलाता है। उच्च-प्रिवvictimphpMyAdmin में लॉग इन करता है औरquery=1के साथ Designer खोलता है। लाइवhistory.js कंटेनर से कॉपी है (h3-unescaped=yes, कॉलम हेल्पर मौजूद)। Chromium पेज पर getTableName()से प्राप्त टेबल नाम के साथDesignerHistory.display()` को कॉल करता है।
परिणाम: #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() को <h3> में जोड़ने से पहले $('<div/>').text(temp).html() या Functions.escapeHtml के साथ एस्केप करें। किसी एक एट्रिब्यूट के Twig डबल-एन्कोडिंग पर निर्भर न रहें। कॉलम-नाम हेल्पर को मॉडल के रूप में रखें।
962857e4f63d42e38f11ff4d63f5e722018add76)js/src/designer/history.jslibraries/classes/Dbal/TableName.phpGNU Affero GPL v3.0. देखें LICENSE। केवल लूपबैक लैब। कोई वारंटी नहीं।