ブラインドインジェクションにおける時間ベースおよびブールベースのインジェクション方法について話す

SQLエラーインジェクションは、この種の脆弱性のようにひどく使用されており、脆弱性発見ツールをバッチで探し、sqlmapが実行されました。

今日は、コマンドがデータベースクエリステートメントに取り込まれたが何も返されない場合に何をすべきかについて話します。たとえば、アプリケーションは「一般的な」ページを返すか、一般的なページ(おそらくWebサイトのホームページ)をリダイレクトします。現時点では、以前に学習したSQLインジェクション方式は使用できません。

ブラインドインジェクション、つまりSQLインジェクションプロセスでは、SQLステートメントが選択された後、選択されたデータをフロントエンドにエコーできません。判断または試行するには、いくつかの特別な方法を使用する必要があります。このプロセスはブラインドインジェクションと呼ばれます。

ブラインドSQLインジェクションは、次の3つのカテゴリに分類されます。

1.ブールSQLに基づくブラインドインジェクション

2.時間ベースのSQLに基づくブラインドインジェクション

3.エラー報告に基づくブラインドSQLインジェクション


プロセス全体で使用されている3つの機能があります

1.mid()関数

mid(striing、start、length)

string(必須)は、返される文字列の一部を指定します。

start(必須)は開始位置を指定します(開始値は1です)。

length(オプション)返す文字数。省略した場合、mid()関数は残りのテキストを返します。


2.substr()関数

substr(string、start、length)

string(必須)は、返される文字列の一部を指定します。

start(必須)は、文字列のどこから開始するかを指定します。

length(オプション)は、返される文字列の長さを指定します。


3.left()関数

左(文字列、長さ)

どのように説明しても、ただ遊んでみたほうがいいです

string(必須)は、文字列の一部が返されることを指定します

length(オプション)は、返される文字列の最初の長さの長さの文字を指定します

ブールベースのブラインドを作成する方法について話しましょう。

ブールSQLに基づくブラインドインジェクションは、SQLインジェクション中に、アプリケーションがTrue(ページ)とFalse(ページ)のみを返すことを意味します。
現時点では、アプリケーションのリターンページに基づいて必要なデータベース情報を取得することはできません。しかし、論理的な判断(サイズの比較)を構築することで、必要な情報を得ることができます。


この時点で通常に戻り、404ページは返されません。これは、ライブラリの長さが8バイトであることを示しています。

これは、left()を使用して、ライブラリ名の名を決定します。これは、ページが通常に戻った場合、最初の文字がt未満であることを意味します。

これは、ページが通常に戻り、最初の文字がrより大きくなければならないことを示し、最初の文字がsである場合です。この方法を使用して、順番に判断します。


それでは、ライブラリの2番目の場所が何であるかを判断しましょう(ここではASCII判断が使用されます)

最後に、現在のライブラリ名が「セキュリティ」であることがわかりました

テーブルの名前を推測してみましょう。最初のライブラリの最初のテーブルの最初の文字のASCIIは113より大きいです。

ascii <115、これらの2ページは通常の命令に戻り、テーブルの最初の文字は「r」です。

検索後、テーブルにはリファラーという名前が付けられます。

3番目のフィールドの最初の文字を推測します

したがって、現在のデータテーブルの3番目のフィールドの最初の文字は「i」です。類推すると、現在のデータテーブルの4番目のフィールドは「id」です。

3番目のフィールドの最初のデータ項目の最初の文字を推測します。

したがって、現在のフィールドの最初のデータ項目の最初の文字は「D」です。

2番目のものを推測します


したがって、現在のフィールドの最初のデータ項目の最初の文字は「u」です。

類推すると、現在のフィールドの最初のデータ項目は「ダム」です。

同様に、「password」フィールドの最初のデータ項目は「Dumb」と推定できます。


ブールブラインドに基づいて、次の時間ベースの注入

SQLコードを挿入した後、2つの状況があります。

  • 挿入されたSQLコードがバックグラウンド[データベース]の通常の関数実行に影響を与えない場合、Webアプリケーションページは正しく表示されます(元のページ)。
  • 挿入されたSQLコードがバックエンドデータベースの通常の機能に影響を与える場合(SQLインジェクションが発生します)、この時点ではWebアプリケーションのページは引き続き正常に表示されます(理由は、Webアプリケーションが「リダイレクト」または「ブロック」を行うためです)対策)。

このとき、質問があります。挿入したSQLコードはバックエンドデータベースによって実行されていますか?つまり、SQLインジェクションはWebアプリケーションに存在しますか?

