ホームページ  >  記事  >  データベース  >  SQL インジェクションの 3 つの方法は何ですか?

SQL インジェクションの 3 つの方法は何ですか?

醉折花枝作酒筹
醉折花枝作酒筹オリジナル
2021-07-27 10:41:4933718ブラウズ

SQL インジェクションには 3 つの方法があります: 1. 数値インジェクション: 入力パラメータが整数の場合、数値インジェクションの脆弱性が存在する可能性があります; 2. 文字インジェクション: 入力パラメータが文字列の場合、脆弱性が存在する可能性があります。文字インジェクションの脆弱性である可能性; 3. 検索インジェクション、データ検索の実行時に検索パラメータがフィルタリングされない。

SQL インジェクションの 3 つの方法は何ですか?

このチュートリアルの動作環境: Windows 7 システム、mysql バージョン 8.0、Dell G3 コンピューター。

SQL インジェクションの原理

SQL インジェクション攻撃とは、特殊な入力をパラメータとして構築し、Web アプリケーションに渡すことを指しますが、これらの入力のほとんどは SQL 構文の組み合わせです。攻撃者が要求する操作が実行される主な理由は、プログラムがユーザーが入力したデータを慎重にフィルタリングしていないため、不正なデータがシステムに侵入する可能性があります。

SQL インジェクションの分類

1. 数値インジェクション

入力パラメータが整数の場合、数値インジェクションの脆弱性が存在する可能性があります。

URL があると仮定します: HTTP://www.aaa.com/test.php?id=1

バックグラウンド SQL ステートメントは次のように推測できます:

SELECT * FROM table WHERE id=1

数値脆弱性を特定するための SQL インジェクション ポイント:

① まず、入力ボックスに一重引用符 '

などの SQL ステートメントを入力します。

SELECT * FROM table WHERE id=1',

は構文に準拠していないため、ステートメントは確実にエラーとなり、スクリプト プログラムは実行できなくなります。データベースからデータを取得し、オリジナルのページを作成します。ページには例外があります。

② 入力ボックスに「1 = 1」と入力します。

SQL ステートメントは次のようになります:

SELECT * FROM table WHERE id=1 and 1 = 1

ステートメントは正しく、実行は正常で、返されるデータは元のリクエストと変わりません。

③ データベースに「and 1 = 2」と入力します。

SQL ステートメントは次のようになります:

SELECT * FROM table WHERE id=1 and 1 = 2

構文は正しく、ステートメントは正常に実行されますが、1 = 2 が永続的に false であるためロジックが間違っており、返されるデータは元のリクエストとは異なります。

上記の 3 つの手順がすべて満たされている場合、プログラムには数値 SQL インジェクションの脆弱性がある可能性があります。

2. 文字インジェクション

入力パラメータが文字列の場合、文字インジェクションの脆弱性が存在する可能性があります。数値注入と文字注入の最大の違いは、数値型は一重引用符で閉じる必要がないのに対し、文字型は通常一重引用符で閉じる必要があることです。

文字インジェクションで最も重要なことは、SQL ステートメントを閉じて冗長コードをコメントアウトする方法です。

バックグラウンド SQL ステートメントが次のとおりであると仮定します。

SELECT * FROM table WHERE username = 'admin'

文字型の脆弱性を判断するための SQL インジェクション ポイント:

① SQL ステートメント

をテストするには、最初に一重引用符 admin' を入力することをお勧めします。

SELECT * FROM table WHERE username = 'admin' となります。 '。

ページ例外。

② 入力: admin' および 1 = 1 --

注: admin の後には単一引用符があります。これは文字列を閉じるために使用され、最後にコメント文字があります。 --(バーの後にスペースが 2 つあります!!!)。
SQL ステートメントは次のようになります:

SELECT * FROM table WHERE username = 'admin' and 1 = 1 --

ページは正しく表示されます。

③ 入力: admin' および 1 = 2 --

SQL ステートメントは次のようになります:

SELECT * FROM table WHERE username = 'admin' and 1 = 2 - -

ページエラー。

上記の 3 つの手順が満たされている場合、文字 SQL インジェクションが存在する可能性があります。

3. 検索インジェクション

