NoSQL Injection
字数 2573 2025-10-01 14:05:44

NoSQL 注入漏洞详解

基本介绍

NoSQL Injection 是一种针对 NoSQL 数据库的安全漏洞,类似于传统的 SQL 注入攻击。NoSQL 数据库是一类非关系型数据库,例如 MongoDB、Cassandra、Redis 等,它们使用不同的数据存储和查询机制。NoSQL Injection 漏洞的本质是未正确验证和过滤用户输入,导致攻击者能够执行未经授权的操作,从而破坏数据库的完整性、泄露敏感数据或执行其他恶意行为。

漏洞类型

NoSQL 注入主要分为以下两种类型:

1. 语法注入

当攻击者能够破坏 NoSQL 查询语法并注入攻击载荷时,就会发生语法注入。该方法与 SQL 注入中使用的方法类似,但由于 NoSQL 数据库使用一系列查询语言、查询语法类型和不同的数据结构,因此攻击的性质差异很大。

2. 运算符注入

当攻击者能够使用 NoSQL 查询运算符来操纵查询时,就会发生运算符注入。

语法注入详解

注入检测

考虑一个在 MongoDB 中显示不同类别产品的购物应用程序。当用户选择 "Fizzy drinks" 类别时,浏览器会请求以下 URL:

https://insecure-website.com/product/lookup?category=fizzy

此时应用程序会发送 JSON 查询并从 MongoDB 数据库中的产品集合中检索相关产品:

this.category == 'fizzy'

要测试输入是否易受 NoSQL 注入攻击,可以在类别参数的值中提交一个模糊字符串。MongoDB 的一个示例模糊字符串是:

'"`{;$Foo}$Foo \xYZ

使用此模糊字符串构建攻击向量:

https://insecure-website.com/product/lookup?category='%22%60%7b%0d%0a%3b%24Foo%7d%0d%0a%24Foo%20%5cxYZ%00

如果这导致原始响应发生变化,则可能表示用户输入没有正确过滤或净化。

过滤字符

确定应用程序将哪些字符解释为语法。可以注入单个字符,例如提交 ',这将导致以下 MongoDB 查询:

