書式文字列攻撃

書式文字列攻撃(しょしきもじれつこうげき、: Format string attack)は、1999年ごろ発見された(それまでは無害と考えられていた)セキュリティホールを利用した攻撃のクラスである。書式文字列攻撃は、プログラムをクラッシュさせたり、不正なコードを実行させたりできる。

概要

問題は、printf() などの書式指定のあるC言語の関数で、ユーザーが入力した文字列をそのまま書式文字列として利用する場合に発生する。悪意のあるユーザーが %s や %x といった書式トークンを使い、スタックやその他のメモリ位置の内容をデータとして出力させることができる。また、%n トークンを使って任意のアドレス位置に任意のデータを書き込ませたりする。

これらのテクニックを組み合わせて、ライブラリ関数のアドレスを書き換えたり、コールスタック上のリターンアドレスを書き換えて不正なコードを実行させる。書式文字列を工夫することで書式文字列自体が変換対象の引数となるようにでき、書式文字列の先頭に %n で上書きされるアドレスを含めておくと、不正なコードを指定したアドレスに書き込める。

それまで書式のバグがあっても危険はないと考えられていたため、この種の脆弱性を持つツールが多数存在することがわかった。MITRE's CVE project のリストによれば、約 150 もの脆弱なプログラムがある。

この種のバグは、プログラマがユーザーの入力した文字列を表示しようとした場合に現れやすい。プログラマが printf("%s", buffer) と書くべきところを printf(buffer) と書いてしまう場合である。この場合、buffer が書式文字列として解釈され、変換文字が含まれているとそれを書式として翻訳しようとする。printf("%s", buffer) であれば、単に入力された文字列を表示するだけである。

この問題は、C言語の引数の解釈で型を意識しないために発生する。特に printf でも使われている varargs 機構はサブルーチンに任意個の引数を渡せる。printf では第一引数である書式文字列の内容によって必要な引数の個数が決まり、それによってコールスタックから引数を pop して使用する。

このバグは1990年にウィスコンシン大学で行われた評価(各種APIにでたらめな引数を与えてシステムクラッシュなどの問題が発生しないかを調査)で最初に見つかった(Miller, Fredriksen, So 1990 参照)。彼らはこれを "interaction effects" と呼び、cshの評価でそれを見つけている。このような不具合の評価手法は後に他者によって体系化され、ファジングと呼ばれることになる。

書式文字列のバグで攻撃される可能性は Tymm Twillman が ProFTPD デーモンのセキュリティ検査中に発見した。その検査で、snprintf にユーザーが入力したデータがそのまま書式文字列として使われているのが見つかった。さらなる評価の結果、このバグを利用してセキュリティを破ることが可能と判明した。この結果を 1999年9月にBugtraqメーリングリストに新たな脆弱性報告としてポストした[1]。しかし、これが重大な問題であると認識されるまで数ヶ月を要することになった。

危険な書式文字列を防ぐ方法

多くのコンパイラは書式文字列を静的にチェックし、問題がある場合には警告を発する。

GNUコンパイラコレクションでは、適当なコンパイラフラグとして、-Wall,-Wformat, -Wno-format-extra-args, -Wformat-security, -Wformat-nonliteral, -Wformat=2 がある[2]

関連項目

参考文献

  • Robert C. Seacord: Secure Coding in C and C++. Addison Wesley, September, 2005. ISBN 0-321-33572-4
  • Tobias Klein: Buffer Overflows und Format-String-Schwachstellen, Dpunkt Verlag, ISBN 3-89864-192-9.
  • Crispin Cowan: Software Security for Open-Source Systems, Published by the IEEE Computer Society, IEEE SECURITY & PRIVACY, JANUARY/FEBRUARY 2003, http://computer.org/security
  • Barton Miller, Lars Fredriksen, Bryan So: An Empirical Study of the Reliability of UNIX Utilities, Communications of the ACM, vol. 33, no. 12 (December 1990). Also appears (in German translation) as Fatale Fehlerträchtigkeit: Eine empirische Studie zur Zuverlässigkeit von UNIX-Utilities, iX, March 1991. http://www.cs.wisc.edu/~bart/fuzz/
  • Crispin Cowan: FormatGuard: Automatic Protection From printf Format String Vulnerabilities, Proceedings of the 10th USENIX Security Symposium, August 2001. http://www.usenix.com/events/sec01/full_papers/cowanbarringer/cowanbarringer.pdf

脚注

外部リンク