Meteor NoSQL 盲注漏洞

2019-08-21 约 306 字 预计阅读 2 分钟

声明:本文 【Meteor NoSQL 盲注漏洞】 由作者 aliyuuu 于 2019-08-21 08:18:00 首发 先知社区 曾经 浏览数 135 次

感谢 aliyuuu 的辛苦付出!

Meteor NoSQL 盲注漏洞

0x00 前言

我最近在Meteor程序中,发现了一个可调用的公开方法"users.count",它可以返回应用程序中已注册的用户数。虽然从威胁评估的角度来看,它的危害并不大,但我还是深入挖掘了一下。

通过空参数{}调用users.count方法,后端会返回1923,即已注册的用户数。

但是,如果将参数更改为{"username": "kertojasoo"},得到的结果却是1

你发现了漏洞所在吗?

在这篇文章中,我将具体介绍如何利用该漏洞,如何自动化利用,如何在其他应用程序中找到类似的漏洞以及如何降低风险。

0x01 漏洞利用

我们可用以下函数从数据库中提取信息。

例如:

Meteor.call("users.count", {
    "username": "kertojasoo",
    "token": {$regex: '^[a-z].*'} // start's with [a-z] (26 possibilities)
}, console.log);

在此示例中,每个用户包含有一个token属性。如果查询的结果是1,我们可以推断出该用户的token是以小写字符开头的。接下来,我们将查询范围再缩小一半:

Meteor.call("users.count", {
    "username": "kertojasoo",
    "role": {$regex: '^[a-m].*'} // start's with [a-m] (13 possibilities)
}, console.log);

通过这种方法枚举,得到第一个字符后,将它添加到正则表达式,继续枚举下一个字符。

因此,虽然我们无法直接读取用户的令牌,通过布尔测试,我们可以进行二进制迭代搜索,最终得到正确的值,我将这种方法称之为“基于正则表达式的NoSQL盲注入“。

GitHub上提供了这种漏洞利用的简单实现(线性搜索)。

如果您能够登录应用程序,就可以先在控制台中利用Meteor.user()方法得到用户名,再进行枚举。在Meteor的官方指南中,还有针对用户提取bcrypt哈希的方法"services.password.bcrypt",当然了,解析bcrypt哈希就是另一件事了。

0x02 meteor简介

首先,我们需要搞清楚,什么是Meteor方法?

Meteor利用method实现客户端 - 服务器的通信——从客户端获取服务器端的代码。“method”本身是一个JavaScript函数名称。

在服务器上定义method如下所示:

Meteor.methods({
  'users.count'({ filter }) {
    return Meteor.users.find(filter).count();
  }
});

一个简单的客户端方法定义:

Meteor.call('users.count', (err, res) => {
  console.log(res);
});

请注意,以上示例并没有验证用户输入,由于服务器代码能够从客户端获取,所以所有的方法都必须实现授权,否则就可能有恶意的客户端滥用服务器。这一点类似于在进行REST处理时保护所有的API接口一样。

0x03 查找meteor方法

在测试Meteor应用程序时,要做的第一件事就是枚举所有公开的可调用方法。一些指南可能会建议你打开浏览器的开发人员工具,在JavaScript代码中搜索Meteor.call,然而还有一种更有效的方法可用于查找公开的Meteor方法。

注意:如果Meteor应用程序在开发模式下运行,则可忽略以下大部分步骤,因为在这种情况下,我们在DevTools中就可以得到所有的源映射。

<center>感谢您在开发模式下运行应用程序!</center>

我还编写了一个bash脚本,用于自动提取公开方法,可以在GitHub上找到。但必须保证只在允许测试的服务器上运行!

<center>自动Meteor方法提取脚本的示例输出</center>

第1步:提取

利用meteor build构建Meteor应用程序时,全部JavaScript文件和模板都会被打包压缩成单个文件,我们可以通过meteor run --production模拟这一过程,通过点击查看Meteor程序的源代码,查看到最后生成的代码。

查看JavaScript文件,最后一行(特别是以var require=开头的行)将包含应用程序指定的代码。这是我们要深入研究的地方。

第2步:JS美化

我们无法美化整个JavaScript bundle,但是如果排除所有包和模板代码,仅保留应用程序本身的代码,还是能够格式化的。大多数代码编辑器都可以美化JavaScript代码,图方便的话也可以使用在线工具。正确地格式化可以方便我们进一步研究代码。

第3步:过滤

在美化后的JS代码中搜索.call(".methods(,你将得到所有可调用的方法名。源代码还提供了测试相关的参数提示。

第4步:试验结果

在DevTools控制台中,你可以尝试调用这些方法并查看结果。可以使用简单的原语,如:

Meteor.call(“method.name”,console.log)

如果需要传递参数,还可以用以下方法:

Meteor.call(“method.name”,{key:“value”},console.log)

0x04 危害

Shodan.io目前报告有38,105个使用的Meteor服务主机。BuiltWith显示目前有17,334个网站在使用meteor。

导出的Shodan数据中发现了18,666个在标准位置含有JavaScript bundle的站点,其中9,379个站点具有Meteor方法。

<center>Shodan.io中查找到的meteor程序</center>

互联网上至少有659,746个公开曝光的Meteor方法。平均一个Meteor应用程序含有70种方法。

利用关键字搜索曝露的方法会产生以下结果:

┌─────────────────────────┐
│ Meteor Exposed Methods  │
├──────────┬───────┬──────┤
│ Keyword  │ Count │  \b  │
├──────────┼───────┼──────┤
│ update   │ 454303724 │
│ get      │ 871023701 │
│ insert   │ 143912542 │
│ create   │ 124751707 │
│ delete   │ 352301813 │
│ add      │ 464341078 │
│ count    │ 14674401 │
│ fetch    │  1434365 │
│ set61780353 │
│ send     │ 21199258 │
│ account  │ 11634251 │
│ find     │  4299223 │
│ password │  7870176 │
│ upload   │  9363175 │
│ read11303171 │
│ submit   │   59081 │
│ filter   │   55577 │
│ token    │ 2155744 │
│ open     │  302439 │
└──────────┴───────┴──────┘ 
Count:   grep -riP "$word" | wc -l \b adds word breaks:   grep -riP "\b$word\b" | wc -l

虽然曝露的方法并不一定是可利用漏洞,但它仍然是一个攻击点。

0x05 缓解

即使开发框架承诺“以最少的代码实现最多的功能”,我们也不能忽略对用户输入数据的验证。

Meteor的官方指南建议所有Meteor应用程序都使用Methods接受客户端的数据,并且严格限制每个方法能够接受的参数。你必须在这些参数进行业务处理之前验证它们。

0x06 结论

无论你想要客户端和后台通过哪种方法进行通信—Meteor方法,WebSockets还是RESTful API — 你都必须保证所有用户输入都经过了验证,不接受格式错误甚至恶意的数据。

提醒:保持安全合法,不要在未经允许的服务器上测试。

本文翻译自 medium.com, 原文链接 。如若转载请注明出处。

关键词:[‘安全技术’, ‘漏洞分析’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now