mongodb

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: 实时网摘mongoDB 用户安全配置; 具体见Ruiy的 mongoDb linux及windows下的安装及配置 默认配置的安全情况 在默认情况下,mongodb是 监听在0.0.0.0之上的。

实时网摘mongoDB 用户安全配置;

具体见Ruiy的 mongoDb linux及windows下的安装及配置

默认配置的安全情况

在默认情况下,mongodb是 监听在0.0.0.0之上的。而任何客户端都可以直接连接27017,且没有认证。好处是,开发人员或dba可以即时上手,不用担心被一堆配置弄的心烦意 乱。坏处是,显而易见,如果你直接在公网服务器上如此搭建MongoDB,那么所有人都可以直接访问并修改你的数据库数据了。

默认情况下,mongod也是没有管理员账户的。因此除非你在admin数据库中使用db.addUser()命令添加了管理员帐号,且使用–auth参数启动mongod,否则在数据库中任何人都可以无需认证执行所有命令。包括delete和shutdown。

此外,mongod还会默认监听28017端口,同样是绑定所有ip。这是一个mongod自带的web监控界面。从中可以获取到数据库当前连接、log、状态、运行系统等信息。如果你开启了–rest参数,甚至可以直接通过web界面查询数据,执行mongod命令。

我试着花了一个晚上扫描了国内一个B段,国外一个B段。结果是国外开了78个MongoDB,而国内有60台。其中我随意挑选了10台尝试连接,而只有一台机器加了管理员账户做了认证,其他则全都是不设防的城市。可见其问题还是比较严重的。

其实MongoDB本身有非常详细的安全配置准则,显然他也是想到了,然而他是将安全的任务推给用户去解决,这本身的策略就是偏向易用性的,对于安全性,则得靠边站了。

用户信息保存及认证过程

类似MySQL将系统用户信息保存在mysql.user表。MongoDB也将系统用户的username、pwd保存在admin.system.users集合中。其中pwd = md5(username + “:mongo:” + real_password)。这本身并没有什么问题。username和:mongo:相当于对原密码加了一个salt值,即使攻击者获取了数据库中保存的md5 hash,也没法简单的从彩虹表中查出原始密码。

我们再来看看MongoDB对客户端的认证交互是如何实现的。mongo client和server交互都是基于明文的,因此很容易被网络嗅探等方式抓取。这里我们使用数据库自带的mongosniff,可以直接dump出客户端和服务端的所有交互数据包:

[root@localhost bin]# ./mongosniff --source NET lo
sniffing 27017 

...//省略开头的数据包,直接看看认证流程。以下就是当用户输入db.auth(username, real_passwd)后发生的交互。

127.0.0.1:34142  -->> 127.0.0.1:27017 admin.  62 bytes  id:8        8
        query: { getnonce: 1.0 } ntoreturn: -1 ntoskip: 0
127.0.0.1:27017  <<--  127.0.0.1:34142   81 bytes  id:7 7 - 8
        reply n:1 cursorId: 0
        { nonce: "df97182fb47bd6d0", ok: 1.0 }
127.0.0.1:34142  -->> 127.0.0.1:27017 admin.  152 bytes  id:9       9
        query: { authenticate: 1.0, user: "admin", nonce: "df97182fb47bd6d0", key: "3d839522b547931057284b6e1cd3a567" }  ntoreturn: -1 ntoskip: 0
127.0.0.1:27017  <<--  127.0.0.1:34142   53 bytes  id:8 8 - 9
        reply n:1 cursorId: 0
        { ok: 1.0 }
  • 第一步,client向server发送一个命令getnonce,向server申请一个随机值nonce,server返回一个16位的nonce。这里每次返回的值都不相同。
  • 第二步,client将用户输入的明文密码通过算法生成一个key,即 key = md5(nonce + username + md5(username + “:mongo:” + real_passwd)),并将之连同用户名、nonce一起返回给server,server收到数据,首先比对nonce是否为上次生成的nonce,然后比对 key == md5(nonce + username + pwd)。如果相同,则验证通过

由于至始至终没有密码hash在网络上传输,而是使用了类似挑战的机制,且每一次nonce的值都不同,因此即使攻击者截取到key的值,也没用办法通过重放攻击通过认证。

