一連のNull Termination攻撃の記事の番外編として、Rubyのhttpclient2ならどうなのか、ちょっと試してみました。

ここにはこんなことが書いてあるので

Rubyのnet/httpsより
注意。net/https は RFC2818 の 3.1 に定められた「サーバーの証明書に記載された身元のチェック」を自らはしない。接続しているはずのサーバのホスト名と証明書に記載されているホスト名が一致するかをライブラリの使用者が各自実装する必要がある。


Rubyはホスト名の一致確認はしてないのかと思ったら、gotoyuzoさんや、nahiさんが「Ruby News 2007.10.04: net/httpsライブラリにおける「中間者によるなりすまし攻撃」に対する脆弱性について」に書かれている通り、ちゃんとホスト名の一致確認はしていると教えてくれました。

それではと、Ruby(のOpenSSL)ではNull Terminationの問題は起きないのかと確認してみました。OpenSSLではNullがあっても識別名の属性値は正しく"\00"のように取得できるので多分問題無いだろうと思うわけですが、、、

Rubyはちょっと書ける程度で殆ど素人同然なんで、いろいろ準備が必要です。いろいろ考えた挙句、簡単そうなんでこんな環境で試すことにしました。

・cygwin上のRuby 1.8.7-p72
・rubygemsを使う
・http-client2を使う

セットアップ



Rubyを足すとこまでは、cygwinのパッケージで普通にやって、

gemsを足すにはこのサイトからrubygems-1.3.5.tgzをダウンロードして解凍してインストールできます。

http://rubyforge.org/frs/?group_id=126参照
% tar xvfz rubygems-1.3.5.tgz
% cd rubygems*
% ruby setup.rb


http-client2

http://raa.ruby-lang.org/project/httpclient/2.1.4
% gem install httpclient --source http://dev.ctor.org/download/


以上です。すごいなぁ、セットアップは簡単です。

で、接続



Null Termination証明書の設定されたニセサーバーを立ち上げといて、以下のようなRubyのプログラムを実行します。テストなんで、ルートだけ追加しとかないといけません。

#!/usr/bin/ruby
require 'rubygems'
require 'httpclient'
URL = 'https://test.ibm.com/' #ニセのホスト
clnt = HTTPClient.new
clnt.ssl_config.set_trust_ca("00-ECOM-TEST-ROOTCA-SIG.pem")
puts clnt.get_content(URL)


で、早速接続。

/usr/lib/ruby/1.8/openssl/ssl.rb:123:in `post_connection_check': hostname was not match with the server certificate (OpenSSL::SSL::SSLError)
  from /usr/lib/ruby/gems/1.8/gems/httpclient-2.1.5.2/lib/httpclient/session.rb:260:in `post_connection_check'


とエラー表示され

test.ibm.com

Subject: C=JP, O=Evil2, CN=test.ibm.com\x00.evil.jp
とは一致しない


と、正しくエラーとなりました。さすが、nahiさんのhttp-client2は簡単だし、ちゃんとしてますねぇ。ちょっとRubyに改宗したくなっちゃいますねぇ(笑)

gotoyuzoさん、nahiさん、ありがとうございました。m(_ _)m

今日のつぶやき


httpclient簡単につかえてかなり良いんですが、set_trust_caとか証明書読み込む時、DERでもPEMでも読めるようになってると、凄くウレシイなぁと思いました。あと、別件でsqlite3-rubyを入れたいんですが、cygwin上でかなりてこずってます(泣)。この二つが解決すればムフフプロジェクトのPerlのやつをRubyに移すかなぁと思っているんですが、はてさて、どうなることやら、、、