当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-088304

漏洞标题:我是如何通过mongodb未授权访问拿下整个分片集群的(泄露大量信息)

相关厂商:分片

漏洞作者: 0x_Jin

提交时间:2014-12-23 21:17

修复时间:2015-02-06 21:18

公开时间:2015-02-06 21:18

漏洞类型:未授权访问/权限绕过

危害等级:高

自评Rank:20

漏洞状态:未联系到厂商或者厂商积极忽略

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-12-23: 积极联系厂商并且等待厂商认领中,细节不对外公开
2015-02-06: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

mongodb 文档型数据库。搭建集群处理海量数据有非常好的效果,这次弄的是拿分片集群的案例,下次再来个拿副本集集群的案例吧。

详细说明:

问题最开始的起源于,mongodb未授权访问。
ip:54.167.122.231 port:27016
(修改了默认端口27017)
在偶然扫到后,登陆了一下,发现命令提示符 竟然是集群的 主节点。
你要问我是怎么知道的?看下图:

屏幕快照_2014-12-23_13_35_16.png


可以看到提示符中的 有集群名以及PRIMARY字样,接触mongodb集群的童鞋可能会知道,这是mongodb集群的标示,有PRIMARY SECONDARY mongos 三种提示符。
mongos :代表采用了分片集群技术。mongos是路由进程,它路由所有请求,然后将结果聚合。它不保存存储数据或配置信息。
PRIMARY:Primary代表主节点 (副本集集群中主节点以及分片集群的从节点都会这样显示)
SECONDARY:SECONDARY 这个代表副本集集群中的从节点(默认没有读写等权限)
那么现在学会了辨认当前数据库服务器是否是集群服务器,下一步就找找集群的配置吧(为了找到其他集群的位置 寻找到主节点)。
链接上集群数据库后执行 rs.conf() 查看下副本集集群配置。
结果如下:

屏幕快照 2014-12-23 14.36.55.png


看到这个便知道这台服务器肯定不是副本集 集群了。
因为副本集集群最少会有三个成员 一个主节点 一个备份节点 一个仲裁节点
但是这里从members里只看到一个成员,那么这个肯定是分片集群的从节点了。
分片集群的话要想找到地址是比较难的了,因为配置信息中并不会透露主节点在哪。这样我们就不好去尝试是否也存在未授权访问。
正当我惆怅如何去寻找主节点时,我看到host的值是一个url地址 并不是我之前扫描到的IP地址。
mongo-events-r3large-1.incrowd.2410.mongodbdns.com:27016
根据之前搞了几次mongodb的经验觉得可以尝试下从url中找到其他节点。
从上图中看到当前集群的名字叫做:events_1 那么说明应该还有其他的分片集群名 比如events_2 events_3等等之类的,如果他只有这么一台分片集群的话 那我也认了。
从上面那个url中也包含了events字样 然后后面跟了个1,为了证明猜想 我ping了下我猜想的url,看他们有没有被解析成ip。

屏幕快照 2014-12-23 14.56.12.png


可以看到猜想是对的,还存在其他分片集群 地址也是根据events_来命名的。
然后我们得到了如下五个ip:

mask 区域
*****122.*****
*****96.1*****
*****.96*****
*****44.1*****
*****.19*****


可以看到上面的服务器都没有在同C段,本身我还想着如果全在一起的话那就去扫扫C段 看能不能扫到分片集群的mongos路由,上去看看到底有多少台分片集群数据库服务器。
给这五个ip加上27016端口 发现全部能链接。
如下图:

屏幕快照 2014-12-23 15.01.21.png


屏幕快照 2014-12-23 15.04.39.png


屏幕快照 2014-12-23 15.05.15.png


屏幕快照 2014-12-23 15.05.47.png


屏幕快照 2014-12-23 15.06.12.png


弄下这么多分片集群的从节点了,先看看里面有什么吧。
show dbs了一下,发现有很多数据库,并且还是以日期命名。

屏幕快照 2014-12-23 15.09.12.png


进入D2014-12-21-H23 这个库 看下

屏幕快照 2014-12-23 15.11.03.png


