Exploitation of CVE-2018-8007
Exploitation of CVE-2018-8007
CVE-2018-8007 is an RCE-vulnerability targeting Couchdb version 2.1.1. Because of some modifications (described below) version 2.1.2 is also vulnerable. Newer versions are not vulnerable.
The vulnerability was found by MD sec and described in [1]. Because I had trouble turning the given PoC into an RCE-exploit, I decided to write this short write-up.
Short description of vulnerability
The vulnerability can be triggered when editing the configuration file by using the REST API. Certain configuration elements are blacklisted and you are not allowed to edit them through the REST API. But by injecting a newline, it is possible to create arbitrary new entries.
Start up database
A new database can be started up quite easily with Docker:
sudo docker run --rm -p 127.0.0.1:5984:5984 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password --name my-couchdb couchdb:2.1.2
Find nodes
The next step is to find the name of some nodes in database, that can be done with the following command:
curl -iv -X GET http://127.0.0.1:5984/_membership -u admin:password
Trouble with os_daemons
My problems started when I didn’t get os_daemons to work correctly. I could use the given PoC to update the config file and was able to manually verify that the config file was updated, but the command was never executed.
For reference, the config file in the docker container will be in the following directory:
/opt/couchdb/etc/local.d/
To see if I misunderstood something, I tried to look at the Couchdb documentation for os_daemons, only to find out that the feature has been removed and the documentation for earlier version has removed the page I was looking for. The full page can however, be found at archive.org[2].
Even after looking at the documentation, I still couldn’t figure out how to make this work. I therefore tried to look at some of the other configurations I could inject. update_notification seemed like a good choice.
After some testing, it still didn’t work. To verify that my configuration was correct, I placed update_notification in from the start and verified that my command was executed. With this we could verify that the problem was with the exploit and not with the configuration.
I decided to re-read the PoC more carefully to see if I missed anything and realised that update_notification is not part of the blacklist shown. A look at the appropriate code[3] also shows that the configuration is not blacklisted.
The exploit is therefore quite simple, we don’t even need to inject a newline, we just configure it like normal.
curl -iv -X PUT http://127.0.0.1:5984/_node/nonode@nohost/_config/update_notification/index-updater --data '"/usr/bin/touch /tmp/hack"'
You can now spawn a shell on the docker container and verify that /tmp/hack has been created.
To clean up, you should of course delete the file and delete the entry in the config. The config entry can be deleted with:
curl -iv -X DELETE http://127.0.0.1:5984/_node/nonode@nohost/_config/update_notification/index-updater
Conclusion
In the end, the exploit is not actually injection of new entries, but a missing entry in the blacklist. The only practical meaning of this is that version 2.1.2 is also vulnerable.
An interesting side-note is that the functionality was seemingly removed independently on the reported vulnerability. It was removed on Agust 1 in a pull request not mentioning the security vulnerability [4]. The pull request related to the vulnerability seems to be [5].