
CVE-2026-25895 FUXA के लिए POC शोषण - अप्रमाणित पथ ट्रैवर्सल -> मनमाना फ़ाइल लेखन -> RCE
FUXA, एक Node.js-आधारित SCADA/HMI प्लेटफ़ॉर्म, के विरुद्ध अप्रमाणित, प्री-ऑथ मनमाना फ़ाइल लेखन। लिखने के बाद कई अलग-अलग प्राइमिटिव के माध्यम से दूरस्थ कोड निष्पादन की श्रृंखला। यह तब भी काम करता है जब secureEnabled = true (प्रमाणीकरण चालू) हो, क्योंकि कमजोर एंडपॉइंट पर कोई मिडलवेयर संलग्न नहीं है।
ExploitDB पर भी उपलब्ध: https://www.exploit-db.com/exploits/52568
| फ़ील्ड | मान |
|---|---|
| CVE ID | CVE-2026-25895 |
| प्रभावित | FUXA <= 1.2.9 |
| पैच किया गया | FUXA 1.2.10 |
| विक्रेता | frangoteam / FUXA |
| हमला वेक्टर | नेटवर्क (HTTP/HTTPS) |
| प्रमाणीकरण | कोई आवश्यकता नहीं |
| प्रभाव | मनमाना फ़ाइल लेखन, दूरस्थ कोड निष्पादन |
| CVSS v3.1 | 9.8 (गंभीर) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| शोधकर्ता | Anthony Cihan (Hann1bl3L3ct3r) |
FUXA का POST /api/upload एंडपॉइंट (server/api/projects/index.js:193) मिडलवेयर के बिना पंजीकृत है, जो secureFnc JWT / API-कुंजी जांच और अन्य सभी प्रोजेक्ट-प्रबंधन एंडपॉइंट पर लागू व्यवस्थापक अनुमति गेट दोनों को बायपास करता है। हैंडलर के अंदर, JSON बॉडी फ़ील्ड destination को फ़ाइलसिस्टम पथ में केवल एक अग्रणी अंडरस्कोर और बिना किसी सामान्यीकरण या संयम जांच के संयोजित किया जाता है:
let destinationDir = path.resolve(runtime.settings.appDir, `_${destination}`);
filePath = path.join(destinationDir, fullPath || fileName);
fs.writeFileSync(filePath, basedata, encoding);
a/../../../../../etc (जहाँ a अग्रणी अंडरस्कोर उपसर्ग को अवशोषित करता है) फॉर्म का destination मान Node के path.resolve को appDir से बाहर किसी भी स्थान पर चढ़ने देता है जहाँ FUXA प्रक्रिया लिख सकती है। चूँकि fs.writeFileSync से पहले एक सशर्त fs.mkdirSync(dir, { recursive: true }) होता है, हमलावर आवश्यकतानुसार मूल निर्देशिकाएँ भी बना सकता है।
परिणाम एक अप्रमाणित मनमाना फ़ाइल लिखने का प्राइमिटिव है जो डिफ़ॉल्ट HTTP पोर्ट (1881) पर पहुँचा जा सकता है, प्री-ऑथ शोषण योग्य है चाहे FUXA व्यवस्थापक ने लॉगिन सक्षम किया हो या नहीं।
एक अप्रमाणित दूरस्थ हमलावर यह कर सकता है:
settings.js को बदलकर अगले FUXA पुनरारंभ पर कोड निष्पादन प्राप्त कर सकता है/etc/cron.d/<file>) डालकर 60 सेकंड के भीतर कोड निष्पादन कर सकता है जब FUXA root (विक्रेता की Docker इमेज में डिफ़ॉल्ट) के रूप में चलता है/root/.ssh/authorized_keys या किसी भी उपयोगकर्ता के ~/.ssh/authorized_keys में SSH सार्वजनिक कुंजियाँ डाल सकता हैयह औद्योगिक प्रक्रियाओं को संचालित करने के लिए उपयोग किए जाने वाले ICS/SCADA प्लेटफ़ॉर्म पर एक प्री-ऑथ गंभीरता खोज है।
| संस्करण | स्थिति |
|---|---|
<= 1.2.9 | असुरक्षित |
1.2.10+ | पैच किया गया |
Ubuntu Server पर FUXA 1.2.9 की स्वच्छ स्थापना के विरुद्ध शोषण की पुष्टि की गई।
एकल-फ़ाइल Python 3 स्क्रिप्ट, एक तृतीय-पक्ष निर्भरता (requests)।
pip install requests
python3 fuxapwn.py --help
होस्ट पर किसी भी असामान्य चीज़ को लिखे बिना चल रहे OS उपयोगकर्ता, Node-RED एक्सपोज़र और किसी भी अन्य खाते की पहचान करें:
python3 fuxapwn.py -u http://target:1881 --mode recon \
--probe-root --probe-home
एक तटस्थ /tmp/healthcheck मार्कर लिखें (फ़ाइलनाम या सामग्री में कोई CVE-विशिष्ट IOC नहीं):
python3 fuxapwn.py -u http://target:1881 --mode canary
यदि FUXA root के रूप में चलता है, तो एक क्रॉन फ़ाइल डालें जो बिना किसी FUXA पुनरारंभ की आवश्यकता के 60 सेकंड के भीतर फायर होती है:
python3 fuxapwn.py -u http://target:1881 --mode cron \
--cron-cmd 'id > /tmp/fx.txt 2>&1'
settings.js प्रतिस्थापन के माध्यम से स्थायी वेबशेलFUXA Node प्रक्रिया के अंदर एक HTTP वेबशेल श्रोता स्थापित करें (अगले कोल्ड स्टार्ट पर सक्रिय होता है, क्योंकि require() मॉड्यूल को कैश करता है), फिर FUXA के पुनरारंभ होने पर एक इंटरैक्टिव REPL में प्रवेश करें:
# पेलोड को स्टेज करें — settings.js को बदलता है लेकिन लक्ष्य के वास्तविक कॉन्फ़िगरेशन (uiPort, allowedOrigins, secureEnabled, आदि) को संरक्षित करता है ताकि एप्लिकेशन सामान्य रूप से सेवा देता रहे।
python3 fuxapwn.py -u http://target:1881 --mode webshell \
--appdata /opt/FUXA/server/_appdata --ws-port 31337
# एक बार FUXA पुनरारंभ होने पर, स्थापित वेबशेल से कनेक्ट करें।
python3 fuxapwn.py -u http://target:1881 --mode webshell-exec \
--ws-host target --ws-port 31337 \
--ws-path /_abc123 --ws-token <printed-above> --interact
पूर्ण प्रति-मोड ध्वज संदर्भ: python3 fuxapwn.py --help.
GET /api/settings (server/api/index.js:103) मिडलवेयर के बिना पंजीकृत है और हल्के रेडैक्टेड लाइव रनटाइम कॉन्फ़िगरेशन लौटाता है (सर्वर भेजने से पहले secretCode और smtp.password हटा देता है)। शेष फ़ील्ड पूर्ण पथ (appDir, workDir, userSettingsFile, logsDir, uploadFileDir) लीक करते हैं जो आमतौर पर सेवा उपयोगकर्ता की पहचान करते हैं, साथ ही nodeRedEnabled, जो एक द्वितीयक अप्रमाणित RCE पथ (नीचे देखें) के लिए एक सीधा संकेत है।
जब FUXA को स्थानीय उपयोगकर्ता खाते के तहत npm start के माध्यम से लॉन्च किया जाता है और इंस्टॉल पथ उपयोगकर्ता को एनकोड नहीं करते (जैसे इंस्टॉल /opt, /tmp, या सामान्य /app के अंतर्गत रहता है), और /root/ लिखने योग्य नहीं है, तो POC शून्य-बाइट लेखन के साथ /home/<candidate>/ को पुनरावृत्त करता है।
FUXA अपलोड हैंडलर fs.writeFileSync से पहले fs.mkdirSync(parent, { recursive: true }) को सशर्त रूप से कॉल करता है, जो EACCES अस्पष्टता पैदा करता है: एक गैर-मौजूद /home/<user>/ mkdir प्रयास पर EACCES के साथ विफल होता है (प्रक्रिया रूट-स्वामित्व वाले /home/ के अंतर्गत निर्देशिकाएँ नहीं बना सकती), जबकि मोड 0700 के साथ मौजूदा /home/<other>/ स्वयं लेखन पर EACCES विफल होता है। एक ही errno, अलग अर्थ। POC सर्वर-फ़ॉरवर्ड किए गए err.message (libuv प्रारूप "<CODE>: <reason>, <syscall> '<path>'") से syscall टोकन पार्स करके और केवल mkdir syscall के अलावा किसी भी syscall पर EACCES को "अन्य उपयोगकर्ता मौजूद" के रूप में रिपोर्ट करके अंतर करता है। यह गलत-सकारात्मक पार्श्व-गति सूची को समाप्त करता है जो एक भोली errno-केवल जांच उत्पन्न करेगी।
यदि लीक की गई सेटिंग्स में nodeRedEnabled = true है, तो FUXA का एम्बेडेड Node-RED व्यवस्थापक एंडपॉइंट (/nodered/flows/deploy, आदि) एक Referer-हेडर व्हाइटलिस्ट जांच (node-red/index.js:134-136) के कारण अप्रमाणित रूप से पहुँचा जा सकता है जो किसी भी अनुरोध को स्वीकार करता है जिसके Referer में /editor, /viewer, या /lab हो। यह एक फ़ंक्शन नोड के माध्यम से तत्काल अप्रमाणित RCE प्रदान करता है जिसमें पुनरारंभ की आवश्यकता नहीं होती है। recon मोड इस स्थिति को ध्वजांकित करता है; ऑपरेटरों को उपलब्ध होने पर इसे प्राथमिकता देनी चाहिए।
settings.js पेलोड लक्ष्य कॉन्फ़िगरेशन को संरक्षित करते हैंsettings.js प्रतिस्थापन (मोड settings-rce और webshell) उत्पन्न करते समय, POC पहले /api/settings के माध्यम से लाइव कॉन्फ़िग प्राप्त करता है और इसे module.exports बॉडी के रूप में JSON-सीरियलाइज़ करता है (JSON एक मान्य JavaScript ऑब्जेक्ट लिटरल उपसमुच्चय है)। यह लक्ष्य के uiPort, allowedOrigins, secureEnabled और अन्य रनटाइम सेटिंग्स को संरक्षित करता है ताकि प्रतिस्थापन के बाद एप्लिकेशन सामान्य रूप से सेवा देता रहे। POC स्पष्ट रूप से चेतावनी देता है जब लक्ष्य में secureEnabled = true या smtp ब्लॉक होता है, क्योंकि सर्वर-साइड रिडक्शन secretCode (JWT फ़ॉलबैक शुरू हो जाएगा) और smtp.password (मैन्युअल रूप से बहाल होने तक ईमेल टूट जाएगा) हटा देता है।
POST /api/upload, विशेष रूप से destination मानों के साथ जिनमें .. या प्रतिक्रिया में पूर्ण फ़ाइलसिस्टम पथ होंGET /api/settings (सामान्यतः केवल प्रमाणित UI द्वारा उपयोग किया जाता है)/tmp/healthcheck*, /tmp/.fuxa-probe-*, या /home/*/.fuxa-probe-* से मेल खाने वाली फ़ाइलें (डिफ़ॉल्ट कैनरी और जांच मार्कर फ़ाइलनाम — POC स्पष्ट IOCs से बचने के लिए इन्हें ओवरराइड करने की अनुमति देता है, इसलिए अनुपस्थिति शोषण को खारिज नहीं करती है)settings.js, /etc/cron.d/*, या ~/.ssh/authorized_keys पर संशोधित टाइमस्टैम्प जो किसी व्यवस्थापक कार्रवाई के अनुरूप नहीं हैं/api/upload एंडपॉइंट मानक मिडलवेयर श्रृंखला द्वारा संरक्षित है।/api/upload और /api/settings के लिए अप्रमाणित अनुरोधों को अवरुद्ध करता है।/root/ लेखन नहीं, कोई /etc/cron.d/ लेखन नहीं, कोई होस्ट-व्यापी क्रॉन के माध्यम से दृढ़ता नहीं)।nodeRedEnabled = false) को अक्षम करें।1.2.101.2.9 में server/api/projects/index.js:193Anthony Cihan (Hann1bl3L3ct3r), Offensive Security के प्रमुख, द्वारा अनुसंधान, PoC और लेखन।
इस रिपॉजिटरी में एक ICS/SCADA उत्पाद में एक गंभीर भेद्यता के लिए कार्यात्मक शोषण कोड है। इसे जिम्मेदार प्रकटीकरण सिद्धांतों के तहत, विक्रेता द्वारा पैचिंग के बाद, रक्षकों (पता लगाने वाले लेखकों, घटना प्रतिक्रियाकर्ताओं) और अधिकृत सुरक्षा परीक्षकों के लाभ के लिए प्रकाशित किया गया है।
इसका उपयोग केवल उन प्रणालियों के विरुद्ध करें जिनके आप स्वामी हैं या जिनके लिए आपके पास परीक्षण करने की स्पष्ट, लिखित प्राधिकरण है। तीसरे पक्ष की प्रणालियों के विरुद्ध इस कोड का अनधिकृत उपयोग अधिकांश न्यायक्षेत्रों में अवैध है और लेखक द्वारा ऐसा माना जाएगा। लेखक दुरुपयोग के लिए कोई देयता स्वीकार नहीं करता है।
यदि आप एक FUXA ऑपरेटर हैं और नियंत्रित परिस्थितियों में इस PoC के विरुद्ध अपने पैच स्तर को मान्य करने में सहायता चाहते हैं, तो लेखक से संपर्क करें।
अधिकृत सुरक्षा-परीक्षण और रक्षात्मक-अनुसंधान उद्देश्यों के लिए जारी। पूर्ण शर्तों के लिए LICENSE देखें।
| मोड | उद्देश्य |
|---|
recon | GET /api/settings के माध्यम से अप्रमाणित जानकारी लीक; पूर्ण पथों से चल रहे OS उपयोगकर्ता का अनुमान; Node-RED स्थिति की रिपोर्ट; वैकल्पिक --probe-root और --probe-home सक्रिय जांच |
canary | तटस्थ डिफ़ॉल्ट पथ के साथ फ़ाइल-लिखने के प्राइमिटिव का प्रमाण |
settings-rce | settings.js को एक पेलोड से बदलता है जो अगले FUXA कोल्ड स्टार्ट पर एक कॉन्फ़िगर करने योग्य कमांड चलाता है |
ssh-key | लक्ष्य उपयोगकर्ता के authorized_keys में एक सार्वजनिक कुंजी लिखता है |
drop | किसी भी पूर्ण पथ पर मनमाना फ़ाइल ड्रॉप |
cron | /etc/cron.d/<name> को RCE के लिए 60 सेकंड के भीतर डालता है बिना FUXA पुनरारंभ की प्रतीक्षा किए (FUXA को root के रूप में चलाने की आवश्यकता है) |
webshell | settings.js प्रतिस्थापन के माध्यम से FUXA Node प्रक्रिया के अंदर एक HTTP वेबशेल श्रोता स्थापित करता है (अगले कोल्ड स्टार्ट पर सक्रिय होता है) |
webshell-exec | पहले से स्थापित वेबशेल के लिए क्लाइंट; एकल कमांड या --interact REPL |