发现就只有一个集合名:events 看看里面的内容吧。
发现了如下内容:

db.events.findOne()
{
"_id" : "wins_050dz2cria3sw0000i801bgmz6d",
"win" : {
"percentage" : 0.42857142857142805,
"fee" : 0.07857143142857101,
"margin" : 0.30000000000000004,
"spend" : 0.261904771428571
},
"ad_id" : "6uZO1IjWu2wAef0AD",
"received_date" : ISODate("2014-12-21T22:59:56Z"),
"queue_ms" : 19000,
"stats" : {
"flurry-persona" : [
"Business Professionals",
"Music Lovers",
"Photo & Video Enthusiasts"
],
"bidmode" : "Smart CPM",
"subcategory" : [
"Music (IAB1-6)",
"Guitar (IAB9-16)",
"Home Recording (IAB9-17)",
"Radio (IAB9-24)",
"Desktop Video (IAB19-14)",
"Home Video/DVD (IAB19-17)"
],
"num_impressions" : 1,
"ip" : "50.153.238.132",
"app" : "GetItLive",
"placement_id" : "flurry-97bf73e1496a453443df580805bacf21f7540358",
"win_price" : 0.18333334,
"height" : 50,
"device" : "iPhone",
"experiments" : [
"country-source-Maxmind",
"carrier-source-Default",
"size-FUZZY",
"freq-NONE",
"lowbids-NEW",
"fetch_frequencies_00004",
"win_url-http://win.crwd.io/"
],
"flurry-ageestimate" : [
"18-24"
],
"form_factor" : "bar",
"common_name" : "iPhone",
"flurry-genderestimate" : [
"Female"
],
"pricing_strategy" : "D1",
"utc_hour" : 22,
"carrier_type_exchange" : "wifi",
"exchange" : "Flurry",
"size" : "320x50",
"category" : [
"Arts & Entertainment (IAB1)",
"Hobbies & Interests (IAB9)",
"Technology & Computing (IAB19)"
],
"city" : null,
"latlon_source" : "geoip",
"uuid" : "3cac7a084ae9167e7a7c4c5c32a401cbfe0b804e",
"bucketed_win_price" : "0.20",
"dnt" : null,
"open" : "on page",
"creative_id" : "wYzGcBnmGHCR",
"udidsha1" : null,
"tz_offset" : "-07:00",
"coordinates" : [
38,
-97
],
"timezone" : "America/Denver",
"os_version" : "iOS 7.1.2",
"flurrycategory" : "Music",
"dpidsha1" : "3cac7a084ae9167e7a7c4c5c32a401cbfe0b804e",
"version" : 2,
"ad_categories" : [
"Sports (IAB17)"
],
"latitude" : 38,
"banned_attributes" : [
"In-Banner Video Ad (User Initiated)"
],
"passbook" : "Yes",
"uniquely_identified" : null,
"banned_categories" : [
"Illegal Content (IAB26)",
"Non-Standard Content (IAB25)",
"Cards & Casino (AND1-3)",
"Cigars (IAB9-9)"
],
"zone_time" : "(America/Denver 15:00)",
"username" : "ryanjbow",
"bucketed_bid_price" : "0.20",
"incrowd_local_time" : "16:00",
"media" : "App",
"bidfloor" : 0.06,
"maxmind_netspeed" : "cable/dsl",
"day_part" : "17:00 Eastern",
"site" : null,
"battr" : [
7
],
"maxmind_isp" : "Comcast Cable",
"priors_experiment" : [
"week",
"Default is country"
],
"tracking_type" : [
"idfa",
"dpidsha1"
],
"idfa" : "6F521468-42C3-45B6-A063-74EEB8CF0999",
"os" : "iOS",
"ad_name" : "DraftKings - US - NFL Over - Wi-Fi App",
"bid_price" : 0.23588334602035002,
"incrowd_offset" : "-06:00",
"creative_source" : "Upload",
"manufacturer" : "Apple",
"badv" : [ ],
"gender" : "Female",
"placement" : "GetItLive",
"udid" : null,
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257",
"region" : null,
"isp" : "Comcast Business Communications",
"longitude" : -97,
"udidmd5" : null,
"idfatargeting" : 1,
"network" : "Wi-Fi",
"range" : "848887808-848953343",
"carrier" : "Wi-Fi",
"image_url" : "http://img.crwd.io/pZE3fsrNumkLcpPn4wYzGcBnmGH.png",
"local_time" : "15:00",
"city_region" : null,
"user_version" : 2,
"country" : "United States",
"margin" : 0.30000000000000004,
"width" : 320
},
"inserted_date" : ISODate("2014-12-21T23:00:15.870Z"),
"type" : "wins",
"bidhash" : "050dz2cria3sw0000i801bgmz6d"
}
events_1:PRIMARY>


