発見の経緯
奥一穂さんとfacebook上で会話していて、スマホアプリ等でSSLサーバ証明書の検証をする際に、コモンネームを検証していないアプリの可能性について示唆を受けました。その内容は、奥さんのブログ記事として以下にまとめられています。Kazuho's Weblog: SSL/TLSライブラリの正しい使い方(もしくは、コモンネームの検証について)詳しくは上記記事をお読みいただくとして、サーバ証明書の検証の要点としては以下となります。
- 証明書が信頼された認証局の発行したものであること
- 証明書の有効期限の範囲内であること
- サーバ証明書のコモンネームが接続しようとしているサーバと一致していること
しかし、一般にMITMモードを備えたPROXY(Burp Suite、Fiddler等)は、発行元が信頼されていないがコモンネームと有効期限は適切な証明書を発行して返します。下図は、Burp Suiteを用いてIPAのサイトに接続した際の証明書の内容です。発行者がPortSwigger CAとなっていますが、それ以外のコモンネーム(CN)と有効期限は適正です。
このため、Burp Suite等はこの実験の目的には適しません。
ネットでしばらく探してみましたが、適当なものが見当たらなかったため、簡易的なPROXYを自作して試すことにしました。
実験環境
実験の環境は、以前のブログ記事で使用した環境をほぼそのまま使い、Burp Suiteの代わりに自作PROXY(下図のMITM PROXY)を使いました。「被害者のAndroid端末」としては、改造していない(ルート化や証明書の追加をしていない)Nexus 7を用いました。MITM PROXYには固定のサーバ証明書(正規のもの)が導入されていて、どのサーバーへの接続に対しても、端末との接続にはそのサーバ証明書を用います。このため、ブラウザでこのPROXY経由で接続すると、下記のようなエラーとなります。下図はIPAのサイトにSSL接続しようとした際にiPhone上のGoogle Chromeが表示しているエラーメッセージです。
実験の結果
この状態でAndroid版Kindleを使用すると、通常は通信エラーになります。下図は、サインインの際のエラー表示の様子です。しかし、テストをしているうちに、Kindleパーソナル・ドキュメントサービスに関しては、上記MITM PROXYにて復号可能な状態でSSL通信をしていることがわかりました。PROXYをBurp Suiteに変更すると通信エラーになるため、証明書のチェックのうちコモンネームの検証がもれていると推測しました。
これはすなわち、この実験で求めていた成果が、意外な大物として釣り上げられたことになります。
下記は、Kindleパーソナル・ドキュメントに対するリクエストの例です。
以下はレスポンスの例です。生のPDFが返されていることがわかります。GET /FionaCDEServiceEngine/FSDownloadContent?type=PDOC&key=FIHKZL674JJEWT… is_archived_items: 1 currentTransportMethod: WIFI software_rev: 1141637187 X-ADP-Request-Digest: K+yGNDcBY3j61RPAtEhhbFHEME+sH4Tn550gwjE88v6TE6EYRAu… Range: bytes=0- Accept-Language: ja-JP X-ADP-Authentication-Token: {enc:JfYZXcdve5JIhRIk8Ec9AfFN/2doDyBtfpWsYeFA… x-adp-alg: SHA256WithRSA:1.0 x-adp-token: {enc:JfYZXcdve5JIhRIk8Ec9AfFN/2doDyBtfpWsYeFAMiImkmQgm3PocVq… x-adp-signature: IZjXKX5fo1LelIUc0FKNRiaiHt9tDI0b7ZRdXcu3j5ClUmnXvOYBUIi3… User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; Nexus 7 Build/KOT49H) Host: cde-ta-g7g.amazon.co.jp Connection: Keep-Alive Accept-Encoding: gzip
なお、レスポンスからPDFデータを取り出したところ、元のPDFと目視レベルで一致していることを確認しました。バイナリでは一致していませんが、Kindleパーソナル・ドキュメントサービス側で加工が入ったと推測します。HTTP/1.1 206 Partial Content Server: nginx Date: Sat, 01 Feb 2014 09:48:27 GMT Content-Type: application/pdf Content-Length: 27318 Connection: keep-alive x-adp-host: HMKP292P91XQM Accept-Ranges: bytes content-disposition: attachment; filename=odawara-tokumaru.pdf; filename*=UTF-8''%6f%64%61%77%61%72%61%2d%74%6f%6b%75%6d%61%72%75.pdf Hint-Sidecar-Download: 0 Content-Range: bytes 0-27317/27318 %PDF-1.5 %粤マモ 1 0 obj <</Type/Metadata/Subtype/XML/Length 2885>>stream <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:format>application/pdf</dc:format><dc:title><rdf:Alt><rdf:li>odawara-tokumaru</rdf:li></rdf:Alt></dc:title><dc:creator><rdf:Seq><rdf:li>Microsoft アカウント</rdf:li></rdf:Seq></dc:creator></rdf:Description> <rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/"><pdf:Producer>Microsoft® Word 2013</pdf:Producer></rdf:Description> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/"><xmp:CreateDate>2014-02-01T17:06:14+09:00</xmp:CreateDate><xmp:ModifyDate>2014-02-01T09:46:44Z</xmp:ModifyDate><xmp:CreatorTool>Microsoft® Word 2013</xmp:CreatorTool></rdf:Description> </rdf:RDF></x:xmpmeta>【以下略】
この問題の影響
この脆弱性による影響を報告します。まず、HTTPSリクエストには認証に関する情報が入っていますので、この情報からAmazonへのセッションがハイジャックされる可能性があります。実際にハイジャック可能かどうかまでは追いかけていません。
次に、レスポンスのPDFデータですが、Kindleパーソナル・ドキュメントサービスを利用して、Kindle端末(Android)に機密文書をダウンロードしようとして、それが盗聴されると情報漏洩となります。
しかしながら、例えば空港のフリーWi-Fiなど信頼出来ないネットワークを使って機密文書をKindle端末にダウンロードするというシナリオがどの程度あり得るかというと、絶対にないとは断言できないものの、それほどありそうなシチュエーションとは思えません。
このような状況を考慮して、IPAによる脆弱性深刻度は、「CVSS値 4.0、攻撃条件の複雑さ: 高」としたのだと推測します。私はこの深刻度評価を支持します。
対策
Android版Kindleをアップデート(本稿執筆時点の最新版は4.6.0)することにより脆弱性は解消されます。アプリケーション開発者がこの問題を確認する方法
アプリケーション開発者が実機テストにてこの問題、すなわちアプリケーションがSSLサーバ証明書のコメンネームを検証しているかどうかを確認するためには、試験用サーバに本番とは別のSSLサーバ証明書(正規のものだがコモンネームの異なるもの)を導入した状態でテストを行い、端末側でエラーになることを確認するとよいでしょう。まとめ
Android版KindleにおけるSSLサーバ証明書の検証不備の脆弱性CVE-2014-3908について報告しました。たまたまKindleの場合、脆弱性の影響はそれほど大きくないと考えますが、外出先等でよく使う機能に当該の問題があると、大きな影響となります。公衆無線LANを使う機会が多いという方は増えていると思いますが、公衆無線LANが偽AP(アクセスポイント)や事前共有鍵を用いた暗号解読(参照)による盗聴の危険性が常にあることを考えると、SSLによる暗号化が情報漏洩を防ぐ上では重要です。皆様の開発されるアプリケーションにおかれましても、SSLサーバ証明書のコモンネームの検証ができているか確認を推奨いたします。
Burpの場合OptionsのProxy Listenersで「Generate a CA-signed certificate with a specific hostname」を選ぶと、こちらの指定したhostnameのCNを持つ証明書を使ってくれます(多分Free版も)。「Use a custom certificate (PKCS12)」という選択肢もあります。
返信削除websec02+google02 さん、大変有益なアドバイスをありがとうございます。コメントに気づくのが今になり、返信が遅れましたこと、お詫びいたします。目的からして「Use a custom certificate (PKCS12)」の方を選択し、所望の結果を得ました。ありがとうございました。
返信削除