|
PHPでSQLインジェクションを実体験 本記事では、セキュリティに対する課題を実体験していく。第2回となる今回は、いよいよ実際にテスト環境を構築し、攻撃を行う。標的となるのはWebシステムの開発で幅広く利用されている「PHP」だ。 PHP本体にはWebブラウザからの入力のデコード処理をはじめとして、Webシステム開発に必要不可欠な機能が組み込まれている。2008年1月3日に最後のPHP 4.x系のリリースとなる「PHP 4.4.8」がリリースされ、これ以降PHP 4.x系の開発は行われなくなった。現在はPHP 5.x系のPHP 5.2.5のみがPHPプロジェクトにより正式にサポートされている状態だ。 データベースサーバへのアクセスもWebシステム開発には必要不可欠な機能の1つとなる。PHPはPostgreSQLやMySQL、SQLite、SQL Server、Oracleなどのデータベースサーバへアクセス可能だ。 Webアプリケーションの中で特にデータベースへのアクセスが脆弱になりやすい部分といわれている。データベースへのクエリ生成に問題がある場合、不正な文字列が挿入され、不正なSQLが実行されるとデータの漏洩や改竄が可能になる。このように不正なSQL文を挿入する攻撃は「SQLインジェクション」と呼ばれている。
SQLインジェクション
第1回:SQLインジェクションによるデータベース操作 SQLインジェクションテスト環境の準備 今回は文字エンコーディングを利用したSQLインジェクションを、実際に体験する。このため、データベースにマルチバイト文字の取り扱いが強化される前のPostgreSQL 8.1.3と脆弱性修正後の8.2.6を利用する。PHPは、PHP 5.x系のソース配付版をLinux上でコンパイルしたPHP 5.2.5を使用する。なお、PHPやPostgreSQLのインストール方法は各ソフトウェアのマニュアルなどを参照してほしい。
リスト1:データベースを作成
$ createdb -E SQL_ASCII injection_test
リスト2:テーブルの作成
injection_test=# create table table1 (field1 text, field2 text);
リスト3:テーブル作成の確認
injection_test=# \d
リスト4:sql.php
<html>
リスト5:table2が削除された
yohgaki@[local] injection_test=# \d
リスト6:SQLクエリの実行結果
SELECT * FROM table1 WHERE field1 LIKE '・ or field2 LIKE ';DROP TABLE table2;--';
まずcreatedbコマンドでPostgreSQL 8.1.3のデータベースを作成する(リスト1)。続いてpsqlコマンドで作成したデータベースに接続し、テスト用のテーブルを作成する(リスト2)。さらにpsqlで「\d」コマンドを使用し、2つのテーブルが作成できたことを確認する(リスト3)。 テーブル作成が終了したら、SQLインジェクションに脆弱なPHPスクリプトをWebサーバの適当な場所に配置する。今回は「http://localhost/sql.php」としてアクセスできる場所に配置している。スクリプト内容はリスト4の通りだ。 sql.phpはtable1からレコードを抽出するだけの参照クエリを実行する。しかし実際にはデータベース設定とPHPスクリプトに問題があるため、SQLインジェクションが可能になる。 まずはじめに「http://localhost/sql.php?q1=abc&q2=xyz」を実行した場合、table1は空のため期待通り何も表示されない。しかし「http://localhost/sql.php?q1=%95&q2=;DROP%20TABLE%20table2;--」のリクエストを送信すると、削除できてはならないはずのtable2が削除されてしまう。 このリクエストを送信後にpsqlでテーブルを一覧するとtable2が削除された事を確認できる(リスト5)。また、Webブラウザにはリスト6のSQLクエリが実行されたと表示される。本来は2つのLIKE句があるはずだが1つのLIKE句として認識され、「DROP TABLE table2」が実行されてしまうのである。 |
||||||||||
|
||||||||||
|
|
||||||||||
|
|
||||||||||
|
||||||||||
|
|
||||||||||
|
||||||||||
|
|
||||||||||
|
||||||||||