これは特殊なタイプのインジェクションです。このタイプのインジェクションは主に、データ検索を実行するときに検索パラメータをフィルタリングしないことを指します。一般的に、リンク アドレスには「keyword=keyword」が含まれます。リンク アドレスには表示されず、検索ボックス フォームから直接送信されるものもあります。このタイプのインジェクション ポイントによって送信される SQL ステートメントのプロトタイプは、大まかに次のとおりです。 select * from table name where field like '%keyword%' インジェクションがある場合は、ブラスト用に次のような SQL インジェクション ステートメントを構築できます。 select * '%test%' や '%1%' のようなフィールドのテーブル名 = '%1%'

次に、一般的なインジェクション名をいくつか示します:

  • POST注入 : POST データにフィールドを注入

  • Cookie インジェクション: Cookie データにフィールドを注入

  • 遅延注入: データベースを使用して注入遅延機能

  • 検索インジェクション: 挿入場所は検索場所です

  • base64 インジェクション: 挿入された文字列は Base64 で暗号化する必要があります

一般的なデータベース インジェクション

データベース インジェクションでは、攻撃者は単にデータベースを使用して、より多くのデータやより大きな権限を取得します。利用方法は次のカテゴリに要約できます:

  • データのクエリ

  • ファイルの読み取りと書き込み

  • コマンドの実行

攻撃者は、データベースに関係なく、プログラムの挿入のためにこれら 3 つのことを実行しますが、異なるデータベースに挿入される SQL ステートメントは異なります。

ここでは、Oracle 11g、MySQL 5.1、SQL Server 2008 の 3 つのデータベースのインジェクションを示します。

SQL Server

1. エラー メッセージを使用して情報を抽出する

SQL Server データベースは非常に優れたデータベースであり、エラー情報を正確に特定できるため、攻撃者にとっては大きな利点となります。攻撃者はエラー メッセージを通じて必要なデータを抽出できるため、これは非常に良いことです。

① 現在のテーブルまたは列を列挙します。

このようなテーブルが存在すると仮定します。

SQL インジェクションの 3 つの方法は何ですか?

root ユーザーの詳細情報をクエリします。 SQL ステートメントの推測は次のとおりです:

SELECT * FROM user WHERE username = 'root' AND passwd = 'root'

攻撃者は SQL Server の機能を使用して機密情報を取得できます。入力ボックスに次のように入力します。 ステートメント:

' 1 = 1 --

最終的に実行される SQL ステートメントは次のようになります:

SELECT * FROM user WHERE username = 'root' AND パスワード = 'root' HAVING 1 = 1 --

SQL エグゼキュータはエラーをスローする可能性があります:

SQL インジェクションの 3 つの方法は何ですか?

攻撃者は現在のテーブルを検出できます。ユーザーであり、フィールド ID が存在します。

攻撃者は、次のステートメントを入力することで、この機能を使用して他の列名を取得し続けることができます:

' GROUP BY users.id HAVING 1 = 1 --

Then SQL ステートメントは For:

SELECT * FROM user WHERE username = 'root' AND passwd = 'root' GROUP BY users.id HAVING 1 = 1 --

エラーがスローされます:

SQL インジェクションの 3 つの方法は何ですか?

列名 username が含まれていることがわかります。エラー メッセージが返されなくなるまで再帰的にクエリを実行できるため、HAVING 句を使用して現在のテーブルのすべての列名を取得できます。

注: この列に集計関数が使用されていない限り、Select で指定された各列は、Group By 句に表示される必要があります。

②. データ型エラーを使用してデータを抽出します

文字列を文字列以外と比較しようとしたり、文字列を互換性のない別の型に変換しようとしたりすると、SQL エディターは例外をスローします。

次の SQL ステートメント:

SELECT * FROM user WHERE ユーザー名 = 'abc' AND パスワード = 'abc' AND 1 > (SELECT TOP 1 ユーザー名 FROM ユーザー)

Executor エラー メッセージ:

SQL インジェクションの 3 つの方法は何ですか?

#ユーザー名 root を取得できます。サブクエリ SELECT TOP 1 username FROM users では、最初にクエリされたユーザー名が返されるため、戻り値の型は varchar 型で、次に int 型の 1 と比較されます。2 つの異なる型のデータは比較できず、エラーが報告されます。データ侵害が発生しました。

このメソッドを使用してすべてのアカウント情報を再帰的に推定します:

SELECT * FROM users WHERE username = 'abc' AND Password = 'abc' AND 1 > (SELECT TOP 1 username FROM users WHERE) ('root')) にはありません。

このステートメントを作成すると、次のユーザー名を取得できます。サブクエリ内のユーザー名を他のカラム名に置き換えると、ここでは説明しませんが、他のカラムの情報も取得できます。

2. メタデータの取得

SQL Server には、メタデータの取得を容易にするための多数のビューが用意されています。まずテーブル内の列の数を推測し、次に UNION を使用して SQL ステートメントを構築し、データを取得します。

例:

SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

現在のテーブルが 2 の場合、UNION ステートメントを使用して現在のデータベース テーブルを取得できます。現在のテーブルの列数を推測する方法については後述します。

一般的に使用されるシステム データベース ビュー:

#SYSOBJECTSデータベース内に作成されたすべてのオブジェクト (制約、ログ、ストアド プロシージャを含む)
3. ORDER BY 句は列数を推測します

ORDER BY ステートメントを使用して、現在のテーブルの列数を確認できます。

例:

① SELECT * FROM users WHERE id = 1——SQL の実行は通常です

②SELECT * FROM users WHERE id = 1 ORDER BY 1 (によると)最初の列 ソート) - SQL 実行は通常です

③ SELECT * FROM users WHERE id = 1 ORDER BY 2 (2 番目の列に従ってソート) - SQL 実行は通常です

④ SELECT * FROM users WHERE id = 1 ORDER BY 3 (3 列目でソート) - SQL は通常通り実行されます

⑤ SELECT * FROM users WHERE id = 1 ORDER BY 4 (4 列目でソート) - SQL は例外をスローします:

SQL インジェクションの 3 つの方法は何ですか?

#4 番目の列に従って並べ替えるとエラーが報告されるため、現在のテーブルの列の数は 3 つだけであると結論付けることができます。この方法は、Oracle データベースや MySql データベースでも機能します。

攻撃者は列数を知った後、通常 UNION キーワードと連携して次の攻撃を実行します。

4. UNION クエリ
UNION キーワードは、2 つ以上のクエリ結果を 1 つの結果セットに結合します。ほとんどのデータベースは UNION クエリをサポートしています。ただし、UNION を使用して 2 つの結果をマージするには、次の基本ルールがあります。

  • すべてのクエリの列の数は同じである必要があります

  • データ型には互換性がある必要があります

① UNION クエリを使用して列数を推測する

ORDER BY メソッドを使用して列数を推測するだけでなく、 UNION メソッドも使用できます。

前に仮定したユーザー テーブルには 5 つの列があります。UNION を使用してクエリを実行すると:

SELECT * FROM users WHERE id = 1 UNION SELECT 1

データベースは次のようになります。問題例外:

SQL インジェクションの 3 つの方法は何ですか?

エラーが発生しなくなるまで再帰的にクエリを実行すると、User テーブル内のクエリ フィールドの数を知ることができます:

UNION SELECT 1 ,2, UNION SELECT 1,2,3

SELECT の後の数値を null に変更して、互換性のない例外が発生する可能性を低くすることもできます。

② 機密情報のユニオン クエリ

列の数が 4 であることがわかったら、次のステートメントを使用して挿入を続行できます:

UNION SELECT 'x', null、null、null FROM SYSOBJECT WHERE xtype='U' (注: xtype='U' はオブジェクト タイプがテーブルであることを意味します)

最初の列のデータ型が一致しない場合、データベースはエラーを報告した後は、ステートメントに互換性が得られるまで再帰的にクエリを実行できます。ステートメントが正常に実行されると、x を SQL ステートメントに置き換えて機密情報をクエリできます。

5. SQL Server が提供するシステム関数を使用する
SQL Server には多くのシステム関数が用意されており、これらのシステム関数を使用すると、SQL を使用せずに SQL Server システム テーブル内の情報にアクセスできます。クエリ。ステートメント。

例:

  • SELECT suser_name(): ユーザーのログイン識別名を返します

  • SELECT user_name(): ベース識別番号はデータベース ユーザー名を返します

  • SELECT db_name(): データベース名を返します

  • SELECT is_member('db_owner' ): データベースかどうか ロール

  • SELECT Convert(int, '5'): データ型変換

