SQLインジェクションは、パラメーターにSQLを含むURLを介してどのように機能するのでしょうか。 mytable
という名前のテーブルを持つデータベースがあるとします。メソッドからIDを取得するときPOST私はそれをこのクエリに入れます:
SELECT * FROM `mytable` WHERE id='POST[id]'
ユーザーがSQLを次のように配置した場合でも、
SELECT * FROM 'mytable'
それは次のようなものになりました:
SELECT * FROM `mytable` WHERE id='SELECT * FROM 'mytable'
だからそれはただ戻る:
SQL構文にエラーがあります。
では、この種の攻撃はどのように機能するのでしょうか。攻撃者は構文エラーを引き起こさずにクエリをどのように変更できますか?
SQLインジェクションのポイントは、変数があるクエリを変更することです。
例として、作成したクエリを使用してみましょう。変数id
に次のようなものが含まれていて、適切にサニタイズされていない場合:
' OR 1=1#
次のように変更されているため、すべての行が返されます。
SELECT * FROM `mytable` WHERE id='' OR 1=1#'
構文エラーを回避するコツは、クエリの残りの部分(文字#
は、この状況でそれを行います。
SQLインジェクションの活用は、SQLステートメントに組み込まれたときに、開発者が意図したセマンティクスを攻撃者にとって有益なものに変更しながら、有効なSQLステートメント構文をもたらすパラメーターを提供する技術です。
インジェクションが可能なDMBSとステートメントタイプによって、SQLインジェクションが成功した結果は、情報開示(任意のデータ、ローカルファイルの読み取り)、データ操作(任意のデータの挿入、削除、変更、書き込み)によって異なります。ローカルファイル)、任意のコマンド実行まで。
DBMSとステートメントは、エクスプロイト中に使用できる techniques にも影響します。接続APIが複数のステートメントの実行を許可しない場合(いわゆる「スタッククエリ」)、 よく引用されるRobert';DROP TABLE Students; --
は効果がありません。その場合も インジェクションが発生する特定のステートメントタイプの副作用に限定されます :SELECT
ステートメントの場合、データの読み取りのみが可能ですが、データを書き込んだり削除したりしないでください。
最後に、実行されたステートメントの結果について攻撃者に与えられるフィードバックにも依存します。エラーメッセージ、特に接続APIまたはプログラミング言語によって生成されるメッセージは、多くの場合、非常に技術的で冗長であり、重要な情報、たとえば、「…の近くのSQL構文にエラーがあります」などの失敗したステートメントの一部を明らかにする可能性があります。このようなメッセージは、インジェクションが発生するコンテキスト(ステートメントタイプ、句タイプ、括弧のネストレベルなど)に関する便利な情報を攻撃者に提供します。
あなたの例では、単純なid=' OR '1'='1
は次のステートメントになります。
SELECT * FROM `mytable` WHERE id='' OR '1'='1'
後者の式'1'='1'
すべての行が選択されます。これに対する拡張は、サブクエリを使用してブラインドな方法で任意のデータを読み取ることです。
SELECT * FROM `mytable` WHERE id='' OR EXISTS (SELECT * FROM users WHERE name='admin' AND password LIKE 'a%') AND '1'='1'
ここで、すべての行は、パスワードがadmin
で始まるユーザーa
が存在する場合にのみ選択されます。それ以外の場合、行は選択されません。この手法は「ブールベースのブラインド」と呼ばれます。