看到看到收集了很多信息,包括了imei码 username 用户性别 国家 isp 手机型号 生产产家 上网方式 用户ip 运营商 以及User-agent APP名字以及APP的一串ID 还有很多看不懂的东西

屏幕快照 2014-12-23 15.26.13.png


光这一个库就有880447条数据 而这个从节点就有300多个库。。。
一共有五台这样的分片集群服务器 加起来就是一千五百个库。
排除掉小于1GB的库 那么一台服务器上就有52个库 5台加起来也有250多个库。
初步统计的话最少有3千万条数据。

漏洞证明:

mask 区域
*****122.*****
*****96.1*****
*****.96*****
*****44.1*****
*****.19*****


屏幕快照 2014-12-23 15.01.21.png


屏幕快照 2014-12-23 15.04.39.png


屏幕快照 2014-12-23 15.05.15.png


屏幕快照 2014-12-23 15.05.47.png


屏幕快照 2014-12-23 15.06.12.png


修复方案:

看到我拿一个url便得到了其他4台分片集群的地址是不是感觉我运气好?
其实不然,一般能用到mongodb做集群的话那么代表数据量特别大,数据量特别大为了使查询快速就必须得用上集群。
一旦用上集群就各种问题来了,集群服务器多的话如何去快速的管理?要么把集群服务器都放在一个网段,要么就是像这个例子一样专门解析一个url到集群服务器上,并加以标示,这样就很很好的管理其他集群服务器了。
不相信?那么我们来看我弄下的另外一个副本集集群的例子。

1.jpg


(上面说过了副本集集群查找其他集群服务器地址是很任意的 rs.conf()就可以看到配置信息了)
可以看到这个数据库服务器的地址也是url地址中加编号,所以说这不是偶然 而是为了方便运维管理也这样做的。
那么面对这样的情况运维该如何去防御别人拿下你们整个集群数据库呢?
这又牵扯到了mongodb的一个问题了,首先mongodb安装好后是会默认启动的,并且还是以服务的方式启动(如果用启动服务的方式来启动mongodb的话你想要加启动选项也加不了) 如果是单台服务器想要进行账号验证很简单,启动mongod 的时候加—auth 来要求认证即可。
但是集群的话该如何去要求认证呢?
可以采用Keyfile认证操作如下:
openssl rand -base64 100 > /Users/root/keyfile0 (生成一个100字符的文件采用base64加密)

2.jpg


3.jpg


chmod 600 /Users/root/keyfile0 (更改下权限)
然后拷贝到其他数据库集群的服务器上,在启动集群服务器的时候加keyfile参数即可。
--keyfile=/Users/root/keyfile0
这样设置后,没有这个文件的机器就无法进去到集群,等于启动了auth参数 攻击者在连接数据库集群服务器的时候就需要认证了。
这样的话集群的子节点就全部需要认证了,那么主节点呢?
主节点还是需要添加账号,切记先在无验证的情况下进入admin库添加上账号(其他集群会自动同步的) 然后再给其他集群加keyfile参数启动。
在给主节点设置上密码后,从节点设置上keyfile上那么验证方面就基本上大功告成了,不要因为嫌一时麻烦而偷懒,安全可不能懒。
温馨小提示:mongodb支持gridfs存储文件,但是不要把重要的配置文件给放入数据库中存储喔,因为攻击者进入数据库后可以下载到本地的。

版权声明:转载请注明来源 0x_Jin@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝

漏洞Rank:20 (WooYun评价)