さまざまなデータベース(mysql、sqlサーバーなど)にはさまざまな脆弱性があり、特定のsqlインジェクションに対して脆弱であることを読んだことがあります。
攻撃者がWebサイトに対してデータベース攻撃(SQLインジェクションなど)を実行しようとすると、最初にデータベースの種類を特定し、その後、検出されたデータベースを考えて攻撃を実行します。
この以前の検査は攻撃者によってどのように実行されますか?特別なクエリを使用していますか?特定のツールはありますか?この情報は見つかりませんでした。
次のようなクエリがあるとします。
_$q="SELECT username, joindate FROM users WHERE username LIKE '%" . $search . "%' LIMIT 20";
_
ここで、パラメータを介して_$search
_を制御するとします。通常は、次のようにjoindate
フィールドにユーザーパスワードを返すようにします。
_$search="' UNION SELECT username, password FROM users; -- -";
_
そのため、クエリは次のようになります。
_SELECT username, joindate FROM users WHERE username LIKE '%' UNION SELECT username, password FROM users; -- - %' LIMIT 20
_
ダブルハイフンの後の部分はコメントなので無視され、データセットの最後の正当なレコードの後に、すべてのユーザー名とパスワードの組み合わせが新しいレコードとして追加されます。驚くばかり!
しかし、データベースをさらに調査するために、データベース名を見つけられるようにこれを調整したいと思います。 MySQLでは、DATABASE()
関数を使用できます。
_$search="' UNION SELECT DATABASE(), 1; -- -";
_
ここで_1
_を使用するのは、使用していないjoindate
フィールドを埋め込むためです。
MSSQLでもまったく同じことができますが、DB_NAME()
を使用します。
_$search="' UNION SELECT DB_NAME(), 1; -- -";
_
これらのトリックはどちらも、データベース名を含む単一の行を結果セットの最後に追加します。
次に、このトリックを拡張して、MySQLではVERSION()
を、MSSQLでは_@@VERSION
_を使用して、現在のデータベースバージョンを返すことができます。 OracleとPL/SQLの場合、_v$version
_テーブルの存在を確認するには、単にクエリを実行してエラーを確認します。
他の回答に加えて、データベースフィンガープリントに使用する1つの方法(特に、インジェクションがブラインドでデータが返されない場合)は、データベースエンジン間の構文の違いです。私がよく使用する このプレゼンテーション のスライド34に良いサンプルがあります。
したがって、良い例は文字列の連結です。 MS-SQLおよびDB2は+を使用しますが、Oracle PL/SQLおよびPostGRESは||を使用するため、それを文字列に挿入してアプリケーションの動作を監視できます。文字列が連結されたように動作する場合は、おそらく注入です。
攻撃者がアプリケーションで使用されているデータベースを特定する最も簡単な方法の1つは、データベースクエリで何らかの方法でアプリケーションにエラーを発生させることです。
次に、アプリケーション内でエラー処理が有効になっていない場合(そうでない場合が多い)、データベースエラーが表示されます。これらは通常非常に詳細であり、そこからデータベースを特定できます。
また、Webアプリケーションが記述されている次の言語、使用されているフレームワーク、使用されているプラットフォーム、ホスティングプロバイダーなどを知っている場合は、検討する価値もあります。それらはすべて、どのデータベースが使用されているかを解明するのに役立ちます。たとえば、aspを使用している場合はMSSQLを使用している可能性が高く、PHP MySQLを使用している可能性が高いです。これは常に正しいわけではありませんが、たとえば、ブラインドSQLインジェクションは、物事を絞り込む別の方法を攻撃します。
これを行うにはいくつかの方法があります。ただし、攻撃を実行するためにデータベースの種類を知っている必要はないことに注意してください。それを知ることは、追加または代替の攻撃ベクトルを提供する可能性がありますが、SQLインジェクションには必要ありません。
ほとんどのデータベースは機能を提供するか、データベースのタイプとバージョンを識別するために使用できる辞書の物語を持っています。これらはベンダーによって異なりますが、一般的なSQLインジェクションポイントが見つかった場合は、有効な応答が得られるまでそれぞれを試すことができます。
SQLの多くの異なる方言の間には、構文の違いもあります。たとえば、Oracleには外部結合を表す(+)構文があります。多くの場合、postgresのテキスト型(Oracleにはない)などの使用可能なデータ型や、シーケンス/自動インクリメント列の処理方法などに微妙な違いがあります。
場合によっては、データベースドライバーまたはコネクタの詳細を取得するだけでわかります。環境、言語などによって、これは簡単な場合とそうでない場合があります。