第1章 総論
ツールの利用

セキュリティ対策の各場面でツールの利用が有効である。例えば、ソースコードを記述する場面では、対策されたランタイムライブラリの利用、ソースコード中の脆弱性が疑われる箇所を指摘してくれる静的検査ツール、ヒープのハンドリングの誤りを指摘してくれる動的検査ツール等がある。また、運用環境においても防御機能が利用できる場合がある。

ツールを利用する場面

ツールを使用する場面として、次の4つの場面が想定できる。

図1-25:ツールを利用する場面

ソースコード記述時に利用できるツール

脆弱性を生じにくいソースコードを記述しようとする際、従来のランタイムライブラリの代わりに「対策されたランタイムライブラリ」を用いる方法がある。例えば、そのようなライブラリには次のものがある。

(1) Managed String Library

領域あふれが生じにくい文字列操作ライブラリ。strcpy_m()、strcat_m()等、約25の関数が用意されている。Burch, Long, Seacord らによる。

https://www.securecoding.cert.org/confluence/display/c/Managed+String+Library

(2) Safe C String Library (SafeStr)

領域あふれが生じにくい文字列操作ライブラリ。safestr_copy()、safestr_concatenate()等約45の関数が用意されている。Messier、Viegaらによる。

http://www.zork.org/safestr/

(注:2014年4月以降サーバ応答無の可能性大)

(3) ISO/IEC TR 24731 "Safe CRT" [Windows]

従来のランタイムライブラリに出力領域長引数を追加する等の改善を施したライブラリ。strcpy_s()、strcat_s()等約70の関数が用意されている。Microsoft Visual Studio 2005にて利用できる。

https://msdn.microsoft.com/ja-jp/library/wd3wzwts(VS.80).aspx

ソースコードの静的検査に利用できるツール

プログラム中の脆弱性を、ソースコードを走査するツールを用いて比較的手早く検出する方法がある。例えば、そのようなツールには次のものがある。

(1) 関数名照合型の検査ツール

strcpy()など、取り扱いに注意を要するC言語のライブラリ関数を使用していると警告してくれるタイプの検査ツール。無償で提供されているものには次のものがある。

(2) Coverity Prevent

プログラムのビルド手順の中で情報を収集し、実際にはプログラムを動作させることなく脆弱性を検出するツール。Coverity Inc.の製品。

http://www.coverity.com/

(3) HP Fortify Static Code Analyzer (SCA)

プログラムのビルド手順の中で情報を収集し、実際にはプログラムを動作させることなく脆弱性を検出(静的解析)するツール。C、C++、Java、ASP .NET等18の開発言語に対応している。
FORTIFY SOFTWARE INC.の製品。

https://www.fortify.com/products/hpfssc/source-code-analyzer.html

(4) /analyze [Windows]

これを指定することによってバッファオーバーフロー等の問題を指摘してくれるようになるVisual C++のコンパイルオプション。Microsoft Visual Studio 2005 Team Systemに含まれる。

http://www.microsoft.com/japan/msdn/teamsystem/

デバッグ時にあふれを検出できるツール

ヒープ上の変数等、ポインタで参照される領域のあふれはソースコードの静的解析では見つけにくい。そのような問題についても検出できるようにするには、実行時に領域のあふれを監視するツールを用いてデバッグする方法がある。例えば、次のものがある。

(1) MALLOC_CHECK_環境変数 [GNU libc]

glibcがもつmalloc() - free()関連のチェック機能を活性化させる環境変数。

http://www.gnu.org/software/libc/manual/html_node/Heap-Consistency-Checking.html

(2) -D_FORTIFY_SOURCE=n オプション [GCC]

C言語のランタイムライブラリのうちのいくつかを、領域あふれを検出するバージョンに置き換えるよう指示する、GCC および glibc (GNU C Library) のオプション。n=1 または 2。

(3) Mudflap [GCC]

バッファオーバーフロー、メモリリーク、ポインタの誤使用等を実行時に検出してくれる。GCCのコンパイルオプションおよびランタイムライブラリからなる。

http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging

(4) Valgrind [GNU/Linux]

割当て領域外への書き込みや、メモリリークを検出することができるヒープデバッガを中心とした、ツールスイート。GNU/Linux用。

http://valgrind.org/

(5) Application Verifier [Windows]

Visual C++ のデバッガとともに動作し、ヒープのダブルフリー等の不具合を検出してくれるVisual Studio 2005の機能。日本語版では「アプリケーションの検証」と呼ばれる。

(6) /RTCs [Visual Studio 2005, Windows]

スタック上の文字配列のあふれを実行時に検出してくれる、Visual C++ のコンパイルオプション。/RTCs のチェックは、後述の /GS のチェックより先に行われる。

運用時に利用できる防御策

プログラム運用環境のいくつかは、領域あふれを検出して処理を中断したり、プログラム中のスタックの位置を変化させて特定アドレスを狙う攻撃を失敗に終わらせる等の防御策をもっている。以下にその主なものを紹介する。

(1) スタック破壊検出

コンパイラによっては、プログラム実行中にスタック破壊を検出する実行コードを生成するよう指示するコンパイルオプションが使える。

1) -fstack-protector [GCC]

2) /GS [Visual C++]

(2) メモリ空間レイアウトのランダム化

オペレーティングシステムによっては、プロセス起動のたびに、スタック等がメモリ空間内の異なる位置に配置されるようにできる。

1) Exec-Shieldのランダム化機能 [Linxカーネルパッチ]

プログラムのロード時に、スタックおよびヒープの開始位置がランダムに決定される。

2) /dynamicbase [Windows Vista]

このリンクオプションをつけてリンクされたプログラムは、プログラムのロード時にスタックの開始位置がランダムに決定される。加えて、text、data、bssの各メモリセグメントが標準とは異なる位置に置かれる。text、data、bssの非標準の位置はVistaの起動のたびにランダムに決定される。なお、ヒープの位置は/dynamicbaseを指定しなくても、プロセスの起動ごとに変化する。

(3) データ実行防止

オペレーティングシステムによっては、データ実行、すなわち、スタックやヒープなどのデータ領域に置かれたバイト列をマシン命令として実行することを禁止できるものがある。多くの場合「実行禁止」ビット(AMDのNXビット、IntelのXDビット)をもつプロセッサの機能が利用される。

1) Exec-Shieldのデータ実行防止機能 [Linxカーネルパッチ]

実行禁止ビットがサポートされたプロセッサの上では、data、bss、ヒープ、スタックの各セグメントにおけるデータ実行を禁止できる。実行禁止ビットがサポートされないプロセッサにおいても、スタック上のデータ実行を禁止できる。

2) WindowsのDEP (Data Execution Prevention) [Windows]

実行禁止ビットがサポートされたプロセッサで動作する、XP sp2以降のWindowsでは、data、bss、ヒープ、スタックの各セグメントにおけるデータ実行を禁止できる。

3) そのほかのデータ実行禁止機構

(4) 共通ジャンプアドレスの保護

1) /SAFESEH [Visual Studio 2005]

システムがもつ例外ハンドラアドレスワードを書き変えることによる攻撃を防ぐための Visual Studio のリンクオプション。プロセスで使われるすべてのモジュールがこのオプションでリンクされている必要がある。