然而当攻击者获取了数据库中保存的pwd hash,则认证机制就不会起到作用了。即使攻击者没有破解出pwd hash对应的密码原文。但是仍然可以通过发送md5(nonce + username + pwd)的方式直接通过server认证。这里实际上server是将用户的pwd hash当作了真正的密码去验证,并没有基于原文密码验证。在这点上和我之前分析的mysql的认证机制其实没什么本质区别。当然或许这个也不算是认证机制的弱点,但是毕竟要获取MongoDB的username和pwd的可能性会更大一些。

然而在Web的监控界面的认证中则有一些不同。当client来源不是localhost,这里的用户认证过程是基于HTTP 401的。其过程与mongo认证大同小异。但是一个主要区别是:这里的nonce并没有随机化,而是每次都是默认为”abc”

利用这个特点,如果攻击者抓取了管理员一次成功的登录,那么他就可以重放这个数据包,直接进入Web监控页面。

同样,攻击者还可以通过此接口直接暴力破解 mongo 的用户名密码。实际上27017和28017都没有对密码猜解做限制,但Web由于无需每次获取nonce,因此将会更为简便。

JavaScript的执行与保护

MongoDB 本身最大的特点之一,就是他是使用 JavaScript 语言作为命令驱动的。黑客会比较关注这一点,因为其命令的支持程度,就是获取 MongoDB 权限之后是否能进一步渗透的关键。

JavaScript 本身的标准库其实相当弱。无论是 spidermonkey 或者是 v8 引擎,其实都没有系统操作、文件操作相关的支持。对此,MongoDB做了一定的扩展。可以看到,ls/cat/cd/hostname 甚至 runProgram 都已经在 JavaScript 的上下文中有实现。看到这里是不是已经迫不及待了?mongo shell 中试一下输入ls(“./”),看看返回。

等等?结果怎么这么熟悉?哈哈,没错,其实这些 api 都是在 client 的上下文中实现的。一个小小玩笑。

那么在server端是否可以执行js呢?答案是肯定的。利用 db.eval(code) ——实际上底层执行的是 db.$cmd.findOne({$eval: code}) —— 可以在server端执行我们的js代码。

当然在server端也有js的上下文扩展。显然 mongod 考虑到了安全问题(也可能是其他原因),因此在这里并没有提供client中这么强大的功能。当然 MongoDB 还在不断更新,长期关注这个list,说不定以后就有类似 load_file/exec 之类的实现。

一劳永逸解决服务端js执行带来的问题可以使用noscripting参数。直接禁止server-side的js代码执行功能。

如需MongoDB解决方案:http://www.bigdataunion.org/detail2.php?id=24

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
NoSQL 安全 数据库连接
MongoDB 常见使用
MongoDB 常见使用
410 0
MongoDB 常见使用
|
7月前
|
NoSQL MongoDB
mongodb
mongodb
25 0
|
4月前
|
存储 NoSQL MongoDB
关于MongoDB
关于MongoDB
87 0
|
8月前
|
存储 NoSQL 定位技术
MongoDB的特点
MongoDB的特点
277 1
|
8月前
|
存储 NoSQL 关系型数据库
什么时候选择MongoDB
什么时候选择MongoDB
65 2
|
8月前
|
存储
MongoDB-片键选择技巧
使用分片的目的是为了将数据存储到不同的服务器上, 所以在选择片键的时候,应该选择取值范围更广的字段作为片键,因为如果取值范围太小, 那么划分出来的数据段就太少, 那么分配到不同服务器的概率就越小, 例如:取值如果只有 true 或 false, 那么就只能划分出两个数据段, 那么也就最多只能保存到两台服务器上。
55 0
|
9月前
|
存储 SQL NoSQL
mongoDB(二)
mongoDB
68 0
|
9月前
|
JSON NoSQL MongoDB
初学mongoDB(一)
初学mongoDB
47 0
|
9月前
|
消息中间件 分布式计算 NoSQL
MongoDB适用场景
MongoDB适用场景
|
10月前
|
存储 SQL 分布式计算
MongoDB的介绍
MongoDB的介绍
56 0