this.category == '''

如果这导致原始响应发生更改,则可能表示 ' 字符破坏了查询语法并导致语法错误。可以通过在输入中提交有效的查询字符串来确认这一点,例如通过转义引号:

this.category == '\''

如果这不会导致语法错误,则意味着应用程序容易受到注入攻击。

确定条件

检测到漏洞后,下一步是确定是否可以使用 NoSQL 语法影响布尔条件。发送两个请求进行测试:

  1. 假条件:'&&0&&'x

    https://insecure-website.com/product/lookup?category=fizzy'+%26%26+0+%26%26+'x
    
  2. 真条件:'&&1&&'x

    https://insecure-website.com/product/lookup?category=fizzy'+%26%26+1+%26%26+'x
    

如果应用程序的行为不同,则表明假条件会影响查询逻辑,但真条件不会,同时也表明注入这种语法风格会影响服务器端查询。

条件覆盖

确定可以影响布尔条件后,可以尝试覆盖现有条件以利用漏洞。例如,可以注入一个始终计算为 true 的 JavaScript 条件,如 "||1||"

https://insecure-website.com/product/lookup?category=fizzy%27%7c%7c%31%7c%7c%27

这将导致以下 MongoDB 查询:

this.category == 'fizzy'||'1'=='1'

由于注入的条件始终为 true,修改后的查询将返回所有项,使攻击者能够查看任何类别中的所有产品,包括隐藏或未知类别。

简易示例

  1. 访问靶场并选择过滤器对类别进行过滤
  2. 对类别参数进行注入测试,提交以下语句会引发报错:
    /filter?category=a'
    
  3. 尝试对引号进行闭合操作:
    Gifts'+'
    
  4. 确定是否可以注入布尔条件来更改响应:
    • 插入一个 false 条件:
      Gifts' && 0 && 'x
      
    • 插入一个 true 条件:
      Gifts' && 1 && 'x
      
  5. 提交一个布尔条件,该条件在类别参数中的计算结果始终为 true:
    Gifts'||1||'
    

运算符注入详解

基本介绍

NoSQL 数据库通常使用查询运算符来指定数据必须满足的条件。MongoDB 查询运算符的示例包括:

  • $where:匹配满足 JavaScript 表达式的内容
  • $ne:匹配所有不等于指定值的值
  • $in:匹配数组中指定的所有值
  • $regex:选择值与指定正则表达式匹配的内容

攻击者可以注入查询运算符来操作 NoSQL 查询。

提交查询

在 JSON 消息中,可以将查询运算符作为嵌套对象插入:

  • 初始情况:{"username":"wiener"}
  • 嵌套之后:{"username":{"$ne":"invalid"}}

对于基于 URL 的输入,可以通过 URL 参数插入查询运算符:

  • 初始情况:username=wiener
  • 嵌套之后:username[$ne]=invalid

如果不起作用,可以尝试以下操作:

  1. 将请求方法从 GET 转换为 POST
  2. 将内容类型标题更改为 application/json
  3. 将 JSON 添加到消息体
  4. JSON 注入查询运算符

注入检测

考虑一个易受攻击的应用程序,在 POST 请求的正文中接受用户名和密码:

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

用一系列运算符测试每个输入。要测试用户名输入是否处理查询运算符,可以尝试以下注入:

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

如果应用了 $ne 运算符,则会查询用户名不等于 "invalid" 的所有用户。如果用户名和密码输入都处理操作符,则可以使用以下有效载荷绕过身份验证:

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

此查询返回用户名和密码不等于 "invalid" 的所有登录凭据,因此攻击者会作为集合中的第一个用户登录到应用程序。要以特定帐户为目标,可以构造一个包含已知用户名或猜测用户名的有效载荷:

{"username":{"$in":["admin","administrator","superadmin"]},"password":{"$ne":""}}

演示示例

  1. 使用提供的凭据登录用户:wiener:peter
  2. 在 Burp Suite 中测试用户名和密码参数,确定它们是否允许注入 MongoDB 操作符:
    • username 参数的值从 "wiener" 更改为 {"$ne":""},然后发送请求
    • username 参数的值从 {"$ne":""} 更改为 {"$regex":"wien.*"},然后发送请求
    • password 参数的值从 "peter" 更改为 {"$ne":""},然后再次发送请求
  3. 在密码参数设置为 {"$ne":""} 的情况下,将用户名参数的值更改为 {"$regex":"admin.*"},然后再次发送请求,成功以管理员用户身份登录

防御措施

  1. 输入验证:对所有用户输入进行严格的验证和过滤
  2. 参数化查询:使用参数化查询或预编译语句
  3. 最小权限原则:数据库用户应具有最小必要的权限
  4. 错误处理:避免向用户显示详细的错误信息
  5. 安全配置:遵循数据库的安全最佳实践和配置指南
  6. 定期更新:保持数据库系统和应用程序框架的最新版本

总结

NoSQL 注入是一种严重的安全威胁,可以导致数据泄露、未授权访问和系统破坏。通过理解 NoSQL 注入的原理、检测方法和利用技术,开发人员和安全专业人员可以更好地保护应用程序免受此类攻击。实施适当的安全措施和遵循安全开发实践是预防 NoSQL 注入的关键。

NoSQL 注入漏洞详解 基本介绍 NoSQL Injection 是一种针对 NoSQL 数据库的安全漏洞,类似于传统的 SQL 注入攻击。NoSQL 数据库是一类非关系型数据库,例如 MongoDB、Cassandra、Redis 等,它们使用不同的数据存储和查询机制。NoSQL Injection 漏洞的本质是未正确验证和过滤用户输入,导致攻击者能够执行未经授权的操作,从而破坏数据库的完整性、泄露敏感数据或执行其他恶意行为。 漏洞类型 NoSQL 注入主要分为以下两种类型: 1. 语法注入 当攻击者能够破坏 NoSQL 查询语法并注入攻击载荷时,就会发生语法注入。该方法与 SQL 注入中使用的方法类似,但由于 NoSQL 数据库使用一系列查询语言、查询语法类型和不同的数据结构,因此攻击的性质差异很大。 2. 运算符注入 当攻击者能够使用 NoSQL 查询运算符来操纵查询时,就会发生运算符注入。 语法注入详解 注入检测 考虑一个在 MongoDB 中显示不同类别产品的购物应用程序。当用户选择 "Fizzy drinks" 类别时,浏览器会请求以下 URL: 此时应用程序会发送 JSON 查询并从 MongoDB 数据库中的产品集合中检索相关产品: 要测试输入是否易受 NoSQL 注入攻击,可以在类别参数的值中提交一个模糊字符串。MongoDB 的一个示例模糊字符串是: 使用此模糊字符串构建攻击向量: 如果这导致原始响应发生变化,则可能表示用户输入没有正确过滤或净化。 过滤字符 确定应用程序将哪些字符解释为语法。可以注入单个字符,例如提交 ' ,这将导致以下 MongoDB 查询: 如果这导致原始响应发生更改,则可能表示 ' 字符破坏了查询语法并导致语法错误。可以通过在输入中提交有效的查询字符串来确认这一点,例如通过转义引号: 如果这不会导致语法错误,则意味着应用程序容易受到注入攻击。 确定条件 检测到漏洞后,下一步是确定是否可以使用 NoSQL 语法影响布尔条件。发送两个请求进行测试: 假条件: '&&0&&'x 真条件: '&&1&&'x 如果应用程序的行为不同,则表明假条件会影响查询逻辑,但真条件不会,同时也表明注入这种语法风格会影响服务器端查询。 条件覆盖 确定可以影响布尔条件后,可以尝试覆盖现有条件以利用漏洞。例如,可以注入一个始终计算为 true 的 JavaScript 条件,如 "||1||" : 这将导致以下 MongoDB 查询: 由于注入的条件始终为 true,修改后的查询将返回所有项,使攻击者能够查看任何类别中的所有产品,包括隐藏或未知类别。 简易示例 访问靶场并选择过滤器对类别进行过滤 对类别参数进行注入测试,提交以下语句会引发报错: 尝试对引号进行闭合操作: 确定是否可以注入布尔条件来更改响应: 插入一个 false 条件: 插入一个 true 条件: 提交一个布尔条件,该条件在类别参数中的计算结果始终为 true: 运算符注入详解 基本介绍 NoSQL 数据库通常使用查询运算符来指定数据必须满足的条件。MongoDB 查询运算符的示例包括: $where :匹配满足 JavaScript 表达式的内容 $ne :匹配所有不等于指定值的值 $in :匹配数组中指定的所有值 $regex :选择值与指定正则表达式匹配的内容 攻击者可以注入查询运算符来操作 NoSQL 查询。 提交查询 在 JSON 消息中,可以将查询运算符作为嵌套对象插入: 初始情况: {"username":"wiener"} 嵌套之后: {"username":{"$ne":"invalid"}} 对于基于 URL 的输入,可以通过 URL 参数插入查询运算符: 初始情况: username=wiener 嵌套之后: username[$ne]=invalid 如果不起作用,可以尝试以下操作: 将请求方法从 GET 转换为 POST 将内容类型标题更改为 application/json 将 JSON 添加到消息体 JSON 注入查询运算符 注入检测 考虑一个易受攻击的应用程序,在 POST 请求的正文中接受用户名和密码: 用一系列运算符测试每个输入。要测试用户名输入是否处理查询运算符,可以尝试以下注入: 如果应用了 $ne 运算符,则会查询用户名不等于 "invalid" 的所有用户。如果用户名和密码输入都处理操作符,则可以使用以下有效载荷绕过身份验证: 此查询返回用户名和密码不等于 "invalid" 的所有登录凭据,因此攻击者会作为集合中的第一个用户登录到应用程序。要以特定帐户为目标,可以构造一个包含已知用户名或猜测用户名的有效载荷: 演示示例 使用提供的凭据登录用户: wiener:peter 在 Burp Suite 中测试用户名和密码参数,确定它们是否允许注入 MongoDB 操作符: 将 username 参数的值从 "wiener" 更改为 {"$ne":""} ,然后发送请求 将 username 参数的值从 {"$ne":""} 更改为 {"$regex":"wien.*"} ,然后发送请求 将 password 参数的值从 "peter" 更改为 {"$ne":""} ,然后再次发送请求 在密码参数设置为 {"$ne":""} 的情况下,将用户名参数的值更改为 {"$regex":"admin.*"} ,然后再次发送请求,成功以管理员用户身份登录 防御措施 输入验证:对所有用户输入进行严格的验证和过滤 参数化查询:使用参数化查询或预编译语句 最小权限原则:数据库用户应具有最小必要的权限 错误处理:避免向用户显示详细的错误信息 安全配置:遵循数据库的安全最佳实践和配置指南 定期更新:保持数据库系统和应用程序框架的最新版本 总结 NoSQL 注入是一种严重的安全威胁,可以导致数据泄露、未授权访问和系统破坏。通过理解 NoSQL 注入的原理、检测方法和利用技术,开发人员和安全专业人员可以更好地保护应用程序免受此类攻击。实施适当的安全措施和遵循安全开发实践是预防 NoSQL 注入的关键。