今回は、古いCMSに潜むSQLインジェクションの脆弱性を検証する。データベースを操作した結果、どんなことが可能になるのか、その危険性をあらためて認識してほしい。
こんにちは。前回の「古い「ZenPhoto」でXSS脆弱性のリスクを確認」では、CMSの蓄積型クロスサイトスクリプティング(XSS)という、タグをそのままコメントに埋め込むことのできる脆弱性を利用して、フィッシングに悪用される恐れのあるダイアログを表示させ、その危険性を実証してみた。
今回は、CMSに潜むSQLインジェクション脆弱性を使ったデータベースの操作にチャレンジしてみたい。
なお本稿で実験に使用する環境は、当たり前だが非常に脆弱なので、絶対に本番環境に使用してはいけない。また本稿で知った攻撃手法を他者の管理するサーバで実行することは、高い確率で不正アクセス禁止法に抵触するため、絶対に行ってはいけない。
実験を行う前に、そもそも「SQLインジェクション脆弱性とは何ぞや?」について、簡単に解説しておこう。
SQLインジェクションとはその名の通り、SQLを挿入する脆弱性だ。Webアプリケーション側が想定しているSQLに外部から細工を加えることで、攻撃者がいろいろとデータベースを操作できてしまう。
もちろん、前提として、外部からの入力値をプログラムが処理する場面が必要となるのはいうまでもない。
簡単な例を挙げて解説しよう。流れは以下のようになる。まず、
http://example.jp/?pass=1
のような、passというパラメータを受け取って処理を行うプログラムがあるとする。処理を行う側(=Webアプリケーション側)は、
$sql='select * from `table` where `pass`=$_GET["pass"]';
のようにして、SQL文を組み立てて実行する。これは、パスワードをDBに保存されているものと比較し、一致した場合はログインに成功し、処理を続行するようなプログラムだ(ここではパスワードを数値としているが、あくまで簡易的なチェックを想定した例である)。
ここに、
http://example.jp/?pass=1 or 1=1
のようなURLでアクセスするとどうなるだろう。ここから導き出されるSQL文は
select * from `table` where `pass`=1 or 1=1
となり、その結果「select * from `table`」と同じようにすべての値が返ってくるようになる。もし、プログラムが「何がしかの値が返ってきたら認証成功」という内容だったなら、アクセス認証を回避できてしまうことになる。
このようにSQLインジェクションとは、外部からの入力によって実行するSQLが書き換えられることで、不正アクセスや情報漏えいなど、開発者が思ってもみない事態が起きることが分かるだろう。
SQLインジェクション脆弱性は、基本的にユーザーの入力を処理する際の不手際に起因する。そこで、基本的な対策は入力値をチェックし、SQLの区切り文字などをきちんとエスケープするということになるのだが、どうしても漏れてしまうことがある。そこで最近では、原理的にSQLインジェクションが発生しにくいとされるプレースホルダの使用が推奨されているようだ。
とはいえ、オープンソースのWebアプリを利用するすべての人がソースコードを読んでから導入するわけではない。となると使う側としては、そのWebアプリに脆弱性がないことを願うしかない。
ここからは実際に、SQLインジェクション脆弱性のあるWebアプリをインストールすることにする。インストールするのは2012年に脆弱性が見つかった「BabyGekko」というCMSだ。この脆弱性については筆者も報告したが、その前に別の人が報告していたようで、返事が届く前に修正されていた。なおこのBabyGekkoは、2013年2月にSCHLIXという名称にリニューアルされている。
脆弱性のあるバージョンは1.2.2e以前なので、ここでは1.2.2eをダウンロードする。
ダウンロードしたら、ターミナルを開き、前回インストールしたlamppのドキュメントルートに解凍する。
$sudo unzip gekko_web_builder_v1.2.2e.zip -d /opt/lampp/htdocs/
次にconfigファイルが必要になるので、サンプルをコピーし、書き込み権限を付与する。
$cd /opt/lampp/htdocs/gekkocms/ $sudo cp config.inc.sample.php config.inc.php $sudo chmod 666 config.inc.php
そして、実験用にgekkocmsフォルダに書き込み権限を加えておく。
$sudo chmod 777 /opt/lampp/htdocs/gekkocms/
次に、phpMyAdminを使い(別に手段は何でもいいが)、BabyGekkoで使用するデータベースとユーザーを作成する。前回同様に新規ユーザーを作成し、ユーザーと同名のデータベースにチェックを入れておけばいいのだが、後の実験のため、グローバル権限の「FILE」にチェックを入れておく。
DBの設定が終わると、WebからBabyGekkoのインストール作業を行う。インストールURLは以下のとおりだ。
http://サーバのIPアドレス/gekkocms/install/
アクセスすると、すべてのチェック項目に緑のチェックが入っているはずだ。入っていない場合は、確認して修正する。
そして、先ほど作成したデータベースの情報を入力して、「Test it」ボタンをクリックする。
問題なければ「So far everything looks great!」というダイアログが表示されるだろう。そして、「Test it」ボタンの下に→「Please click here to proceed」というリンクが増えているので、そこをクリックする。
するとCMSの設定と管理者ユーザーのパスワードなどを設定する画面が表示されるので、適当な値を入れて「Submit」ボタンをクリックする。なお、メールアドレスが「@IPアドレス」になっている場合はエラーが出るので、適当なドメイン名に変更する。
するとデータベースが作成される。サンプルデータを投入するかどうか尋ねられるので、ラジオボタンを「Yes」に合わせて、「Submit」ボタンをクリックする。
これでインストールは終了した。/install/フォルダを別の名前に変更するか削除しておこう。
http://サーバのIPアドレス/gekkocms/
を見ると、サンプル画面が表示されるのが分かるだろう。
管理者としてBabyGekkoにログインするには、
http://[サーバのIPアドレス]/gekkocms/admin/
にアクセスする。
これで管理者メニューが表示されるはずなのだが、エラーがあるようで表示されない部分がある。調査したところ、/gekkocms/jsに.htaccessにエラーがあるようだ。
$vi /opt/lampp/htdocs/gekkocms/js/.htaccess
で開き、
RewriteRule yui_combo.js js_gzip.php?js=yui_combo RewriteRule yui_mini_utilities.js js_gzip.php?js=yui_mini_utilities
を
RewriteRule yui_combo.js /gekkocms/js/js_gzip.php?js=yui_combo RewriteRule yui_mini_utilities.js /gekkocms/js/js_gzip.php?js=yui_mini_utilities
に修正する。
Copyright © ITmedia, Inc. All Rights Reserved.