なぜPHPアプリにセキュリティホールが多いのか?

第6回意外に知られていないブラインドSQLインジェクション

前回の記事でSQLインジェクションの話は終わりにして、クロスサイトスクリプティングの話を書かせて頂こうと思っていました。しかし、6月5日に東京にて開催されたPostgreSQLカンファレンス2007でセキュリティをテーマに講演させて頂き、意外にブラインドSQLインジェクションをご存じでない方が沢山いらっしゃいました。40名ほどの聴講者の皆様にSQLインジェクションをご存じの方?とお聞きするとほぼ全ての方が知っていると答えたのですが、ブラインドSQLインジェクションをご存じの方は数名でした。

SQLインジェクションの常識

ブラインドSQLインジェクションの話をする前に、SQLインジェクションとその対策の常識について確認します。

SQLインジェクション対策として間違ってはいないが不十分な対策

  • エラーメッセージを表示しない(特にSQLエラー)
  • ユーザ入力文字列をエスケープする

これらはSQLインジェクション対策として有用な対策ですが、十分な対策ではありません。この連載でも解説済みですが、SQLインジェクションを確実に防ぐには、全てのクエリにバインドメカニズム(ストアドプロシージャ)を利用する、すべての変数を文字列として処理しエスケープするの2種類の対策があります。

これらの対策を行っても、1ヶ所でもブラインドSQLインジェクションによって攻撃可能である場合、データベース全体のデータを盗まれたり、改ざんされる危険性があります。

以下はよくあるSQLインジェクションの脅威に対する誤解です。

  • データベースの構造を知られていなければ攻撃できない
  • エラーメッセージを表示しなければSQLインジェクションによって攻撃されない
  • SQLインジェクションを成功させるには高度な攻撃スキルが必要である

これらは全てとても危険な誤った認識です。

ブラインドSQLインジェクション

PostgreSQLカンファレンスの私のセッションをお聞きになられた方は、デモによりいかに簡単にブラインドSQLインジェクションが可能か理解いただけたと思います。

ブラインドSQLインジェクションを利用した攻撃手順

  1. SQLインジェクションに脆弱な箇所を見つける
  2. フィンガープリンティングによりSQLデータベースサーバの種類を判別する
  3. ブラインドSQLインジェクションを行い、データベースの構造を解析する
  4. 攻撃用のSQL文を実行させ、情報の不正取得や改ざんを行う

まず、SQLインジェクションに脆弱な部分を発見するのは比較的簡単です。例えば、レコードIDの入力が可能な箇所を探すには、ID番号の代わりに

1 AND 1 = 1

1 OR 1 = 1

のような文字列を送信してアプリケーションの動作がどのように変化するか観察するとSQLインジェクションに脆弱か判別できます。これ以外にもSQLインジェクションに脆弱かチェックするために便利な文字列はいくつもあります。エラーメッセージが表示されなくてもプログラムの動作はSQL文の実行結果によって変化します。プログラムが予期していない入力を与えることによって発生するアプリケーションの動作の違いによって攻撃者が簡単にSQLインジェクションに脆弱か判別できます。

データベースサーバの種類もフィンガープリンティングによって簡単に判別できます。ステップ1でSQLインジェクションに脆弱な箇所がわかっているので、その脆弱性を利用してDBMS特有の関数が利用できるか調査します。例えば、MySQLを利用している場合はbenchmark()関数が利用でき、PostgreSQLの場合はpg_sleep()関数が利用できるかチェックすることによりデータベースサーバの種類が判別できます。

次にブラインドSQLインジェクションを行ってデータベースを解析します。ブラインドSQLインジェクションにはデータベースシステムのシステムカタログ(テーブル定義などを保存したシステムデータベース)をクエリしてテーブル名やフィールド名を解析します。

SQL Serverのフィールド名を取得
SELECT name FROM syscolumns
WHERE id =(SELECT id FROM sysobjects
           WHERE name = 'tablenameforcolumnnames')
PostgreSQLのテーブル名を取得
SELECT tablename FROM pg_tables WHERE schemaname= 'public'

詳しい解説は省略しますが、ブラインドSQLインジェクションが可能な場合、テーブル名、フィールド名、データ型などデータベース定義全体を解析できます。

最後に解析したデータベースの設計情報とSQLインジェクション脆弱性を利用して、目的のデータを盗んだり、改ざんします。データベース構造がわかっているので、SQLインジェクション攻撃を成功させるのはそれほど難しいことではありません。

SQLインジェクション脆弱性は非常に危険

すべてのSQLインジェクション脆弱性がブラインドSQLインジェクションに利用できるわけではありませんが、SQLインジェクション脆弱性の多くがブラインドSQLインジェクションを許してしまいます。SQLインジェクション対策は非常に簡単ですが、作ってしまうと非常に危険な脆弱性であることを、Webサイト運営者と開発者は理解していなければなりません。

参考URL

SQL Injection Cheatsheet
http://ferruh.mavituna.com/makale/sql-injection-cheatsheet/
Blind SQL Injection (PDF)
http://www.spidynamics.com/whitepapers/Blind_SQLInjection.pdf

おすすめ記事

記事・ニュース一覧