SQL インジェクションには 3 つの方法があります: 1. 数値インジェクション: 入力パラメータが整数の場合、数値インジェクションの脆弱性が存在する可能性があります; 2. 文字インジェクション: 入力パラメータが文字列の場合、脆弱性が存在する可能性があります。文字インジェクションの脆弱性である可能性; 3. 検索インジェクション、データ検索の実行時に検索パラメータがフィルタリングされない。
このチュートリアルの動作環境: Windows 7 システム、mysql バージョン 8.0、Dell G3 コンピューター。
SQL インジェクション攻撃とは、特殊な入力をパラメータとして構築し、Web アプリケーションに渡すことを指しますが、これらの入力のほとんどは 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 データベースは非常に優れたデータベースであり、エラー情報を正確に特定できるため、攻撃者にとっては大きな利点となります。攻撃者はエラー メッセージを通じて必要なデータを抽出できるため、これは非常に良いことです。
① 現在のテーブルまたは列を列挙します。
このようなテーブルが存在すると仮定します。
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 エグゼキュータはエラーをスローする可能性があります:
攻撃者は現在のテーブルを検出できます。ユーザーであり、フィールド 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 --
エラーがスローされます:
列名 username が含まれていることがわかります。エラー メッセージが返されなくなるまで再帰的にクエリを実行できるため、HAVING 句を使用して現在のテーブルのすべての列名を取得できます。
注: この列に集計関数が使用されていない限り、Select で指定された各列は、Group By 句に表示される必要があります。
②. データ型エラーを使用してデータを抽出します
文字列を文字列以外と比較しようとしたり、文字列を互換性のない別の型に変換しようとしたりすると、SQL エディターは例外をスローします。
次の SQL ステートメント:
SELECT * FROM user WHERE ユーザー名 = 'abc' AND パスワード = 'abc' AND 1 > (SELECT TOP 1 ユーザー名 FROM ユーザー)
Executor エラー メッセージ:
#ユーザー名 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')) にはありません。
このステートメントを作成すると、次のユーザー名を取得できます。サブクエリ内のユーザー名を他のカラム名に置き換えると、ここでは説明しませんが、他のカラムの情報も取得できます。
SQL Server には、メタデータの取得を容易にするための多数のビューが用意されています。まずテーブル内の列の数を推測し、次に UNION を使用して SQL ステートメントを構築し、データを取得します。
例:
SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
現在のテーブルが 2 の場合、UNION ステートメントを使用して現在のデータベース テーブルを取得できます。現在のテーブルの列数を推測する方法については後述します。
一般的に使用されるシステム データベース ビュー:
データベース ビュー | 説明 |
---|---|
##SYS.DATABASES | SQL Server のすべてのデータベース |
SYS.SQL_LOGINS | SQL Server のすべてのログイン |
INFORMATION_SCHEMA.TABLES | 現在のユーザー データベース内のすべてのデータ テーブル |
INFORMATION_SCHEMA.COLUMNS | 現在のユーザーのすべての列データベース |
SYS.ALL_COLUMNS | ユーザー定義オブジェクトとシステム オブジェクトのすべての列の結合 |
SYS .DATABASE_PRINCIPALS | データベース内の各権限または列の例外権限 |
SYS.DATABASE_FILES | データベースに保存されているデータベース ファイル |
データベース内に作成されたすべてのオブジェクト (制約、ログ、ストアド プロシージャを含む) |
説明 | |
---|---|
ユーザーが SQL Server ID を使用して SQL Server インスタンスに接続できるようにする新しい SQL Server ログインを作成します | |
現在のデータベースからデータベース ユーザーを削除します | |
Microsoft Windows ローカル グループ リストを提供するか、指定された Windows ドメインでグローバル グループ リストを定義します | |
レジストリの読み取り | |
レジストリの書き込み | |
レジストリの削除 | |
ディレクトリの読み取り | |
パスワードの変更 | |
サービスの停止またはアクティブ化 |
Role | Permission |
---|---|
bulkadmin | BULK INSERT ステートメントを実行できます |
dbcreator | 任意のデータベースを作成、変更、削除、復元できます |
ディスク ファイルを管理できます | |
データベース エンジンで実行されているインスタンスをプラントできます | |
ログイン名とその属性を管理できます。サーバー レベルの権限の GRANT、DENY、および REVOKE を利用できます。また、データベース レベルの権限の GRANT、DENY、および REVOKE も利用できます。 ; さらに、SQL Server ログインのパスワードを再設定することもできます | |
サーバー全体の構成オプションを変更したり、サーバーをシャットダウンしたりすることもできます | |
リンク サーバーを追加および削除でき、特定のシステム ストアド プロシージャを実行できます | |
データベース エンジンであらゆるアクティビティを実行可能 |
declare @query varchar(888) select @query=0x73656C6563742031 exec(@query)または: declare/ **&) を突破できます。 #&*/varchar(888)/**/@クエリ/**/@query=0x73656C6563742031/**/exec(@query)関連する推奨事項: "
mysql チュートリアル 》
以上がSQL インジェクションの 3 つの方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。