この状況に直面すると、前述のブールベースのブラインドSQLインジェクションを再生するのは困難です(ブールベースのブラインドSQLインジェクションの前提は、Webプログラムによって返されるページにtrueとfalseの2つの異なるページがあるためです)。現時点では、通常、Webアプリケーションの応答時間の違いに基づいてSQLインジェクションがあるかどうか、つまり時間に基づいてブラインドSQLインジェクションがあるかどうかを判断します。

ifステートメント/ if()関数

ブラインドタイムベースのSQLインジェクションでは、操作が正しいかどうかを判断するために条件ステートメントを使用することがよくあります。

<code class = "hljs bash has-numbering"> <span class = "hljs-keyword"> if </ span>条件<spanclass = "hljs-keyword">その後</ span> <span class = "hljs-キーワード ">実行</ span> _something <spanclass =" hljs-keyword ">その他</ span> <spanclass =" hljs-keyword ">実行</ span> _something_ <spanclass =" hljs-keyword ">それ以外の場合</ span> 11 </ code>
つまり、特定の条件が発生した場合はステートメント1を実行し、それ以外の場合はステートメント2を実行します。

MySQLの以下のように、IF()関数の構文は次のとおりです。

<code class = "hljs ruleslanguage has-numbering"> <span class = "hljs-keyword"> IF </ span>(expr1、expr2、expr3)</ code>

expr1がtrueの場合、IF()関数はexpr2ステートメントを実行します。それ以外の場合、IF()関数はexpr3ステートメントを実行します。

sleep()関数

mysqlでは、sleep()関数の構文は次のとおりです。

<code class = "hljs erlang has-numbering"> <span class = "hljs-function"> <spanclass = "hljs-title">スリープ</ span> <spanclass = "hljs-params">(秒) </ span> </ span> </ code>

つまり、sleep()関数コードの実行が数秒間遅れます。

BENCHMARK()関数

mysqlでは、BENCHMARK()関数の構文は次のとおりです。

<code class = "hljs axapta has-numbering"> BENCHMARK(<span class = "hljs-keyword"> count </ span>、expr)
</ code>
つまり、BENCHMARK()関数は、式exprcount回を繰り返し実行します。

通常の状況では、BENCHMARK()関数は多くのCPUリソースを消費するため、使用することはお勧めしません。


次に、時間ベースのブラインドSQLインジェクションについて学習します。

ここではIF(クエリステートメント、1、sleep(5))を使用します。つまり、クエリステートメントがtrueの場合、結果を直接返します。クエリステートメントがfalseの場合、5秒後にページに戻ります。したがって、ページに戻るまでの時間の長さに基づいてクエリステートメントが正しく実行されたかどうかを判断します。つまり、開始点は前のブールベースのブラインドSQLインジェクションに戻ります。つまり、クエリステートメントを作成して次のことを判断します。結果は本当です。

ステップ1は、現在のデータベース名を列挙します


database()は、現在のデータベースを表示し、現在のデータベースのASCIIコードを比較することによって現在のデータベースの特定の文字を列挙できます(二分法を使用して1つずつ列挙することをお勧めします)。

最後に、現在のデータベースを「セキュリティ」として取得します。

ステップ2は、現在のデータベースのテーブル名を列挙します

ここでは、図に示すように、現在のデータベースの最初のテーブルの最初の文字を列挙する方法のみを示します。

テーブルの最初の文字を102と比較すると、ブラウザは5秒後にそれを表示します(以下の内容は無視してください)。つまり、テーブルの最初の文字は102より大きく、これは誤りです。次に、テーブルの最初の文字を100と比較すると、ブラウザに直接表示されます。つまり、テーブルの最初の文字が100より大きくなります。このようにして、テーブルのすべての文字を取得できます。

最後に、現在のデータベースで「emails」という名前の最初のテーブルを取得します。

ステップ3は、現在のデータテーブルのフィールド名を列挙します

ここでは、列挙された現在のデータテーブルの最初のフィールド名を完全に表示します。写真が示すように:

多くの人は、取得した各文字が完全なフィールド名であるとどのように判断するのか疑問に思うでしょう。フィールドの長さがわからないからです。

これは非常に単純です。つまり、フィールド名を列挙するときに、1と直接比較する場合(つまり、現在の文字のASCIIコードが1より大きい場合)、これがエラーを示す場合、一般に、完全なフィールド名は現在です。写真が示すように:

ステップ4:各フィールドに対応するデータ項目の内容を列挙します

このステップで、次のような問題が発生しました。


ステップバイステップで判断すると、最終結果は「admin」です。

最後に、XiongJunkunのブログに感謝します。

おすすめ

転載: blog.csdn.net/weixin_45682070/article/details/107819901