6. ストアド プロシージャ
ストアド プロシージャ (ストアド プロシージャ) は、システム コマンドの実行、レジストリの表示、ディスク ディレクトリの読み取りなど、大規模なデータベース システムで特定の機能を実行するために使用される一連の SQL "関数" です。

攻撃者が最もよく使用するストアド プロシージャは「xp_cmdshell」です。このストアド プロシージャを使用すると、ユーザーはオペレーティング システム コマンドを実行できます。

例: http://www.aaa.org/test.aspx?id=1 にインジェクション ポイントがある場合、攻撃者はコマンド攻撃を実行できます:

http:// www.aaa.org/test.aspx?id=1; exec xp_cmdshell 'net user test test /add'

最後に実行された SQL ステートメントは次のとおりです:

SELECT * FROM table WHERE id=1; exec xp_cmdshell 'net user test test /add'

セミコロンの後のステートメントは、相手のサーバー上に攻撃者のユーザー名テストとパスワードテストを使用して新しいユーザーを作成できます。

注: このタイプのストアド プロシージャはデータベース ユーザーが使用できるわけではありません。ユーザーは CONTROL SERVER 権限を保持している必要があります。

一般的な危険なストアド プロシージャは次のとおりです。

データベース ビュー 説明
##SYS.DATABASES SQL Server のすべてのデータベース
SYS.SQL_LOGINS SQL Server のすべてのログイン
INFORMATION_SCHEMA.TABLES 現在のユーザー データベース内のすべてのデータ テーブル
INFORMATION_SCHEMA.COLUMNS 現在のユーザーのすべての列データベース
SYS.ALL_COLUMNS ユーザー定義オブジェクトとシステム オブジェクトのすべての列の結合
SYS .DATABASE_PRINCIPALS データベース内の各権限または列の例外権限
SYS.DATABASE_FILES データベースに保存されているデータベース ファイル
ストアド プロシージャ説明sp_addloginユーザーが SQL Server ID を使用して SQL Server インスタンスに接続できるようにする新しい SQL Server ログインを作成しますsp_dropuser現在のデータベースからデータベース ユーザーを削除します##xp_enumgroupsxp_regreadxp_regwritexp_redeletevaluexp_dirtreesp_passwordxp_servicecontrol

さらに、特殊な関数やストアド プロシージャを使用する場合、データベースには特定のアクセス許可が必要です。一般的な SQL Server データベースのロールと権限は次のとおりです:

Microsoft Windows ローカル グループ リストを提供するか、指定された Windows ドメインでグローバル グループ リストを定義します
レジストリの読み取り
レジストリの書き込み
レジストリの削除
ディレクトリの読み取り
パスワードの変更
サービスの停止またはアクティブ化
#diskadminディスク ファイルを管理できますprocessadminデータベース エンジンで実行されているインスタンスをプラントできますsecurityadminログイン名とその属性を管理できます。サーバー レベルの権限の GRANT、DENY、および REVOKE を利用できます。また、データベース レベルの権限の GRANT、DENY、および REVOKE も利用できます。 ; さらに、SQL Server ログインのパスワードを再設定することもできますserveradminサーバー全体の構成オプションを変更したり、サーバーをシャットダウンしたりすることもできますsetupadminリンク サーバーを追加および削除でき、特定のシステム ストアド プロシージャを実行できますsysadminデータベース エンジンであらゆるアクティビティを実行可能
Role Permission
bulkadmin BULK INSERT ステートメントを実行できます
dbcreator 任意のデータベースを作成、変更、削除、復元できます
7. 動的実行
SQL Server はステートメントの動的実行をサポートしており、ユーザーは文字列を送信して SQL を実行できます。発言。

例: exec('SELECT ユーザー名、パスワード FROM ユーザー')

16 進数の SQL ステートメントを定義し、exec 関数を使用してそれを実行することもできます。ほとんどの Web アプリケーションとファイアウォールは一重引用符をフィルターします。exec を使用して 16 進 SQL ステートメントを実行すると、多くのファイアウォールやアンチインジェクション プログラム (例:

declare @query varchar(888)
select @query=0x73656C6563742031
exec(@query)

または:

declare/ **&) を突破できます。 #&*/varchar(888)/**/@クエリ/**/@query=0x73656C6563742031/**/exec(@query)

関連する推奨事項: "

mysql チュートリアル

以上がSQL インジェクションの 3 つの方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。