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


今日は久しぶりにセキュリティ関係について書き残そうと思います!

 

皆さん、世の中のサイトの何割位に脆弱性があると思いますか?

正解はなんと、9割方のページに何らかの欠陥があるという調査結果が出ているそうです、、、

今日はその脆弱性をつく手法の中で、『ブラインドSQLインジェクション』というものについてちょっとだけ説明しようと思います。

 

 

皆さんはSQLインジェクションについては知っていると思いますが、よく見かける文献にある実行例はどれもテーブル名等々が分かっている状態で実行するのがほとんど。ぺネトレーションテストを行う場合、当たり前ですが攻撃者はそんな中の情報は知らない前提で行うものです。

まずはSQLインジェクションについて少し。

これはアプリケーションのセキュリティーホールを利用して、任意のSQL文を注入(inject)し実行させ、データベースを不正に操作することを指します。

例えば、以下のようなSQL文があるとします。以下実行環境をMicrosoft社のSQLServerとします。

SELECT * FROM user WHERE id = '(会員ID)' AND pass ='(パスワード)';

ウェブのSQLインジェクションに対して未対策のログインフォームで、ID「testid」は分かっているがパスワードが不明な場合、ID欄に『testid'; --』と入力すると以下のような文ができます。

SELECT * FROM user WHERE id = 'testid'; --' AND pass ='(パスワード)';

『--』以降はコメントアウトとして処理されるため、パスワードの如何に関わらず「testid」さんとして問題なくログインできます。仮にパスワードの入力判定をしている場合でも、適当な値を入力さえしていれば通ってしまいます。

たとえIDが分かっていなくても、『' OR 1=1; --』と入力すれば、

SELECT * FROM user WHERE id = '' OR 1=1; --' AND pass ='(パスワード)';

となり、idカラムにどんな値が入力されようと『1=1』は常に真なのでuserテーブル内の全てのレコードが選択されます。

 

ここまで原理が分かってしまえば後は何でもし放題ですよね?w

試しに『'; UPDATE user SET pass=''; --』と入力したとすると、、、とんでもないですね。

SELECT * FROM user WHERE id = ''; UPDATE user SET pass=''; --

ログインは出来ず、一瞬失敗したかな?と思いますが、その裏では全てのパスワードが削除されているのです。あぁおそろしや・・・・・

 

 

ここで疑問が生じますよね?

『おい、なんでテーブル名がuserで、カラム名がpassということが分かってんだよ!』

・・・その通りです、ゴメンナサイ。ここで登場するのがブラインドSQLインジェクションです。

原理はとっても簡単で、『最初のテーブル名は1文字目がuか?2文字目はsか?』なんて事を延々と続けていけばいいんです。条件文にサブクエリを含ませて、その真偽によって判断します。

 

テーブル名を取得するためには

SELECT name FROM sysobjects WHERE xtype = 'U';

とすれば良いです。

試しに『' OR (SELECT count(name) FROM sysobjects WHERE xtype = 'U') > 0 --』を入力します。これは(テーブル数)>0は真かどうかを見ているので、テーブルがひとつでもあればログインできます。これを使えばサーバー内にあるテーブル数は確定できますね?(別に使うこと無いけどww)

 

では続いて先頭のテーブル名を得てみましょう。

' OR lower(substring((SELECT min(name) FROM sysobjects WHERE xtype = 'U'),1,1)) >= 'n' --

まず『SELECT min(name) FROM sysobjects WHERE xtype = 'U'』で先頭のテーブル名を取得し、これを以下'user'とします。substring('user',x,y)でx文字目からy文字取得し、ここでは'u'となります。lower()によって小文字へ変換されるため、決定が容易になります。

'u'は'n'以降なのでここでログインは成功します。次に'n'を't'として真、'x'として偽、'v'として偽、'u'として真なので1文字目が'u'と定まります。

それでも心配なら、『>= 'u' --』を『= 'u' --』として確実に確認してみるのもいいでしょう。

次は2文字目の確認です。substring()の引数を(x,y)=(1,2)として'un','ut'・・・としても間違ってはいませんが、毎回毎回'u'を打つのは非効率的です。なので、(x,y)=(2,1)とすれば'n'として真、't'として偽、'q'として真、's'として真より2文字目が's'と決定します。

これを繰り返して'user'まで求まったとします。しかし、ここで決定したぞ!と喜んではいけません。まだ4文字目も以降名前が続く可能性は十分あるからです。

