2011-01
24
07:25:54
iPhoneアプリのSSL接続をパケットキャプチャする方法


ブラウザでアクセスするWEBサービスだと、たとえSSL/TLSでセッションが暗号化されていても所詮ピア・ツー・ピア通信なので例えばFirefoxだとFirebugなどでブラウザ側でパケットをキャプチャできます。
でもiPhone(iOS)アプリだとiPhoneにそんなツールが入れられないしキャプチャできない、と思い込んでいませんか?
実は僕もそうだったのですが、この件に関連して可能なキャプチャ方法を見つけたので覚え書きで残しておきます。

但し素人の方法なのでもっと洗練された方法もあるはず。セキュリティクラスタの皆さんにおかれてはよりよい方法をご存じであればぜひTBやコメントなど頂きたく。

なおセキュリティの向上や社会的に正当な目的の下で正しく使用されることを期待してこのエントリーを記載しています。筆者は利用の結果に対して全くの無責任・無保証ですので、あくまで自己責任でご利用下さい。

概要

所謂Man In The Middle(MiTM)と呼ばれる「第三者介入」方式によるキャプチャとなります。つまりSSL/TLSは本来ピア・ツー・ピアなので第三者が通信経路上で通信傍受して暗号を複合化することは無理なので、クライアント側(ブラウザやここではiPhoneアプリ)を騙して別のサーバーに接続させ暗号を解除し、そこでキャプチャを取るという方法です。
本来は攻撃手法の一種ですが、応用すると暗号化通信でもキャプチャできるようになる、ということです。

以下に今回説明する方法の概要図を掲載します。

  1. iPhoneではホストAをターゲットサイトと誤認させる
  2. ホストAは仮想的にターゲットサイトとして振る舞う。SSL/TLSを解除しリクエストをホストBへ転送する。
  3. ホストBはリクエストを受け取って仮想的にSSL/TLSクライアントとしてターゲットサイトへフォワード
  4. ホストAまたはBにてキャプチャ

使用ツール・機材

まずは当然iPhone(もしくはiPad,  iPod touch)。iOSバージョンは問いません。
但しスムーズに行うには残念ながらJailBreakしておく必要があります。

またここでは以下のツールを利用します。

iPhone構成ユーティリティ (Windows版はこちら)
OpenSSL
stunnel
Delegate
WireShark (但しパケットキャプチャできるなら何でもいい)

iPhone構成ユーティリティ以外はマルチプラットフォームで動作するツールです。WindowsでもMac, Linuxでも動作するはずです。
機材はホストが二台必要です。仮想ホストでも構いません。僕の場合は、上記図でホストBにはWindows7を、ホストAにはBに入れていたcoLinux(Debian)を使用しました。
iPhone構成ユーティリティはMacまたはWindowsが必要です。

1. OpenSSLでCAおよびサーバー証明書を作成

