序言 在我们进入MongoDb注入之前,我们必须明白MongoDb是什么,为什么我们更喜欢其他数据库。由于MongoDb不使用sql人员认为它不容易受到任何类型的注入攻击。但相信我,没有人出生在内在的安全方面。我们必须采取一些逻辑来防止攻击。简而言之,MongoDb是由MongoDb Inc.开发的开源数据库,它将数据存储在类似JSON的文档中,结构可能有所不同。这些相关信息存储在一起,以便通过MongoDb查询语言进行快速查询访问。
MongoDb是最受欢迎的,它具有非常高的性能(1000亿个/秒)。MongoDb更受欢迎的另一个原因是因为它在关系数据库不是很好的适用的许多使用情况下表现出色。例如,具有非结构化,半结构化和多态数据的应用程序以及具有较大可扩展性要求的应用程序,数据中心部署。 我们来尝试一下注入在第一种情况下,我们有一个PHP脚本,显示与特定ID相对应的用户名和密码。
在上面的脚本中,可以看到数据库的名称是安全性, 而名称的集合是用户。我们 从GET 方法获取 u_id 参数,然后将其传递给给我们相关结果的数组.Sounds好吗?我们尝试把一些比较运算符与数组进行比较。
哎呀.. !! 它为我们倾倒了整个数据库。你能弄清楚出了什么问题吗?这是因为输入http://localhost/mongo/show.php?u_id [$ ne] = 2
创建了以下MongoDb查询。 $qry= array(“id” => array(“$ne” => 2))因此,它显示除了id = 2 之外的所有结果,我们在快照1中看到。
让我们考虑另一种情况,其中脚本与前面的工作相同,但在这种情况下,我们将使用findOne方法创建MongoDb查询。
我们将首先快速查看findOne方法的工作。该方法具有以下语法: db.collection.findOne(query, projection)这将返回满足指定查询条件的文档。例如,如果我们需要找到与id = 2相关联的结果, 我们将触发以下命令:
现在来看看源代码:
这里的关键是以某种方式打破查询,然后再次修复。你能猜测如果我们输入以下查询会发生什么? http://localhost/mongo/inject.php?u_name=dummy’});return{something:1,something:2}}//&u_pass=dummy这将中断查询并返回所需的参数。我们来检查输出:
你有没有注意到它给了我们两个错误,只是因为我们想访问两个真的不存在的参数?间接地,这个错误显示用户名和密码是数据库中的参数,这就是我们想要的。
一旦我们键入正确的参数,而不是某些东西,错误就会被删除。
现在我们想要找到数据库的名称。在MongoDb中,db.getName()方法用于查找数据库的名称。所以查询将是:
为了转储数据库,我们首先需要找到集合的名称。db.getCollectionNames()方法用于在MongoDb中查找集合的名称。
所以,到目前为止,我们已经获得了数据库和集合的名称。剩下的是找到用户集合中的数据,可以如下完成:
同样,我们可以具有通过改变函数内部的参数其他用户名和密码db.users.find()[2],等
现在,你已经熟悉了MongoDB的注射,可能你想了解预防 的这种注射的。 让我们考虑第一种情况 ,我们将参数传递给数组。为了防止这种注入,我们以某种方式需要停止对数组中比较运算符的执行。所以解决方案之一是以下列方式使用implode()函数:
implode()函数返回从数组中的元素的字符串。因此,我们只得到一个与该特定ID相对应的结果,而不是所有的结果。
在第二种情况下,我们可以使用addslashes()方法,以便查询不会被攻击者破坏。但是使用正则表达式替换特殊符号将是一个好主意。您可以使用以下正则表达式: $u_name =preg_replace(‘/[^a-z0-9]/i’, ‘\’, $_GET[‘u_name’]);
现在,如果我们尝试中断查询,它不会提示我们出现错误。
备注http://php.net/manual/en/mongocollection.find.phphttps://media.blackhat.com/bh-us ... _Server_Side_WP.pdf
from:https://mp.weixin.qq.com/s?__biz ... ZBRMCm3sEFiEsL1z#rd
|