悪用厳禁!! HTTP通信を盗聴する方法【Pythonで学ぶセキュリティ】

Python

概要

本日はPythonセキュリティシリーズということでPythonを用いてセキュリティの基礎について解説してゆきます
今回は暗号化の重要さを知るために、ログインする際のユーザー名とパスワードを盗聴の仕方を紹介します
なお、今回のHTTP通信盗聴は私自身のPC内に構築したサーバに対して、私自身が行った通信に対して行っております
他人の通信を盗聴することは犯罪ですので、決して行わないでください

暗号化有無の確認方法

まずはPythonとFlaskで作成したログイン画面を用意します
みなさんはこの画面に対する通信が暗号化されているか、されていないかわかりますでしょうか?
正解は暗号化されておりません
では、暗号化されていないことはどこを確認すればわかるのでしょうか?
答えは、アドレスバーを確認すればわかります

アドレスバーをコピーしてメモ帳にはりつけるとhttp://127.0.0.1/loginとなっていることがわかります
アドレスがhttpで始まっている場合は暗号化されておらず、httpsで始まっている場合は暗号化されています
今回はhttpで始まっているので暗号化はされていないことがわかります

ログイン処理の概要

ログイン時のブラウザとサーバのやり取りは次のようになっています
ログインフォームにメールアドレスとパスワードを入力し、ログインボタンを押すと、
サーバへメールアドレスとパスワードが送信され、送信したメールアドレス、パスワードがサーバ側のデータベースにある
情報と一致すればログインに成功します

そして、メールアドレスとパスワードの送信はHTTPプロトコルで行われるのですが、この通信は暗号化されていないので
ツールを使えば簡単に盗聴することができます
試しにやってみましょう

Wiresharkの準備と実践

まずWeb通信の解析を行うためのツールが必要なのでダウンロード、インストールを行います
ツールにはWiresharkを使います。Wiresharkを用いればネットワークの通信をリアルタイムに解析することができます
インストールしたら早速起動してみましょう

起動したらどのネットワークを監視するかを選択できるのでAdapter for loopback traffic captureを選びましょう
これはローカル環境へのネットワーク通信をキャプチャできます。
今回はサーバをローカル環境に立てているのでこれが適切です

この画面になったら、ブラウザからログイン画面にもう一度アクセスしてみましょう
その後、Wiresharkの画面に戻ると通信がキャプチャできていることがわかります

試しにどのような内容か見てみましょう
例えばこのHTTP通信はGET /login HTTP/1.1は/loginというURLに対してGETリクエストを行ったことを意味します

GETリクエストとはサーバに対して情報の取得を要求するリクエストです
そして、少し後の方を見てみるとまたHTTP通信が見つかります
これは先ほどのリクエストに対するサーバのレスポンスです
HTTP/1.1 200 OK (text/html)というレスポンスが返ってきていますね。
200 OKはリクエストが成功したことを意味するレスポンスコードです。
そしてtext/htmlはHTML、つまりログイン画面を返却してきたことを意味します

Wiresharkで通信の中身を見ることができるのがわかったところで、いよいよログインをしてみましょう。
ログインを実行してWiresharkを見てみると、中にPOSTとなっているものが見つかります
POSTはデータを送信する際によく使われるリクエストです。この通信の中を見てみましょう
下の方のForm itemの項目に入力したemailとpasswordが乗っているのがわかりますね
このようにHTTP通信は暗号化されていないので、簡単にツールで盗聴できてしまうことがわかります

暗号化

では、この通信を暗号化してみましょう
暗号化にはopensslを使用します。このライブラリには暗号化に関する基本的な機能が実装されています
Windowsでopensslを使う方法は色々ありますが、今回はWSLをインストールし、Linuxについてくるopensslを使います

WSLとはWindows Subsystem for Linuxの略でWindows10上でLinuxを動作させることができます
ではWSLを準備してみましょう。Microsoft Storeを開き、検索欄にLinuxと入力します

するとUbuntuが出てくるのでそれを選択し、インストールします
少し経つとUbuntuが起動します

Ubuntuが起動したらopensslで通信暗号化の準備を行います
暗号化のためにやるべきことは三つです
秘密鍵の作成、CSRの作成、サーバー証明書の作成の三つです
やや専門的な話になるので簡単に解説すると、秘密鍵はCSR、サーバー証明書の作成に必要です
そして、CSRは証明書署名要求というものです。これはサーバ証明書の作成に必要です
最後に、サーバー証明書は通常、暗号化とWebサイトの運営者・運営組織の実在証明に使用されます
ただし、今回は前者の暗号化のみが機能する状態となっております
後者のWebサイトの運営者・運営組織の実在証明が機能していないWebサイトを公開するとセキュリティ上危険なので
ご注意ください。今回はあくまで検証用にローカル環境のサーバに用いているのでよしとしております

秘密鍵、CSR、サーバー証明書は

# 秘密鍵の作成
openssl genrsa 2048 > server.key

# CSRの作成
openssl req -new -key server.key > server.csr

# サーバ証明書の作成
openssl x509 -req -days 3650 -signkey server.key < server.csr > server.crt

生成し終えたらこれをFlask起動時の引数に与えて起動します

https://127.0.0.1:443と入力してみると再びログイン画面が起動していることがわかります

そして、以前、アドレスバーはhttpであったのに対し、今回はhttpsとなっております。
このことから通信が暗号化されていることがわかります

次にWiresharkの方を見てみましょう

先程はHTTPプロトコルの通信が表示されていたのに対して今回は表示されなくなっております
その代わりにTLSv1.3というプロトコルが見受けられます。
これはTransport Layer Securityの略で暗号化通信を行うためのプロトコルです
ここからも暗号化がうまくいっていることがわかりますね

今回の暗号化における注意点

最後に今回の暗号化について一つ注意点があります
Webサイトを公開する際に、HTTPSプロトコルを用いて通信を暗号化しさえすればよいかというとそうではありません
今回、作成した証明書は自己証明書やオレオレ証明書と言われております
証明証は通常第三者に正当性を証明してもらうものですが、今回、自分で自分の正当性を証明するようなことをしているので
信頼できない証明書となっております。
今回のような検証用に用いるのであればそこまで問題ないと思われますが、外部に公開するWebサイトには
ちゃんとした証明書を使うことをおすすめします

タイトルとURLをコピーしました