MongoDB怎样默认安全设置以及MongoDB中JavaScript该怎么执行与保护
创始人
2024-12-19 00:04:00
0次

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


MongoDB怎么样默认安全设置

在默认情况下,mongod是监听在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值,即使攻击者获取了数据库中保存的md5hash,也没法简单的从彩虹表中查出原始密码。

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

[root@localhostbin]#./mongosniff--sourceNETlo

sniffing27017

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

127.0.0.1:34142-->>127.0.0.1:27017admin.62bytesid:88

query:{getnonce:1.0}ntoreturn:-1ntoskip:0

127.0.0.1:27017<<--127.0.0.1:3414281bytesid:77-8 replyn:1cursorid:0="" 127.0.0.1:34142--="">>127.0.0.1:27017admin.152bytesid:99

query:{authenticate:1.0,user:"admin",nonce:"df97182fb47bd6d0",key:"3d839522b547931057284b6e1cd3a567"}ntoreturn:-1ntoskip:0

127.0.0.1:27017<<--127.0.0.1:3414253bytesid:88-9    replyn:1cursorId: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的值,也没用办法通过重放攻击通过认证。    然而当攻击者获取了数据库中保存的pwdhash,则认证机制就不会起到作用了。即使攻击者没有破解出pwdhash对应的密码原文。但是仍然可以通过发送md5(nonce+username+pwd)的方式直接通过server认证。这里实际上server是将用户的pwdhash当作了真正的密码去验证,并没有基于原文密码验证。在这点上和我之前分析的mysql的认证机制其实没什么本质区别。当然或许这个也不算是认证机制的弱点,但是毕竟要获取MongoDB的username和pwd的可能性会更大一些。    然而在Web的监控界面的认证中则有一些不同。当client来源不是localhost,这里的用户认证过程是基于HTTP401的。其过程与mongo认证大同小异。但是一个主要区别是:这里的nonce并没有随机化,而是每次都是默认为”abc”。    利用这个特点,如果攻击者抓取了管理员一次成功的登录,那么他就可以重放这个数据包,直接进入Web监控页面。    同样,攻击者还可以通过此接口直接暴力破解mongo的用户名密码。实际上27017和28017都没有对密码猜解做限制,但Web由于无需每次获取nonce,因此将会更为简便。    

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

JavaScript本身的标准库其实相当弱。无论是spidermonkey或者是v8引擎,其实都没有系统操作、文件操作相关的支持。对此,MongoDB做了一定的扩展。可以看到,ls/cat/cd/hostname甚至runProgram都已经在JavaScript的上下文中有实现。看到这里是不是已经迫不及待了?mongoshell中试一下输入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代码执行功能。      

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...