本稿で紹介した脆弱性を回避するためには、ソフトウェアを安全なバージョンにアップグレードすることが、最も根本的な対策となる。このことは何も本脆弱性に限ったことではなく、ソフトウェアのバグによって生じるほとんどの脆弱性にいえることである。
例:本稿で利用した脆弱性の場合
(OpenSSL SSLv2バッファオーバーフロー)
この問題の修正版のOpenSSL 0.9.6e以上にアップグレードする。ただし、0.9.6eでも別の脆弱性が指摘されているため、最新の0.9.6gを利用するとよい。
例:mod_sslで使用するOpenSSLのバージョンを確認
$ strings /usr/lib/apache/libssl.so
| grep "OpenSSL 0" |
また、関連ファイルをRCSやCVSでバージョン管理しているソフトウェアの場合、ident(1)で調べるという手もある。
しかしながら、ソフトウェアのアップグレードによる対策を行ううえで、どうしても避けて通れない問題がある。それが、脆弱性が指摘(公開)されてから対策が完了するまでのタイムラグだ。つまり、そのタイムラグによって生じた時間がたとえわずかであったとしても、対策が完了するまでの間は、攻撃者に侵入を許してしまう恐れがある。もちろん、指摘される以前からその脆弱性は含まれている訳だが、脆弱性が公開される/されないでは、攻撃の被害を受ける確立は雲泥の差となるだろう。
根本的な対策が行われるまでの間、少しでも攻撃被害にあう時間を減らすためには、以下のいずれかの暫定策を実施するとよい。
脆弱性の存在するサービスのみ停止(無効)し、根本的な対策が行われるまで、そのサービスを起動(利用可能)しないようにする。
例:本稿で利用した脆弱性の場合
(OpenSSL SSLv2バッファオーバーフロー)
メリット | サービスを停止している間は確実に侵入を許さない |
---|---|
デメリット | 根本的な対策がなされるまでサービスを停止することになるため、実運用に支障をきたしてしまう |
脆弱性の中には、ソフトウェアの設定により攻撃を回避できるものもある。
例:本稿で利用した脆弱性の場合
(OpenSSL SSLv2バッファオーバーフロー)
メリット | 現状の運用サービスを維持しつつ攻撃を回避できる |
---|---|
デメリット | 場合によっては、脆弱性をつかれてしまうことがある |
対象サーバにて特定の脆弱性に対する攻撃を、最初から無効にしておけばよい。そうすれば、タイムラグによって生じる時間のみならず、脆弱性が指摘される以前からも、対象サーバの身を守ることができる。
例:スタックバッファオーバーフローの脆弱性
メリット | 特定の脆弱性による攻撃を未然に防ぐことが可能 |
---|---|
デメリット | サービスパフォーマンスの低下、そのほかのサービスの動作に影響を及ぼす可能性がある |
本来であれば、先述の「暫定策3 特定の脆弱性をついた攻撃を無効にする」で詳しく取り上げる予定だったが、Libsafeは本稿で利用したOpenSSL SSLv2のバッファオーバーフロー問題を検知してくれなかった。そのため、ここでは参考程度にLibsafeの導入事例を紹介する。
Avayaが提供するLibsafeは、スタックバッファオーバフローやフォーマットストリング攻撃を防ぐことを目的としたツールである。DLL(Dynamically Loadable Library)形式で動作し、C言語のスタックバッファオーバーフローを引き起こす関数(strcpy()やgets())に渡すデータを事前に受け取り境界値チェックを行ったり、スタックのリターンアドレスやフレームポインタの正当性チェックを行うことでフォーマットストリング攻撃も検知し、防御することが可能*2。また、そのほかのスタックオーバーフローを防ぐツールと比べ、運用環境への導入および取り外しが容易に行える。
(1)Libsafeの入手
http://www.avayalabs.com/project/libsafe/index.htmlより、LibsafeのRPM版を入手する。
(2)Libsafeのインストール
Red Hat Linux 7.3 i386に、入手したRPM版のLibsafeをインストールする。
# rpm -ihv libsafe-2.0-16.i386.rpm |
(3)動作確認
インストールした時点でLibsafeが有効になる。/etc/ld.so.preloadファイルの中身をみると、/lib/libsafe.so.2というLibsafeの動的ライブラリが指定されていることが分かる。
# cat /etc/ld.so.preload
|
/etc/ld.so.preloadに指定したライブラリは、そのOS上のすべてのソフトウェアの実行時にさきがけてロードされる。以下はlddコマンドで/usr/sbin/httpdの動的に呼び出される共有ライブラリの状況を見た結果である。/lib/libsafe.so.2が存在することが分かる。
# ldd /usr/sbin/httpd |
Libsafeでは、対応するスタックバッファオーバフローなどの攻撃を検知すると、デフォルトで/var/log/secureにその内容を記録する。以下は、スタックの境界値を越えた書き込みを行おうとした行為を記録している。問題は、/usr/sbin/httpd(Apache)プロセスの/usr/lib/apache/mod_dir.soのmemcpy()で発生している。
|
|
Libsafe: /var/log/secureに出力された内容 |
Libsafeでは、先述のLibsafeで検知したログを特定のメールアドレス宛にも送信できる。ただし、本稿で使用したRPM版のLibsafeは標準対応しておらず、メール通知機能を有効にしたい場合は、ソースコードのコンパイル時に以下の手順でNOTIFY_WITH_EMAILフラグを有効にしておく必要がある。
(1)ソースコードの入手と展開
RPM版と同様に、http://www.avayalabs.com/project/libsafe/index.htmlより入手して、展開する。
$ tar zxvf libsafe-2.0-16.tgz |
(2)NOTIFY_WITH_EMAILオプションを有効にする
$ cd libsafe-2.0-16 |
CCFLAGSが設定されている最後あたりに、以下の1行を追加し保存終了する。
CCFLAGS += -DNOTIFY_WITH_EMAIL |
(3)コンパイルとインストール
$ make |
(4)宛先の設定
Libsafeメールの送信先は、/etc/libsafe.notifyファイルに記述する。
例:security@www.example.co.jp宛にメールを送信する場合
# echo security@www.example.co.jp
> /etc/libsafe.notify |
/etc/libsafe.notifyにsecurity@www.example.co.jpの1行が追加される。設定内容は、ファイルに書き込んだ時点で有効になる。なお、検知時は以下のようなメールが指定した宛先に送信される。
|
|
Libsafe:電子メールで送信された内容 |
/etc/ld.so.preloadに指定すると、すべてのソフトウェアでLibsafeが呼び出されることになるが、これを特定のソフトウェアに限定させることも可能である。その場合は、LD_PRELOAD変数を使えばよい。
例えば、Apacheのみに限定する場合は、Apacheの起動スクリプト/etc/init.d/httpdに以下を追加すればよい。設定はApacheを再起動することで有効となる。
LD_PRELOAD=/lib/libsafe.so.2 |
また、/etc/init.d以下のすべての起動スクリプトのみに適用する場合は、/etc/init.d/functionsに上記の設定を追加するとよい。
特定サービスのみを除外したい場合は、/etc/libsafe.excludeファイルに、除外するサービスのプログラムの絶対パスを追加する。
例えば、Apacheのみを対象外にする場合は、Apacheのデーモンプログラムの/usr/sbin/httpdの1行を/etc/libsafe.excludeに追加すればよい。
以上、Libsafeを用いたスタックバッファオーバーフローへの対策例を紹介した。なお、Libsafeは、あくまでメモリのスタック領域上における不正な操作に対して有効となるものであり、まれに報告されているヒープ領域*3で発生するバッファオーバーフローに対しては有効とはならないことに注意してほしい。
また、Libsafeは、まれに正常に動作(検知)してくれないことがある。そのため必ず検知し防御してくれるものと思わない方がよいだろう。
次回は、バックドアの設置事例とその対策方法について説明する。
主に、不正アクセス監視サービス、セキュリティ検査、セキュリティポリシー策定支援などのサービス提供している。また、セキュリティに関する教育サービスも実施中。
木村 靖(きむら やすし)
セキュリティコンサルタントとして、不正アクセス監視やセキュリティ検査 などに従事している。金融機関、官公庁、大手製造業などへのセキュリティシ ステムの導入、セキュリティ検査などの実績を持つ。
Copyright © ITmedia, Inc. All Rights Reserved.