暗号化した通信はtcpdumpでどう見えるか
プロトコルの脆弱(ぜいじゃく)性
前回は、tcpdumpの基本的な使い方について説明しました。今回は、tcpdumpを用いていくつかの通信内容を実際に閲覧し、それらの結果から通信を行う際のセキュリティーについて検討してみます。
HTTP、FTP、SMTP、POP3(またはIMAP4)は、いずれも私たちが普段インターネット上で提供されているサービスを利用する上で、非常に重要な役割を果たしているプロトコルです。
SMTP/POP3は、メールの送受信を行うためにはなくてはならないものですし、HTTPは、Googleに代表される検索エンジンの定着や、近年のWeb 2.0/クラウドコンピューティングと言ったキーワードの元で盛り上がりを見せている数多くのWebブラウザベースの新しいサービスの出現によって、果たす役割が年々拡大しています。
しかし、これらのプロトコルは成立した時代が古く、現在のようにさまざまな人々によって利用されることを想定していなかったため、セキュリティーに関しては当初ほとんど考慮されていませんでした。そのため、インターネットの利用者が増加し、多様化するにしたがって、これらのプロトコルのセキュリティー上の問題が指摘されるようになりました。特に、ユーザーのパスワードの扱いに関しては大きな問題となっています。
セキュリティー上の問題を解決するために、これらのプロトコルにはいずれもパスワード、または通信内容すべてを暗号化するための方法が追加されました。しかし、これらのプロトコルは互換性を保つために従来の(セキュリティー上に問題のある)方法で通信を行うことも可能としています。
また、プロトコルによっては追加された暗号化方式自体に脆弱性が発見されたなどの理由で、別の暗号化方式を用いることが推奨されている場合もあります。したがって、安全な通信を行うためにはサービスの提供者/利用者双方がセキュリティー意識を強く持ち、どのような方法を用いて通信を行うのが良いのかを調査することが重要です。
そこで、今回はパスワードなどのように第三者に知られると問題となるような通信内容を実際にtcpdumpを用いて閲覧してみます。平文で流れるパスワードを取得することが予想以上に容易であることを実感し、個々人のセキュリティー意識の向上につながれば、と思います。
tcpdumpでユーザー名とパスワードを閲覧してみよう
今回は、図1-1のサンプルプログラムを用いてメールの受信を行い、tcpdumpを用いてその通信内容を閲覧してみます。図1-1のサンプルプログラムは、指定されたPOP3サーバーへ指定されたユーザー名、パスワードで接続し、サーバーに受信メールが存在していれば、最も新しく到着したメールの内容を表示するプログラムです。なお、このプログラムは、筆者が公開しているライブラリ(http://sourceforge.jp/projects/clxcpp/)を使用しています。
図1-2は、tcpdumpを用いて、図1-1のサンプルプログラムを実行したときのパスワード送信時の通信内容を表示させたものです。平文でパスワードを送信している場合、メールを受信するための通信パケットを取得することさえできれば容易に他人のパスワードを取得できることが分かります。これは、平文でパスワードを送信しているのであれば、ほかのプロトコルにおいても同様です。
パスワードを平文で送信することの危険性は、インターネットが普及するにつれて広く認識されるようになりました。そのため、前述したように、パスワードの送受信を行うことのあるプロトコルには、通信パケットが盗聴されたとしてもパスワードが分からないようにするための暗号化方法が追加されました。通信パケットを盗聴された場合でも、パスワード(または通信内容すべて)を知られないようにする方法として、以下の2通りが存在します。
・パスワードを暗号化する
・通信経路を暗号化する
次に、これら暗号化方法のそれぞれについて説明していきます。
APOPのパスワード暗号化手順
通信パケットを盗聴された場合でも自分のパスワードを知られないようにする方法として、まずパスワードを暗号化することが検討されました。メールの受信(POP3)では、この認証方法をAPOPと呼んでいます。
APOP認証は、チャレンジ/レスポンスと呼ばれる方式を用いることによってパスワードを暗号化し、第三者から通信パケットを盗聴されたとしても、そこから第三者がパスワードが解読することはできないようになっています。チャレンジ/レスポンス方式とは、サーバーから受信した文字列(チャレンジ)とパスワードを組み合わせたものに対して何らかの演算処理を行い、その結果(レスポンス)をサーバーへ送信する方式です。APOP認証においては、演算処理にはMD5(http://www.faqs.org/rfcs/rfc1321.html)が用いられています。
MD5はハッシュ関数(不可逆な一方向関数)であるため、仮に第三者が通信パケットを盗聴することによってハッシュ値を取得することができたとしても、その値から元のパスワードを解読することはできません(非常に困難である)。
また、POP3サーバーから送信されるチャレンジ文字列は、クライアントが接続するたびに変化するため、盗聴したハッシュ値をそのまま利用することもできません(このため、チャレンジ/レスポンス方式で生成される値はワンタイムパスワードと呼ばれています)。この仕組みを用いることによって、POP3はパスワードの漏えいを防止しています。
サーバー/クライアント間におけるAPOPを用いた認証手順は、以下のようになります。
1.クライアントがPOP3サーバーに接続すると、サーバーは(APOP をサポートしていることが前提)チャレンジ文字列と呼ばれる文字列をクライアントへ送信する。
2.クライアントは、受信したチャレンジ文字列とパスワードを連結して、その文字列のMD5ハッシュ値を計算する。クライアントは、このハッシュ値をパスワードとして、ユーザー名とともにサーバーへ送信する。
3.サーバーもクライアントへ送信したチャレンジ文字列とサーバーに保存されているユーザーのパスワードを用いて、クライアントと同様の方法でMD5ハッシュ値を計算する。サーバーは、自らが計算したハッシュ値とクライアントから送信されたハッシュ値を比較することによって認証処理を行う。
tcpdumpで通信内容を見てみる
最後に、tcpdumpを使って、APOP 認証を用いてメールの受信を行っている通信の様子を閲覧してみます。
図2-1のサンプルプログラムは、図1-1の最新の受信メールの内容を表示させるサンプルプログラムにAPOP認証を行う処理を追加したものです。また、図2-2はtcpdumpを用いて、図2-1のサンプルプログラムを実行したときの通信内容を表示させた結果の一部(パスワードの送受信部分)を表しています。図2-2を見ると、ユーザー名は依然として容易に取得することができますが、パスワードの部分は解読できない文字列に暗号化されていることが分かります。
HTTPやSMTPなどほかのプロトコルにおいても、暗号化の手順や使用するハッシュ関数など詳細部分に違いはありますが、基本的にはAPOPと同じような方法でパスワードを暗号化し、認証を行うための方法が提供されています。
次は経路上の通信を暗号化する方式について解説します。
通信経路の暗号化
先に述べたように、APOP認証方式を用いてパスワードを暗号化することによって、通信パケットが盗聴されたとしても、ユーザーのパスワードが漏えいすることを防ぐことができます。しかし、この方法を用いた場合には、ユーザーのパスワードのみしか暗号化されず、それ以外の内容に関しては平文のまま通信が行われます。
そのため、例えばクレジットカードの情報などのように、通信内容自体に重要な情報が含まれるような場合には、その情報が漏えいしてしまう危険性があります。
また、APOP認証方式にはその認証手順や使用しているハッシュ関数自体に含まれる脆弱性のために、第三者によって暗号化された値が解読されてパスワードが漏えいしてしまう危険性が指摘されています(参考:独立行政法人 情報処理推進機構「APOP(エーポップ)方式におけるセキュリティー上の弱点(脆弱性)の注意喚起について」(http://www.ipa.go.jp/security/vuln/200704_APOP.html)。この問題については、現時点では根本的な対策方法は存在していません。
そこで、これらの問題を回避する方法として、SSL/TLSを利用して通信経路自体を暗号化することが推奨されています。SSL/TLSを用いた場合、送信ホストはパケットを送信する際に、データ部分を暗号化して送信します。そのため、第三者が通信パケットを盗聴したとしても、通信内容(パケットのデータ部分)を知ることができないようになっています。
POP3においては、SSL/TLSを用いた通信はPOP3 over SSL(POP3S)と呼ばれています。POP3S通信はPOP3用のデフォルトのポート番号である110番ポートではなく、通常995番ポートが用いられます。HTTPやSMTPなどほかのプロトコルにおいても、SSL/TLSを利用して通信を行う場合はそれぞれHTTPS、SMTPSと呼ばれ、通常の通信に使用されるポート番号とは別のポート番号を用いて通信を行います(通常、HTTPSは443番ポート、SMTPSは465番ポート)。
tcpdumpで通信内容を見てみる
では、実際にtcpdumpを用いて、POP3Sを用いてメールの受信を行っている通信の様子を閲覧してみます。図3-1のサンプルプログラムは、図2-2のサンプルプログラムにPOP3Sを用いて通信するように修正を加えたものです。また、図3-2はこのサンプルプログラムの実行したときの通信内容をtcpdumpで表示させた結果の一部を表しています。図3-2を見ると、パスワードのみならず、通信内容がすべて解読できない文字列に暗号化されていることが分かります。
必ずしもすべての場合において、通信内容を暗号化しなければならない訳ではありません。LAN内のように基本的には信用できる人のみで構成されたネットワーク内で利用するなど、セキュリティーに過敏にならなくても良いような場合も存在します。
また、利用しているサーバーがSSL通信をサポートしていない、またはサポートしていたとしてもサーバー証明書などの扱いが不適切であるなどの理由で、パスワード認証の際にはAPOPなどの認証方式を強いられる場面にも遭遇します。しかし、少なくともインターネットを介して(重要な)データの送受信を行う場合には、十分にセキュリティーに注意する(場合によっては、利用することを止める)必要があるだろうと思います。