MongoDB注入:如何黑掉MongoDB

Python部落组织翻译,禁止转载欢迎转发


2016年4月11日

我现在的项目里面大量地使用MongoDB。从工作项目到个人项目,MongoDB就是这样一个很好的数据引擎。但是,由于它相对较新,因此如果它出了什么问题并不是很好地被人知道,而且会让你手足无措毫无准备。它也确实让我手足无措过。我也想指出的是,NoSQL的注入并不是个新的概念。你可以到处找到更多相关内容。这篇文章就是来讨论一种我所偶然发现的技术,以及这种技术会如何改变数据库里面的记录,如果你不是足够小心的话。溢出利用是很明显的,也是可以很容易避免的,但是在很多方面SQL注入也是很明显的。可是还是有很多人会掉进一个圈套里面。我自己就掉进了MongodDB的圈套里面,但是我也在这期间学到了很多,因此我很乐意分享我的经验。

在我们开始这个有趣的事情之前,我想要提一提MongoDB中的一个允许溢出利用的特征。MongoDB有一种能力去更新对象,通过使用周期来使用嵌套的键。先给你们看看下面这个例子。

在数据库中我们有一个这样的记录:
 

   {
      name:"John",
      info:{
          age:65
      }
    }


这个记录可以通过下面的查询来更新:


db.people.update({"name":"John"}, {"$set":{"info.age":66}})


非常棒!很酷,对不对!也很方便。

问题是,如果子键并不是硬编码的,那么用户如何决定哪个键要被传送呢?或者,如果有下面这样的查询,又会发生什么呢?


keyName = request.form|'keyName'|
keyData = request.form|'value'|
db.people.update({"name":"John"}, {"$set":{"info.{}".format(keyName):keyData}})


现在,我们的问题来了,那就是我们正在处理的用户的输入是没有经过过滤的。如果这里面有一些敏感信息,那个攻击者是可以改变他们的。

我拿一个“真实世界”的测试来说明这种溢出利用,只是来展示这个问题是如何产生的,在使用了错误的编码的时候。下面这段Python代码就是一个完整的应用例子:


这个站点相当简单。它有一个登陆页面,一个注册页面,一个设置页面以及一个索引页让用户根据姓和名来查找一个用户并返回这个用户的年龄。值得一提的是,就我们这篇文章一开始所讨论的问题来说,这段代码是有漏洞的。现在让我们切到攻击者模式吧。。。。。。

我们的目的是获取管理员页面。经过一些侦察摸索后,我们已经发现有一个管理员页面是在/admin/这里,但是这是普通用户不能访问的。我们也已经知道数据库架构是什么,也知道什么将快速地对这个站点产生实际的攻击。。。。。。就像这个代码:


    {
        "username" : "username",
        "account_info" : {
            "secret_key" : "secret",
            "age" : 45,
            "isAdmin" : false
        },
        "password" : "password",
        "firstname" : "lastname"
    }


上面的firstname:lastname键值对看起来有点意思。

首先,我要创建一个账号来获得多一点的权力以便访问这个站点。随后我试着去访问/admin/,结果我得到的是:访问被拒

好的不能再好了。。。。。。居然不可访问。回过头再看看这个架构,isAdmin可能就是那个控制着访问该页面的关键,另外由于名:姓键值对看起来是被用户设定了的,我们可能要尝试一下在设置页面里对account_info进行修改。这是因为设置页面允许我们去更新用户名,密码,姓和名的信息。

现在,我们就能试着去注入一个值,这个值将更新isAdmin为1,在Python里面这个值也就是真。

没有错误,我猜这已经成功了。

事实如下图。。。。。。

成功了。访问被授权了。

我很奇怪的是,用户的那些信息可以获得一个秘钥。。。。。。不过,我也不知道我的秘钥是什么,但是我可以将它改成我所知道的。

这应该可以起作用。。。。。。


太他妈的可怕了。这些个可能性真是无穷无尽。我可以将这些做成一个跨站请求伪造攻击来修改其他账号的秘钥,同事可以查看所有账号信息。谁知道还有没有其他的可以做。

因此,很明显的是,所有有关这个站点的设计是很糟糕的。敏感信息也没有哈希化,同时键值也不应该是变量。不论什么原因,如果键值需要有变量,那么这些变量应该要被检查是否是可信用的预期的输入,这样可以确保溢出利用不会发生。事后我觉得这样的漏洞太小儿科和愚蠢了。我会承认的是我已经掉到这个圈套里面了,同时如果在我这么做的时候我还没发觉它,那么一旦部署之后这将是很严重的问题。

这件事提醒你,要审查你的输入并且不要在键里面使用变量。这不是个好时机。

祝大家好运。
Frankie


翻译者:lappy
原文地址:http://www.technopy.com/mongodb-injection---how-to-hack-mongodb.html


 

2月15日11:00到13:00网站停机维护,13:00前恢复