web-dev-qa-db-ja.com

Webアプリケーションの背後にあるデータベースを知る方法は?

さまざまなデータベース(mysql、sqlサーバーなど)にはさまざまな脆弱性があり、特定のsqlインジェクションに対して脆弱であることを読んだことがあります。

攻撃者がWebサイトに対してデータベース攻撃(SQLインジェクションなど)を実行しようとすると、最初にデータベースの種類を特定し、その後、検出されたデータベースを考えて攻撃を実行します。

この以前の検査は攻撃者によってどのように実行されますか?特別なクエリを使用していますか?特定のツールはありますか?この情報は見つかりませんでした。

14
user674887

次のようなクエリがあるとします。

_$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_テーブルの存在を確認するには、単にクエリを実行してエラーを確認します。

12
Polynomial

他の回答に加えて、データベースフィンガープリントに使用する1つの方法(特に、インジェクションがブラインドでデータが返されない場合)は、データベースエンジン間の構文の違いです。私がよく使用する このプレゼンテーション のスライド34に良いサンプルがあります。

したがって、良い例は文字列の連結です。 MS-SQLおよびDB2は+を使用しますが、Oracle PL/SQLおよびPostGRESは||を使用するため、それを文字列に挿入してアプリケーションの動作を監視できます。文字列が連結されたように動作する場合は、おそらく注入です。

9
Rory McCune

攻撃者がアプリケーションで使用されているデータベースを特定する最も簡単な方法の1つは、データベースクエリで何らかの方法でアプリケーションにエラーを発生させることです。

次に、アプリケーション内でエラー処理が有効になっていない場合(そうでない場合が多い)、データベースエラーが表示されます。これらは通常非常に詳細であり、そこからデータベースを特定できます。

また、Webアプリケーションが記述されている次の言語、使用されているフレームワーク、使用されているプラ​​ットフォーム、ホスティングプロバイダーなどを知っている場合は、検討する価値もあります。それらはすべて、どのデータベースが使用されているかを解明するのに役立ちます。たとえば、aspを使用している場合はMSSQLを使用している可能性が高く、PHP MySQLを使用している可能性が高いです。これは常に正しいわけではありませんが、たとえば、ブラインドSQLインジェクションは、物事を絞り込む別の方法を攻撃します。

4
Mark Davidson

これを行うにはいくつかの方法があります。ただし、攻撃を実行するためにデータベースの種類を知っている必要はないことに注意してください。それを知ることは、追加または代替の攻撃ベクトルを提供する可能性がありますが、SQLインジェクションには必要ありません。

ほとんどのデータベースは機能を提供するか、データベースのタイプとバージョンを識別するために使用できる辞書の物語を持っています。これらはベンダーによって異なりますが、一般的なSQLインジェクションポイントが見つかった場合は、有効な応答が得られるまでそれぞれを試すことができます。

SQLの多くの異なる方言の間には、構文の違いもあります。たとえば、Oracleには外部結合を表す(+)構文があります。多くの場合、postgresのテキスト型(Oracleにはない)などの使用可能なデータ型や、シーケンス/自動インクリメント列の処理方法などに微妙な違いがあります。

場合によっては、データベースドライバーまたはコネクタの詳細を取得するだけでわかります。環境、言語などによって、これは簡単な場合とそうでない場合があります。

0
Tim X