Metasploitable2でWebアプリの脆弱性を勉強する(SQLi その4)

※記事の内容は、ご自身が管理するサイト以外には絶対に使用しないでください。

[OWASP TOP10] A1_Injection_SQLi_4_Blind_SQL_via_Timing_Login


f:id:jiranyan:20190307170158p:plain

Blind SQL via TimingなのでTime-based SQL Injectionという理解でよいでしょう。

ログイン画面は A1_Injection_SQLi_2_BypassAuthentication_Login で既に検証済みなのでなのでHTTPリスエスト(パラメータ)やSQLなどについてはをそちらをご覧ください。

Time-based SQL Injectionについては、徳丸さんの記事で簡潔に説明されています。後述する実用例も参考にさせていただきました。

blog.tokumaru.org

まずは、単純なTime-based SQL Injectionの検証を行います。時差を利用してSQLiを検証するのでSleepを使用します。

SQLのイメージは下記のようになります。

SELECT * FROM accounts WHERE username='hogehogehoge' and password='hoge' and sleep(1)-- '

まずパラメータに「' and sleep(1)-- 」(1秒スリープ)を挿入し送信します。右下の処理時間に着目してください。

f:id:jiranyan:20190307173849p:plain

次にパラメータに「' and sleep(5)-- 」(5秒スリープ)を挿入し送信します。右下の処理時間に着目してください。

f:id:jiranyan:20190307174257p:plain

実際には8秒遅延していますが、まあSQLiが効いているということでよいでしょう。本来ですともっとサンプリングした方がよいですがsleepが効いていることがわかればよいです。

次に、Time-based SQL Injectionを利用して、情報を抜いてみます。やはり攻撃者としては認証情報が欲しいところですので、パスワードを調査します。

SQLのイメージです。「admin」のパスワード(文字列)を先頭から1文字づつ抜いていき、指定した文字と同じだったらsleepするという検証していくという方法です。

SELECT * FROM accounts WHERE username='hogehogehoge' AND password='hoge' and (select if(substr((select password from accounts  where username='admin'),1,1)='a',sleep(1),0))

試してみます(ブラウザからのリクエストを改ざん)

まずは先頭の文字が一致しないケースです。ちなみにパスワードは「adminPass」です。82millsecで処理されています。

f:id:jiranyan:20190307175950p:plain

次に先頭の文字が一致する[a]ケースです。2069millsecで処理されています。sleepが効いているようです。2秒遅延だけど・・・

f:id:jiranyan:20190307180551p:plain

2文字目不一致

f:id:jiranyan:20190307181036p:plain

2文字目一致[d]

f:id:jiranyan:20190307181339p:plain

3文字目不一致

f:id:jiranyan:20190307182710p:plain

3文字目一致[m]

f:id:jiranyan:20190307182812p:plain

4文字目不一致

f:id:jiranyan:20190307183406p:plain

4文字目一致[i]

f:id:jiranyan:20190307183423p:plain

5文字目不一致

f:id:jiranyan:20190307183438p:plain

5文字目一致[n]

f:id:jiranyan:20190307183451p:plain

以降、同じように繰り返していけば、いつかパスワードを抜くことができますね。