' OR (SELECT count(name) FROM sysobjects WHERE xtype = 'U' AND name = 'user') > 0 --』として真なら'user'テーブルは存在し、晴れて先頭のテーブル名を決定することができました。

 

'user'の次のテーブル名を取得するには、

' OR lower(substring((SELECT min(name) FROM sysobjects WHERE xtype = 'U' AND name > 'user'),1,1)) >= 'n' 』として同じ事を繰り返せばOKです!ww

今回はSQL Serverを対象としましたが、それ以外は以下のようにすれば良いです。

Oracle
select * from all_objects where object_type='TABLE';

PostgreSQL
select * from pg_tables where not tablename like 'pg%' order by tablename;

H2
select * from INFORMATION_SCHEMA.tables;

では、今日はここまで~

SynAck Capture Nite 2011 参加してきました。


その名のとおり、ネットワークキャプチャの勉強会に参加してきました。
NiteってNightの間違いじゃないの?と激しく思っていたところ、主催者の方からしっかりと解説

『最近って色々省略するのが流行ですもんねw』

って、えー 本当ですか???

まぁ、そんなこんなで始まったこのSynAck Capture Nite 2011、実は北海道の『北海道情報セキュリティ勉強会(セキュポロ)』にも同時中継されていたようです。

まず、ネットエージェントの杉浦社長によるから『永続的パケットキャプチャのすすめ』という講義を受けました。

普段皆さんもパケットキャプチャに使われているであろうWiresharkですが、これではメモリの要領を超えて記録することはできません。
ということは、永続的にキャプチャし続ることはできない⇒インシデントが起きた時実際のパケットを確認できない!!

そんなわけで紹介されたのがこの Packet Black Hole
・・・まぁ、自社製品の宣伝ですねwww

その後、パケット記録用の媒体(HDD等)の話もありましたが、ここでは割愛させていただきます。

キャプチャだけでなく、IDSを本格的に運用するならSnortとかtsharkとかどう?とのことです。
Snortはセプキャン以来使ってないな・・・と懐かしく思い出されます~

続きまして、この記事のカテゴリにAndroidが含まれてる所以ですね。
一応個人としてもAndroidのアプリ開発者なので、この話にも非常に興味惹かれました。

まぁどういう内容かといいますと、ダウンロードしてるAndroidアプリの解析ですね。
まずはパケットキャプチャです。端末をWi-Fiネットワークに接続し、ミラーリングハブを噛ませてパケットを取ります。
これは単純にWiresharkで十分でしょう。
そこからapkファイルを抽出、それをunzipでclass.dexを取り出します。
Dex2jarをかけてjarファイルに変換し、JDでデコンパイルすればもうそこにはソースコードが・・・

とのことですが、家にはミラーリングハブはありません。なのでARPスプーフィングをしてキャプチャを試みましたが、予想通りSSHの通信は中継できず、試みははなから頓挫しましたorz

まあ、いずれかまた取り組みます!乞うご期待ですね。

次のセッションは、DEFCON19に参加した @ghetto2199さんによるCTFパケット解析の講義です。

ここでまめ知識ですが、DEFCONとは毎年ラスベガスで開催されている世界最大級のセキュリティ会議と言われるものです。
DEFCONでは講演以外にも、セキュリティに関するワークショップなどさまざまなイベントがありますが、その中でも特に人気と言えるのがCTF(Capture The Flag)です。
CTFでは各チームにサーバー機とイメージが配布され、互いに自分のサーバー上のサービスを守りながら、相手の秘密鍵の奪取や上書きなどの攻撃をします。
自らのバイナリを解析して脆弱性を見つけてパッチを当てながら相手を攻撃するとても高度な戦いです。(二十年以内に絶対行ってやる!!!!)

てなわけでDEFCONの説明を簡潔にしたところでパケットの解析された結果です。
@ghetto2199さんの所属するsutegoma2チームが攻撃を受けたサービスの一部を紹介。

1、telephone

Port:1477

キーが奪取される

攻撃パケットはエンコードされていた

上部のパケットがデコーダーになっている

2、htlame

Port:42737

telephone経由で/tmp/foobar/にシンボリックファイルを張られる

キーが奪取される

3、rotary

Port:3375

キーの奪取と上書き

攻撃パケットがIDSに引っかからなかった理由、それはそれぞれが独自のエンコーダを使用しているからとか
ヘッダ部分にデコーダとなるバイナリが含まれているとかおそろしや((((;゜Д゜)))

主催者のまっちゃだいふく(@ripjyr)さん、会場提供のネットエージェントさん、ありがとうございました。