まずiPhoneやstunnelで使用するためのCA証明書+キーペアおよび仮想のサーバー証明書+キーペアを作成します。
詳しくは検索などして頂きたいのですが、例えば僕は以下の手順で生成しました。

  1. /usr/lib/ssl/misc/CA.sh -newca (CAを初期構築する)
  2. openssl req -new -keyout targetserver_key.pem -out targetserver_csr.pem (仮想SSLサーバーのキーペアとCSR生成)
  3. openssl ca -out targetserver_cert.pem -infiles stargetserver_csr.pem (CAでCSRへ署名して仮想SSLサーバー証明書作成)
  4. openssl x509 -inform PEM -outform DER -in cacert.pem -out cacert.cer (CAのPEMからCER(PKCS#11)ファイル生成)

必要になるファイルはtargetserver_key.pem、targetserver_cert.pem、cacert.cerの三つです。
CA含めてDN(証明書の属性情報。国(C)とか組織名(O, OU)とかです)は適当でいいですが、唯一サーバー証明書のCN(コモンネーム。氏名などと表示される場合もあります)はターゲットサイトのホスト名に必ず一致させておく必要があります。注意しましょう。

2. stunnelの設定

syunnelは著名なSSLリバースプロキシです(SSLプロキシではなく、リバースプロキシです。ここ重要)。具体的には非SSLサーバーをSSL化する際に利用できます。例えば非SSLなメールサーバーをSSL化する例が多いようです。ここでは先の仮想サーバー証明書を組み込んだHTTPSサーバーとしてホストAで起動され、ホストBへ非SSLなHTTPとして転送します。つまりSSLアクセラレーターとして動作することになり、ここで一時的にSSL/TLSは解除されます。
コマンドラインからパラメータ起動する方法もありますが、僕はコンフィグファイルを使用しました。以下に例を載せます。
この設定ではポート443でSSL/TLSを待ち受け、ホストBのポート8080へフォワードすることになります。

/etc/stunnel/stunnel.conf

; Sample stunnel configuration file by Michal Trojnara 2002-2006
; Some options used here may not be adequate for your particular configuration
; Please make sure you understand them (especially the effect of chroot jail)

; Certificate/key is needed in server mode and optional in client mode
cert = /etc/stunnel/targetserver_cert.pem
key = /etc/stunnel/targetserver_key.pem

; Protocol version (all, SSLv2, SSLv3, TLSv1)
sslVersion = all

(略)

;[pop3s]
;accept  = 995
;connect = 110

;[imaps]
;accept  = 993
;connect = 143

;[ssmtp]
;accept  = 465
;connect = 25

[https]
accept  = 443
connect = ホストBのIPアドレス:8080
TIMEOUTclose = 0

その後起動します。
stunnel4 /etc/stunnel/stunnel.conf
サーバー証明書のキーペアのパスワードを聞かれたら入力すれば起動します。

3. Delegateの設定

ホストBにDelegateを設定します。
Delegateは説明の必要も無いぐらい著名な国産汎用プロキシでインターネット黎明期から現在に至るまで脈々と開発が継続されています。機能が大変豊富でプロキシに関わることでは出来ないことは無いほどですが、逆に豊富すぎて使いこなせないことがしばしばです。

ここでは単にホストAから受けたHTTPフォワード要求をポート8080で受け取り単にターゲットサイトへ転送するという申し訳ないぐらいの単純な利用です。本当はホストAでのSSLリバースプロキシもDelegateで行いたかったのですがうまくやり方が分かりませんでした。。

8080ポート用の設定ファイルを掲載しておきます。僕はこれをWindows上で起動しています。

8080.cfg

-P8080
ADMIN=admin@localhost
PERMIT=”*:*:*”
SERVER=https
FSV=sslway
MOUNT=”/* https://ターゲットサーバーのホスト名/*”
RELIABLE=”*”

後はコマンドラインから起動します。

dg9_9_7.exe -v += 8080.cfg

4. iPhoneへCA証明書の組み込み

ここが今回の話題の最大のポイントになります。
iPhone構成ユーティリティは主に企業内部でiPhoneを配布するために様々な設定をプロファイルという単位でまとめてiPhoneに直接設定しておくことが出来ます。このプロファイルのインストールとあるいはアンインストールも構成ユーティリティからしか行えません。
このプロファイルには企業の内部CAの証明書をインストールして信頼させる機能があるのでこれを利用します。

  1. まず構成ユーティリティを起動してiPhoneを接続します。
  2. [構成プロファイル]-[資格情報]を選択します
  3. 構成ボタンを押して、1で作成したcacert.cerを追加します。Macでキーチェーンに追加していない場合には「信頼されていない証明書」というアラートが出ますが問題ありません。
  4. デバイスからiPhoneを選択して今設定したプロファイルをインストールします。

5. iPhoneでターゲットサイトをホストAへ偽装する

このステップが必要なため、JBが必要になります。
単純に/etc/hostsファイルでターゲットサイトのホストが、ホストAのIPアドレスを示すように書き換えます。
あるいはDNSサーバーに定義済みキャッシュを設定できるならJB無しでも可能なように思いますが、試していません。

6. キャプチャを行う

これで準備は完了です。実際にiPhoneからアプリを起動して動作するかどうか確認してみましょう。正常に動作するなら、stunnelやDelegateにログが表示されるはずです。

実際のパケットキャプチャはホストA上でもB上でもどちらでも構いません。またツールもWireSharkがお薦めですが、使い慣れたツールがあれば別に何でも構いません。
ホストA<->B間のHTTP通信がキャプチャ対象です。


以上です。質問・ご意見などありましたらお気軽にコメント欄までどうぞ。但しすべてを把握している訳でもないので、その点はご容赦を。

追記

改訂版を書きました。

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください