ノートPCとWiresharkでスマートフォンの通信を覗いてみよう

AvatarPosted by

この記事は GRIPHONE Advent Calendar 2022 5日目の記事です。

こんにちは、SREの笹です。

ゲームの開発をしていると、デバッグツールで見られる一般的な情報に加えて、TCP等より物理層に近い情報を見ながらデバッグをしたいと思うことがあります。そのような時、コンピューター上で動作しているプログラムであれば、Wiresharkなどのパケットキャプチャーを使えば簡単に情報を確認できますが、スマートフォン上で動作しているゲームだとそう簡単には確認することができません。

今回は、できるだけ手軽に、簡単に、WiFiを通して接続しているスマートフォンの通信をWiresharkでキャプチャしてみようという趣旨の記事になります。

できるだけ手軽に、簡単に。

WiresharkとWiFiでパケットキャプチャーする方法を簡単に検索してみると、無線LAN親機とスマートフォンの間を流れる通信を傍受してキャプチャするような記事が多くヒットします。いわゆるパケットスニッフィング、盗聴のやり方ですね。

これを行うには、特定のモードに対応した無線LANアダプターやドライバーが必要です。自分自身が所有しているスマートフォンの通信を見るためだけに行うには少し敷居が高いように思えます。

無線LAN親機とスマートフォンの間の通信は特定の機材を利用しないとできない

一方で、本記事で紹介する方法は無線LAN親機の代わりにPC自体が親機となり、スマートフォンから接続してもらうことで通信をキャプチャする方法です。この方法では、基本的に有線LAN端子を搭載したPCもしくは有線LANアダプタとPCさえあればスマートフォンとインターネットの間を流れる通信をキャプチャでき、そのほかに特別な機材や設定は必要ありません。

いわゆるホットスポットモードを使えば簡単にキャプチャ可能

利用する機材

今回この記事を執筆するために利用した機材は下記のとおりです。

– ノートPC: MacBook Pro M1
– 有線LANアダプタ: LUA4-U3-AGTE-BK
– iPhone 12 mini
– Wireshark 4.0.0

PCをインターネットとスマートフォンの中間に置くためには、PCとスマートフォンを接続するためのWiFiアダプタと、PCとインターネットを接続するためのアダプタの2つが必要になります。今回はMacBookを利用しているので、PCとスマートフォンの接続には内蔵WiFiを利用できますが、内蔵WiFiを利用するとPCとインターネットを接続するアダプタがなくなってしまいます。そこで、インターネット接続用にUSBの有線LANアダプタを利用しています。ノートPCによっては、有線LANポートと内蔵WiFiを二つ搭載しているものがありますので、その場合は追加の機材は必要ないでしょう。

実際の接続イメージ

今回の構成では、PCの内蔵WiFiを無線LAN親機として利用してスマートフォンと接続し、PCとインターネットはUSBの有線LANアダプタを用いて接続します。

設定

PCとスマートフォンを接続するために、PCの内蔵WiFiを無線LAN親機として利用するための設定します。といっても、特殊な作業は必要なく、OS標準の画面から設定できるはずです。

macOSの場合

macOSの場合は、システム環境設定内の共有画面から設定できます。インターネット共有をクリックすると、設定画面が表示されます。

共有する接続経路のドロップボックスでは、PC本体がどの回線を用いてインターネットに接続するかを選択します。今回の場合は有線LANアダプタでインターネットに接続しているので、有線LANアダプタをここで選択します。

相手のコンピューターでのポートはWi-Fiを選択します。あらかじめWi-Fiオプションをクリックして、SSIDとパスワードを設定しておくと良いでしょう。

インターネット共有の設定

Windowsの場合

手元に検証できる環境がないため詳細は省きますが、Windowsでも条件がそろえば無線LAN親機とする設定も行うことができそうです。

モバイル ホットスポットWindows PC を使用する – Microsoft サポート

スマートフォンから接続する

これまでの設定がうまくいっていれば、スマートフォンのWiFi設定画面で無線LAN親機となったPCのSSIDが表示されているはずです。それに接続して、インターネットが表示出来れば準備は完了です。

スマートフォンからMacBook Proに接続できた

SSIDが表示されない場合、macOS自体がWiFiから切断されており、有線LANアダプタ経由でインターネットに接続されているか確認しましょう。ここでWi-Fi自体には接続ができたがインターネットに接続できない場合は、共有する接続経路が正しいものになっているか確認しましょう。

Wiresharkで通信を観察

では早速Wiresharkを用いて通信を観察してみましょう。

Wiresharkを起動すると、どのネットワークインターフェースを流れるパケットをキャプチャするかを選択できる画面が表示されます。WiFiを共有しているネットワークインターフェースを選択しましょう。私のMacBookの場合は `ap1` がWiFiを共有しているインターフェースでした。

通信量でグラフの表示が変わるので選択する目安になる

この画面で誤ってインターネットとつながっているインターフェースを選択してしまうと、スマートフォンとインターネットの通信以外にコンピューター内のアプリケーションの通信も画面に表示されてしまいます。注意しましょう。

ネットワークインターフェースを選択すると、画面が切り替わり大量のログが流れ始めるはずです。この一行一行が、スマートフォンとインターネットを流れるパケットそのものになります。

多くの場合、スマートフォンを何も操作していない状態でもログが流れているはずです。スマートフォン上のアプリケーションやOSは、ユーザーの操作によらずバックグラウンドで通信を行っていることが多々あります。そのおかげで写真の自動バックアップであったりプッシュ通知が実現されているわけですね。

ただ、このままだと自分の操作に対応したログがバックグラウンド通信のログですぐに流れてしまいます。そこでWiresharkのフィルタ機能を使い、見たいログだけを画面に表示させてみましょう。

今回はWikipediaのページを開いたときに流れるパケットを観察してみます。Wikipediaのドメイン ja.m.wikipedia.org は2022年12月現在IPアドレス 103.102.166.240 と紐づいているので、これをフィルタに追加して適当なWikipediaのページを開いてみましょう。

ページが読み込まれると同時にログが表示されました🎉 Wiresharkの強力なフィルタは設定次第で様々なログを見やすく表示することができます。Wiresharkの詳しい操作方法については割愛させていただきますが、このフィルタ機能は非常に強力なのでぜひ色々と試してみていただければ幸いです。

TIPS: HTTPSの暗号化とHTTPの盗聴

ブラウザの開発者ツールを利用したことがある人は、なぜホスト名でフィルタをせずIPアドレスでフィルタをしているのか疑問に思う方もいるかもしれません。

結論から言うと、HTTPSの通信はTLSを用いてサーバーとブラウザの間で暗号化されているためWiresharkで内容を読みだすことはできません。パケットの内容を見ることはできますが、人間には理解できない謎のデータが表示されるだけです。

TLSで暗号化されたHTTPSのデータ

Webサーバーのホスト名やパスといった情報はHTTPに含まれている情報です。これが暗号化されているため、Wiresharkで読みだすことができず、その情報を用いてフィルタを行うことができないというわけです。

逆に言えば、HTTPな通信はWiresharkで簡単に読みだすことができます。試しに、スマートフォンで私の自宅のルーターの設定画面にログインして、そのログを表示してみましょう。ルーターのログイン画面はHTTPですので、スマートフォン上に表示されているHTMLの内容からログインのパスワードまですべてWiresharkで読みだすことが出来ました。

HTTPな通信では入力したパスワードまで通信内容のすべてが表示できる

今回は自分でPCを無線LAN親機に設定しスマートフォンを繋げましたが、記事の冒頭で書いた通りネットワークの盗聴は準備さえすれば誰でも出来てしまうことです。HTTPなページで機密情報を扱うのがいかに危険であるかも理解できましたでしょうか。

劣悪な回線を再現してみよう

macOSを利用している場合は、Network Link Conditionerというツールを利用することで回線の帯域やパケットロス率、遅延なども設定可能です。

この機能を利用することで、劣悪なインターネット環境を擬似的に再現できます。例えば、固定回線のWiFi下では問題なく利用できているアプリケーションが、地下鉄では利用できなかったといった場合の問題の切り分けの手段の一つとして利用できます。

パケットロスが発生した時の挙動は利用するプロトコルにより異なります。HTTP2等で利用されているTCPでは、クライアントがパケットロスを検知するとサーバーへ再送要求を行うことでデータの完全性を維持しようとします。対して、リアルタイム通信でよく利用されているUDPやPingコマンドで利用されているICMPでは再送要求を行いません。

実際に接続して試してみましょう。今回は挙動をわかりやすくするために、上りと下りそれぞれに10%のパケットロスを設定しています。

現実の回線ではありえないほど低品質な回線を疑似的に再現

まずはPingから試してみましょう。iPhoneアプリのPingを利用します。

WiresharkはPingで利用されているICMPパケットの紐付けに対応しており、上りのリクエストと下りのレスポンスの紐付けをおこなってくれます。経路のどこかでパケットロスが発生したリクエストについては、no response found!と表示されていることが確認できます。

最終的なパケットロス率は30%を超える

ちなみに、今回Wiresharkが監視しているのは無線LAN親機となっているap1インターフェースです。Network Link Conditionerは接続しているインターネットとのパケットを制御しているため、上りのパケットはキャプチャされた後に廃棄されます。ですから、画面の中でno response found!となっているパケットは上りで廃棄されたのか下りで廃棄されたのかWiresharkでは観測できません。注意しましょう。

次はWebページの表示を試してみます。表示するWebページは先ほどのものと同じWikipediaのトップレベルドメインのページにしましょう。

先ほども記述した通り、HTTPで主に利用されているTCPはパケットがロスしたことを検知すると再送要求を行います。Wiresharkではパケットロス時の再送を行の背景を黒色にして教えてくれます。

ページの読み込みが遅くなり大量の再送が発生している

テキスト主体のWikipediaでも、かなりの再送が発生していることがわかりますね。ページの読み込みも格段に遅くなりました。設定上は50Mbpsほど出る回線ですが、それでもパケットロスが発生すると余計な通信が必要になるため体感できるページスピードも低下します。

Network Link Conditionerは共有ネットワークだけではなく、WiFiを出しているMacBook本体の通信にも影響を与えます。切り忘れないように注意しましょう。

まとめ

本記事ではWiresharkを用いてスマートフォンの通信を読み取り、パケットの流れを追ってみました。これらの物理層に近いパケットのキャプチャは、普段のアプリケーション開発ではあまり意識しないことではありますが、それゆえにハードウェアやOSに隠蔽されてしまっており、不具合が発生した時に原因を特定しにくい部分でもあります。

「コード上では何一つ間違っていないのになぜか通信がうまくいかない」「品質の悪い回線のみで不具合が発生する」といった時、このようなパケットキャプチャの手法を取ってみることで原因に一歩近づけるかもしれません。私たちのプロジェクトでも、iOS特有のコネクションリセットの挙動が原因で不具合が発生していたことを突き止めることができました。

この記事が誰かのお役に立てればと思います。